diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/_images/BYOC.png b/_images/BYOC.png new file mode 100644 index 0000000..94702a1 Binary files /dev/null and b/_images/BYOC.png differ diff --git a/_images/CR_workshop_setup.png b/_images/CR_workshop_setup.png new file mode 100644 index 0000000..47b4502 Binary files /dev/null and b/_images/CR_workshop_setup.png differ diff --git a/_images/community.png b/_images/community.png new file mode 100644 index 0000000..ddd9a62 Binary files /dev/null and b/_images/community.png differ diff --git a/_images/hackmd--controls.png b/_images/hackmd--controls.png new file mode 100644 index 0000000..46a74c7 Binary files /dev/null and b/_images/hackmd--controls.png differ diff --git a/_images/hackmd--full-demo.png b/_images/hackmd--full-demo.png new file mode 100644 index 0000000..0988b6f Binary files /dev/null and b/_images/hackmd--full-demo.png differ diff --git a/_images/hackmd--questions2.png b/_images/hackmd--questions2.png new file mode 100644 index 0000000..a609199 Binary files /dev/null and b/_images/hackmd--questions2.png differ diff --git a/_images/history-landscape-dark.png b/_images/history-landscape-dark.png new file mode 100644 index 0000000..a1aef3c Binary files /dev/null and b/_images/history-landscape-dark.png differ diff --git a/_images/history-portrait-dark.png b/_images/history-portrait-dark.png new file mode 100644 index 0000000..2fc1fa6 Binary files /dev/null and b/_images/history-portrait-dark.png differ diff --git a/_images/history-portrait-light.png b/_images/history-portrait-light.png new file mode 100644 index 0000000..5f4361c Binary files /dev/null and b/_images/history-portrait-light.png differ diff --git a/_images/history-portrait.png b/_images/history-portrait.png new file mode 100644 index 0000000..28e18b0 Binary files /dev/null and b/_images/history-portrait.png differ diff --git a/_images/history-rsh.png b/_images/history-rsh.png new file mode 100644 index 0000000..1bbb1cc Binary files /dev/null and b/_images/history-rsh.png differ diff --git a/_images/instructor.png b/_images/instructor.png new file mode 100644 index 0000000..718f2a8 Binary files /dev/null and b/_images/instructor.png differ diff --git a/_images/landscape.png b/_images/landscape.png new file mode 100644 index 0000000..eda9d42 Binary files /dev/null and b/_images/landscape.png differ diff --git a/_images/learner-large.png b/_images/learner-large.png new file mode 100644 index 0000000..3b6d2cd Binary files /dev/null and b/_images/learner-large.png differ diff --git a/_images/learner-normal.png b/_images/learner-normal.png new file mode 100644 index 0000000..590135e Binary files /dev/null and b/_images/learner-normal.png differ diff --git a/_images/learner-small.png b/_images/learner-small.png new file mode 100644 index 0000000..5d5f421 Binary files /dev/null and b/_images/learner-small.png differ diff --git a/_images/portrait.png b/_images/portrait.png new file mode 100644 index 0000000..415799f Binary files /dev/null and b/_images/portrait.png differ diff --git a/_images/steps.png b/_images/steps.png new file mode 100644 index 0000000..6c978b5 Binary files /dev/null and b/_images/steps.png differ diff --git a/_images/survey-impact1.png b/_images/survey-impact1.png new file mode 100644 index 0000000..7dd0ddc Binary files /dev/null and b/_images/survey-impact1.png differ diff --git a/_images/survey-impact2.png b/_images/survey-impact2.png new file mode 100644 index 0000000..8771bff Binary files /dev/null and b/_images/survey-impact2.png differ diff --git a/_images/welcome.png b/_images/welcome.png new file mode 100644 index 0000000..302082c Binary files /dev/null and b/_images/welcome.png differ diff --git a/_sources/co-teaching.md.txt b/_sources/co-teaching.md.txt new file mode 100644 index 0000000..c197f10 --- /dev/null +++ b/_sources/co-teaching.md.txt @@ -0,0 +1,110 @@ +(co-teaching)= + +# Co-teaching + +:::{objectives} +- Get to know the principle of co-teaching: How we do it and how you can too. +- Learn the team teaching concept and how to tailor it to your situation. +::: + +:::{instructor-note} +- Teaching: 15 min +- Exercises: 10 min +- Discussion: 5 min +::: + + +## Overview + +CodeRefinery lessons benefit from the application of the concepts of **co-teaching**. + +:::{admonition} Co-teaching +[Co-teaching](https://en.wikipedia.org/wiki/Co-teaching) can be defined as "the division of labor between educators to plan, organize, instruct and make assessments on the same group of students, generally in a common classroom, and often with a strong focus on those teaching as a team complementing one another's particular skills or other strengths". +::: + +Co-teaching can be used in various forms, some of which are present in our workshops: +- **Teaching + support**, e.g. one of the teachers leading instruction while the other watches over and maintains the collaborative document (HackMD/HedgeDoc/...). +- Another similar example is **remote learning groups** that watch the streamed CodeRefinery lessons guided by the local instructors. +- Having open-source material and planning jointly allows **multiple instances** of a lesson to be held by multiple teachers: + - *parallel teaching*, to different audiences at the same time, + - *alternative teaching*, to different audiences at the same or different time, with potential content adjustments (for example, different installation procedures). +- **Team teaching**, where the lesson is presented by multiple (in most cases, two) teachers who actively engage in conversation with each other. The team-teaching concept is explained in more detail in the [CodeRefinery manual](https://coderefinery.github.io/manuals/team-teaching/). + +In reality, different forms are very often mixed or fused together, even within a single lesson. + +Co-teaching is not an online-only concept. However, it is very practical in online teaching due to larger number of instructors and learners potentially available to join a teaching session. + + +## Co-teaching and team teaching benefits + +- It **saves preparation time**. Co-teachers can rely on each other's strengths while creating/ revising the material as well as in unexpected situations during the lesson. +- It **helps with onboarding new instructors**. One of the co-teachers can be learning at the same time, either the subtleties of the material taught (in this case literally being the "voice of the audience") or the teaching process itself. +- Team teaching **looks more interactive and engaging** to the audience in many cases, without forcing the learners to speak up if they can't or don't want to do so. +- It also **ensures responsive feedback and less workload** by having more active minds. + + +### Are there any downsides? + +Not every learner and not every instructor might like the team-teaching approach. +- It might seem **less structured**, unprepared, and chaotic, even with preparation. + - It might create situations where instructors accidentally talk over each other or "interrupt" and change the flow of the lesson. + - For some instructors it can be stressful to not know in advance what questions they get asked from the co-instructor. + - Sometimes when an unexpected question is asked that throws the other instructor off, it can add to the feeling of chaos and unpreparedness. +- It can be interactive and engaging but it can also end up awkward if the co-teachers don't have a good synergy. + - Can sound awkward: Main instructor talking all the time and at the end asking co-instructor whether everything is clear and co-instructor only saying "yes". + - Possibly more engaging: Co-instructor asking questions which help with the flow and a common understanding of the material. + + +## Team teaching specifics + +- For successful team teaching, additional **coordination** is needed, first of all to agree on the teaching model (see below) and the person in control (the **director**) for the lesson or its parts. +- It's useful to keep track of the **lecture plan**. The discussion is a good way to make lesson more interactive and adjust to the audience, but deviating too much will become disorienting (for example, if someone dropped their attention for a minute and now is trying to catch-up by reading lecture notes). +- Experienced solo teacher might have a habit to keep talking (lecturing), while the co-teacher might not want to "interrupt". Therefore, it is important for the leading presenter to anticipate and **allow for remarks/ questions**, and this can be different from one's previous teaching style at first. + + +## Team teaching models + +We propose two basic models, but of course there is a constant continuum. + + +### Guide and demo-giver + +One person serves the role of **guide**, explaining the big picture and context of the examples. + +Another, the **demo-giver**, +- shows the typing and does the examples, +- might take the role of a learner who is asking about what is going on, to actually explain the details, or to comment occasionally. + +Hands-on demos and exercises work especially well like this. + + +### Presenter and interviewer + +In this case, one is the **presenter** who is mostly explaining (including demos or examples), and trying to move the forward through the material. + +Another, the **interviewer**, +- serves as a learner or spotter, +- fills in gaps by asking relevant questions, +- tries to comment to the presenter when things are going off track. + +This can be seen as closer to classical teaching, but with a dedicated and prepared "voice of the audience". + + +### Exercise + +:::{exercise} Discuss the models of team teaching (10 min) +While in breakout rooms, discuss one of the basic team-teaching models presented here: +- Have you already tried this or similar model in your teaching? +- Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best? + +Write your comments in the collaborative document. +::: + + +## Summary + +:::{keypoints} +- Co-teaching focuses on complementing individual skills and strengths in teaching process. +- Co-teaching may save time, reduce teachers' workload and make lessons more interactive/ engaging. +- Team teaching requires some adjustments in lesson preparation and delivery. +::: diff --git a/_sources/coderefinery-intro.md.txt b/_sources/coderefinery-intro.md.txt new file mode 100644 index 0000000..50d108c --- /dev/null +++ b/_sources/coderefinery-intro.md.txt @@ -0,0 +1,116 @@ +# About the CodeRefinery project and CodeRefinery workshops in general + +:::{objectives} +- Discuss what CodeRefinery is and how we got here +- Understand about the challenges to define our target audience +::: + +CodeRefinery is a +[Nordic e-Infrastructure Collaboration (NeIC)](https://neic.no/) +project that has started in October 2016 and is currently +funded until February 2025. We are working on the continuation plans. + +The funding from 2022-2025 is designed to keep this project active +beyond 2025 by forming a support network and building a community of +instructors and contributors. + + +:::{discussion} History +The CodeRefinery project idea grew out of two [SeSE](http://sese.nu) courses given at KTH Stockholm in 2014 and 2016. +The project proposal itself was submitted to NeIC in 2015, accepted in 2015, and started in 2016. + +We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form. +::: + + +## Goals + +- Develop and maintain **training material on good enough software development practices** for researchers that write code/scripts/notebooks. +- Our material addresses all academic disciplines and tries to be as programming language-independent as possible. +- Provide a [code repository hosting service](https://coderefinery.org/repository/) that is open and free + for all researchers based in universities and research institutes from Nordic countries. +- Provide **training opportunities** in the Nordics using (Carpentries and) CodeRefinery training materials. +- Evolve the project towards a **community-driven project** with a network of instructors and contributors. + + +## Community + +```{figure} img/community.png +Image showing the key areas of the CodeRefinery community: Workshops, chat inlcuding help channel, online meetings and co-working, +other collaborative training, eg on High Performance Computing topics. +``` + +CodeRefinery is not just workshops, we are community and want you to be part of it! + +There are many different levels of involvement, from the occasional commenter in chat, +CodeRefinery ambassador (people who like the project and workshops and help us spreading the word) or lesson issue creators and lesson contributors to +local host, co-instructor or co-organizer. + +Best **first step** in any case is to join the [CodeRefinery Zulip chat](https://coderefinery.zulipchat.com) +or let us know about your interest at support@coderefinery.org. + + +## Target audience + +One common question we get is how do we relate to [the Carpentries](https://carpentries.org). +This section describes how we see it: + + +### Carpentries audience + +The Carpentries aims to teach computational **competence** to learners through an applied approach, +avoiding the theoretical and general in favor of the practical and specific. + +**Mostly, learners do not need to have any prior experience in programming.** +One major goal of a Carpentries workshop is to raise awareness on the tools researchers can learn/use to speed up their research. + +By showing learners how to solve specific problems with specific tools and providing hands-on practice, +learners develops confidence for future learning. + +:::{admonition} Novices +We often qualify Carpentries learners as **novices**: they do not know what they need to learn yet. +A typical example is the usage of version control: the Carpentries lesson +[Version Control with Git](https://swcarpentry.github.io/git-novice/) +aims to give a +very high level conceptual overview of Git but it does not explain how it can be used in research projects. +::: + + +### CodeRefinery audience + +In that sense, CodeRefinery workshops differ from Carpentries workshops as we assume +our audience already writes code and scripts and we aim at teaching them **best software practices**. + +Our learners usually do not have a good overview of **best software practices** but are aware of the need to learn them. +Very often, they know of the tools (Git, Jupyter, etc.) we are teaching +but have difficulties to make the best use of them in their software development workflow. + +Whenever we can, we direct learners that do not have sufficient coding experience to Carpentries workshops. + +:::{admonition} Competent practitioners +We often qualify CodeRefinery learners as **competent practitioners** because they already have an understanding of their needs. +::: + +:::{discussion} Challenges related to defining our target audience +We often get the feedback "I wish I would have known X earlier!" +*Competent practitioners* have run into issues with **not** caring (or not fully understanding) +about version control, documentation, modularity, reproducibility before, so they are easily motivated to learn more. + +For a *novice* these topics may seem unnecessary and "too much" and the workshop may feel too difficult to follow. +However, the materials are designed so that one can always revisit a topic, when needed. +The important part is that you know that "X" exists, and where to find more information, which is also beneficial for novices. +::: + +--- + +:::{keypoints} Keypoints: CodeRefinery +- Teaches intermediate-level software development tool lessons +- It is difficult to define "best practices", we try to teach **"good enough" practices** +- Training network for other lessons +- Publicly-funded discrete projects (3 projects actually) transitioning towards an open community project +- We have online material, teaching, and exercise sessions +- Our main target audience are competent practitioners, but also novices and experts can get something out of the workshops +- We want more people to work with us, and to work with more people +::: diff --git a/_sources/collaborative-notes.md.txt b/_sources/collaborative-notes.md.txt new file mode 100644 index 0000000..15f84b3 --- /dev/null +++ b/_sources/collaborative-notes.md.txt @@ -0,0 +1,333 @@ +(collaborative-notes)= + +# Collaborative notes + +:::{objectives} +- Be able to provide a highly interactive online workshop environment with collaborative documents +::: + +:::{instructor-note} +- Teaching: 10 min +- Exercise: 15 min +- Questions & Answers: 5 min +::: + +## Introduction + +The Collaborative document is how you interact with the participants. +The participants can ask questions and give feedback through the collaborative +document. During a CodeRefinery session there can be a large a volume of questions. +A dedicated person, a Collaborative document-manager, is needed to answer and edit the collaborative document. +Let us see how the collaborative document is used, then discuss the role of +the editor or collaborative document-manager. + +## Collaborative document mechanics and controls +Technologies that can be used as a collaborative document are [Hackmd](https://hackmd.io), [HedgeDoc](https://hedgedoc.org), +or [Google Docs](https://www.google.com/docs/about/) + +[Hackmd](https://hackmd.io) or [HedgeDoc](https://hedgedoc.org/) are real-time text editor online. We use it to: +* As a threaded chat, to **answer questions and provide other information** without + interrupting the main flow of the room. +* provide everyone with a **more equal opportunity to ask questions**. +* **create notes** which will be archived, for your later reference. + +You do not need to login/create an account to be able to edit the document. + +### Basic controls + +```{figure} img/hackmd--controls.png + +This may look slightly different on mobile devices and small windows. +``` + +- At the top (left or right), you can switch between **view**, + **edit**, and **split view and edit** modes. + +- You write in [markdown](https://commonmark.org/help/) here. Don't + worry about the syntax, just see what others do and try to be like + that! Someone will come and fix any problems there may be. + +- Please go back to view mode if you think you won't edit for a + while - it will still live update. + + +### Asking questions + +**Always ask questions and add new sections at the very bottom**. +You can also answer and comment on older questions, too. + +```{figure} img/hackmd--questions2.png + +Questions and answers in bullet points +``` + +Since we plan to publish the questions and answers later as part +of the workshop page, we recommend to not use any names. You can indicate +your own name to make it easier to discuss more during the workshop but +then always use this form: `[name=Myname]`. This makes it easier for +us to automatically remove all names before publishing the notes. + +Other hints: + +- Use `+1` to agree with a statement or question (we are more likely + to comment on it). + +- Please leave some blank lines at the bottom + +- NOTE: Please don't "select all", it highlights for everyone and adds a + risk of losing data (there are periodic backups, but not instant). + +- It can be quite demanding to follow the collaborative document closely. Keep an eye + on it, but consider how distracted you may get from the course. For + things beyond the scope of the course, we may come back and answer + later. + + +### Don't get overwhelmed + +There can be a flood of information on the collaborative document. Scan for what is +important, then if you would like come back later. But it is +important to keep checking it. + + +### Privacy + +- Assume the collaborative document is **public and published: you never + need to put your name there**. + +- The collaborative document will be **published on the website afterwards**. We will + remove all non-instructors names, but it's easier if you don't add + it there in the first place. + +- Please keep the link private during the workshop, since since + security is "editable by those who have the link". + +- You can use `[name=YOURNAME]`, to name yourself. We *will* remove + all names (but not the comments) before archiving the notes (use + this format to make it easy for us). + +## Exercise + +:::{exercise} Discuss how to collaborate and handle questions (15 min) +Write down your conclusions in the shared document. Items to discuss are: +- What is your experience with questions and discussions while teaching? +- How do you deal with them? +- What kind of technologies do you prefer: chat, shared document, or voices + and discussion raised during instruction? And why? +::: + +## Collaborative Document Manager + +We have one person who is a "Collaborative Document helper". This isn't the only +person that should edit and answer, but one person shouldn't have too +much else on their mind so can focus on it. They also make sure that +the collaborative document is updated with exercise, break, and other meta-information to +keep people on track. + +Below, (*) = important. + +### Before the workshop + +* Create a new collaborative document for the workshop +* make sure that **editing is enabled for anyone without login** +* Add workshop information, links to the workshop page and material +and an example question and answer to the top of the collaborative document(see below) + +### Most things to edit (everyone) + +Make it easy to post after the course and consistent to follow: + +* Tag all names with `[name=XXX]` (so they can be removed later), + remove other personal data or make it obvious. +* Add in information on exercises (new section for them, link, end + time, what to accomplish) +* Make a logical section structure (`#` for title, `##` for sections, + `###` for episodes, etc. - or what makes sense) + + + +### General Collaborative Document practices + +```{figure} img/hackmd--full-demo.png +:align: right + +A live demo of a Collaborative Document during a Q&A time. The two instructors are +discussing some of the import answers. Multiple learners have asked +questions, multiple answers, and some remaining to be answered +``` + + + +Keep it formatted well: + +- (*) Tag names you see with `[name=XXX]` so that we can remove it + later. +- Heading level `#` is only the page title +- Add a new `##` heading when a new *lesson* or similar thing is + started (introduction, icebreaker, break between lessons, etc) +- Add a new `###` heading when a new *episode*, *exercise*, *break* + (within exercise session) +- Ensure people are asking questions at the bottom, direct them there + if they aren't. +- (*) Ensure each question is a bullet point. Each answer or follow-up + should be a bullet point below. + - Should you use more deeply nested bullet points, or have only one + level below the initial question? It depends on the context, but + if a conversation goes on too long, try not to let it go too + deep. + + +Update with meta-talk, so that learners can follow along easily: + +- Add Icebreaker and introductory material of the day. Try to talk to + people as they joined to get them to open the collaborative document and answer. +- Anything important for following along should not be only said via + voice. It needs to be in the collaborative document, too. +- New lessons or episodes, with links to them. +- For exercises, link to exercise and add the duration, end time, + goals. If these are unclear, bring it up to the instructor by voice. +- Add a status display about breaks. + + +Screenshare it when necessary: + +- During breaks and other times, share the collaborative document(including the + notification about break, and when it ends). +- It is nice if the arrangement allows some of the latest questions to + be seen, so people are reminded to ask there. +- Someone else may do this, but should make sure it happens. + +Answer questions + +- If there is an question that should be answered by the instructor by + voice, bring it up (by voice) to the instructor immediately. +- How soon do you answer questions? Two points of view: + - Answer questions right away: can be really intense to follow. + - Wait some so that we don't overload learners: reduces the info + flow. But then do people need to check back more often. + - You need to find your own balance. Maybe a quick answer right + away, and more detailed later. Or delay answers during the most + important parts of the lecture. +- Avoid wall-of-text answers. If reading an answer takes too long, it + puts the person (and other people who even try to read it) behind + even more by taking up valuable mental energy. If an answer needs a + wall of text, consider these alternatives: + - Progressive bullet points getting more detailed (first ones + useful alone for basic cases) + - Don't be worried to say "don't worry about this now, let's talk + later." + - Figure out the root problem instead of answering every possible + interpretation + - Declare it advanced and that you will come back later. + +Ensure it can be posted quickly: + +- The collaborative document gets posted to the workshop webpage. For this, it needs some + minimal amount of formatting (it doesn't need to be perfect, just + not horrible). +- All names and private information needs to be stripped. This is why + you should rigorously tag all names with `[name=XXX]` so they can be + removed (see above). + - Learner names can be completely removed. CR staff names can be + `[name=CR]` or something similar. + - There may be other private URLs at the top or bottom. + +- If possible, send the PR adding the collaborative document to the workshop webpage + (though others can do this, too). + + + +### Collaborative document format example + +``` +# Workshop, day 1 + + +## Lesson name +https://coderefinery.github.io/lesson/ + +### Episode name +https://coderefinery.github.io/01-episode/ + +- This is a question + - Anwser + - More detailed answer +- question + - answer + +### Exercises: +https://link-to-exercise/.../.../#section +20 minutes, until xx:45 +Try to accomplish all of points 1-3. Parts 4-5 are optional. + +Breakout room status: +- room 2, need help with Linux permissions +- room 5, done + +### Break +:::danger +We are on a 10 minute break until xx:10 +::: + + +## Lesson 2 +https://coderefinery.github.io/lesson-2/ + +``` + +### Posting the collaborative document to the website + +The collaborative document should be posted sooner rather than later, and hopefully the +steps above will make it easy to do so quickly. You could wait a few +hours, to allow any remaining questions to be asked an answered. + +- Download as markdown +- Remove any private links at the top +- Adjust headings so that they are reasonable +- Look for private info and remove it + - Search document for `[name=???]` (change to `[name=staff]` or + `[name=learner]`) + - Any names not tagged with `[name=]` + - usernames in URLs + - private links + +### Feedback template + +`````` +## Feedback, day N + +:::info +### News for day N+1 +- . +- . +::: + +### Today was (multi-answer): +- too fast: +- just right: +- too slow: +- too easy: +- right level: +- too advanced: +- I would recommend this course to others: +- Exercises were good: +- I would recommend today to others: +- I wouldn't recommend today: + +### One good thing about today: +- ... +- ... + +### One thing to be improved for next time: +- ... +- ... + +### Any other comments: +- ... +- ... +`````` +:::{keypoints} +- Having a collaborative document improves communication and interaction. +- Answering questions requires a dedicated person - A Collaborative Document Manager. +- The collaborative document should be posted on the web site as soon as possible. +::: diff --git a/_sources/computational-thinking.md.txt b/_sources/computational-thinking.md.txt new file mode 100644 index 0000000..943d9c8 --- /dev/null +++ b/_sources/computational-thinking.md.txt @@ -0,0 +1,25 @@ +(computational-thinking)= + +# Computational thinking + + +:::{objectives} +- Explain what is computational thinking +- Get to know how the theory of computational thinking can be used in teaching +- Short exercise +::: + +:::{instructor-note} +- Teaching: 20 min +- Exercises: 10 min +::: + + +Materials available as [slides](https://github.com/coderefinery/train-the-trainer/blob/main/content/computational_thinking.pdf). + + +:::{keypoints} +- Computational Thinking consists of 4 main parts: decomposition, pattern recognition, abstraction and algorithmic design. +- How can this be a useful framework for solving problems? +- How can this be used practically? +::: diff --git a/_sources/cool-gems.md.txt b/_sources/cool-gems.md.txt new file mode 100644 index 0000000..a4a6f5c --- /dev/null +++ b/_sources/cool-gems.md.txt @@ -0,0 +1,16 @@ +(cool-gems)= + +# Sharing teaching gems + +:::{objectives} +- Our goal is to share our teaching tricks and tools and demonstrate them in + very short presentations/discussions. +::: + +:::{instructor-note} +- Demonstrations: 35 min +::: + +Here we encourage participants to take the screen share for 3 minutes and +demonstrate either some tool or trick they found useful for their teaching or +something from a course you liked. diff --git a/_sources/feedback-and-impact.md.txt b/_sources/feedback-and-impact.md.txt new file mode 100644 index 0000000..698de4a --- /dev/null +++ b/_sources/feedback-and-impact.md.txt @@ -0,0 +1,200 @@ +# How we collect feedback and measure impact + +:::{objectives} +- Discuss how one can collect feedback from learners ("what can we improve?"). +- Discuss how we convert feedback into actionable items. +- Discuss how we measure the impact of teaching ("did we achieve our goals?"). +- Discuss the "why". +- Get to know the reasons and sources of inspiration behind major lesson and workshop updates. +::: + +:::{instructor-note} +- Discussion: 20 min +- Exercises: 10 min +::: + + +## Asking questions before the workshop + +- Motivation: Know your audience. +- Until 2021 we had a pre-workshop survey: + - Data, questions, and notebook: + - Zenodo/DOI: +- After 2021 we incorporated some of the questions into the registration form. + - Easier registration experience for participants. + - After 5 years of running workshops, we had a good idea of what to expect. + + +## Collecting feedback as we teach + +- Each day we ask for feedback in the collaborative notes. + - One good thing about today. + - One thing to improve for next time. + - Any other comments? +- During the workshop we sometimes check in and ask about the pace, example: + ``` + How is the speed so far? (add an "o") + - Too fast: oooooo + - Too slow: ooo + - Just right: ooooooooooooooooooo + ``` +- We publish all questions, answers, and feedback. Example: +- How we follow up: + - Some problems we can fix already before the next workshop day. + - We convert feedback/problems into GitHub issues and track these close to the lesson material. + + +## Trying to measure impact with longer-term surveys + +- Motivation: Understand the long-term impact of our workshops. Have something to show to funders. +- 2024 post-workshop survey: + - Blog post: + - Questions, notebook, and figures: + - Zenodo/DOI: +- 2021 version: + - Data, questions, notebook, and figures: + - Zenodo/DOI: +- How we use the results: + - When reporting to funders. + - When planning future workshops and bigger picture changes. + + +## Lessons learned + +- Think about how to measure impact/success from the beginning. +- **Make the feedback and survey results public**. +- Make the results persistent and citable. +- Have a mechanism to follow-up on feedback. +- Anonymization is more than just removing or dissociating names. +- Take time designing your survey and collect feedback on the survey itself. + + +## Take time designing your survey + +We are not experts in survey design but we reached out to RISE Research +Institutes of Sweden to get feedback on our survey questions. They provided us +with a lot of valuable feedback and suggestions for improvements. +Below are few examples. + + +### Example 1 + +First version of our survey question about impact: +- "Do our workshops help to save time in future?" Please quantify in hours saved: ... + +Feedback: +- Difficult to answer. +- Since when? Until all eternity? + +```{figure} feedback-and-impact/survey-impact1.png +:width: 80% +:class: with-border +:alt: Screenshot of earlier version of the survey question about impact. + +Earlier version of the survey question about impact. +``` + +Feedback: +- The question "Do our workshops help to save time in future?" is unspecified, + unnecessary, and leading. +- "No time saving" does not match the wording "save time" in the question. + +```{figure} feedback-and-impact/survey-impact2.png +:width: 80% +:class: with-border +:alt: Screenshot of later version of the survey question about impact. + +Later version of the survey question about impact. +``` + +- The wording "have you saved" now matches "No time saved". + + +### Example 2 + +- Earlier version: + ``` + Would you judge your code to be better reusable/reproducible/modular/documented + as a result of attending the workshop? + + - More reusable + - More reproducible + - More modular + - Better documented + - None of the above + ``` +- Feedback: The question is not neutrally formulated and risks leading to + over-reporting of yes answers. Consider balancing so that the questions are + formulated more neutrally. +- Reformulated to: + ``` + After attending the workshop, would you judge your code to be + more reusable or not more reusable? + + - My code is more reusable + - My code is not more reusable + - Not sure + ``` + + +### Example 3 + +- Early version: + ``` + What else has changed in how you write code since attending the workshop? + + [free-form text field] + ``` +- Feedback: Leading and assumes that something has changed. +- Reformulated to: + ``` + Has anything else changed in how you write code for your research after + attending the workshop? + + [free-form text field] + ``` + + +### Example 4 + +- Earlier version: + ``` + Has it become easier for you to collaborate on software development with your + colleagues and collaborators? + + - Yes + - Not sure + - No + ``` +- Feedback: + - Leading question. + - Avoid "Yes" and "No" response options because respondents tend to answer + "Yes" if that option is available, leading to a risk of measurement error + (acquiescence bias). + - Do not place "Not sure" in the middle of the scale because it captures + participants who actually don't know and should therefore be placed at the + bottom instead of in the middle of the scale. +- Reformulated to: + ``` + After attending the workshop, has it become easier or not for you to + collaborate on software development with your colleagues and collaborators? + + - Collaboration is easier + - Collaboration is not easier + - Not sure + ``` + + +## Exercise: Group discussion (10 min) + +:::{exercise} Group discussion using the collaborative notes +- What tricks/techniques have you tried in your teaching or seen in someone + else's teaching that you think have been particularly effective in collecting + feedback from learners? +- Can you give tips or share your experiences about how to convert feedback + into actionable items? +- How do you measure the impact of your teaching? Any tips or experiences about + what you have tried or seen other courses do? +- Anybody knows of good resources on survey design? Please link them in + the collaborative notes. +::: diff --git a/_sources/guide.md.txt b/_sources/guide.md.txt new file mode 100644 index 0000000..3c956d8 --- /dev/null +++ b/_sources/guide.md.txt @@ -0,0 +1,91 @@ +# Instructor guide + + +## Target audience + +- Everyone teaching online workshops about computational topics or interested in teaching. +- Previous and future instructors and helpers of CodeRefinery workshops. + + +## Timing + +**Session 1** +- 15 min: Intro +- 45 min: Lesson design and development +- 15 min: Break +- 45 min: Lesson template +- 15 min: Break +- 30 min: How we collect feedback and measure impact +- 10 min: Outro and feedback + +**Session 2** +- 15 min: Intro +- 10 min: About the CodeRefinery project and CodeRefinery workshops in general +- 30 min: Collaborative notes and interaction +- 15 min: Break +- 35 min: Workshop overview, roles, onboarding/installation, helpers +- 20 min: Sound +- 15 min: Break +- 30 min: Screenshare +- 10 min: Outro and feedback + +**Session 3** +- 15 min: Intro +- 30 min: Computational thinking +- 15 min: Break +- 30 min: Teaching philosohies +- 30 min: Co-teaching +- 15 min: Break +- 35 min: Sharing teaching tips, tricks, tools etc +- 10 min: Outro and feedback + +**Session 4** +- 15 min: Intro +- 10 min: Why we stream +- 20 min: Behind the stream +- 15 min: Video editing (part 1) +- 15 min: Break +- 25 min: Video editing (part 2, exercise) +- 20 min: OBS introduction +- 15 min: Break +- 30 min: OBS setup +- 15 min: What's next? + +## Talking points for each sessions intro + +- Brief CodeRefinery intro +- Instructors intros +- Notes intro + - Check-in + - Icebreaker + - Participant intros in breakoutrooms (Random assign first, then same for whole session) +- Daily schedule, learning objectives +- Code of conduct +- Chat (please use collaborative notes) + +## Participant preparations for each session +Copied from e-mail communication with participants before each session. + +**Session 1:** +In general you will only need your brain for the exercises and discussions, but some will have the option to go deeper, which may require some accounts or tools to be set-up. We will inform about these things the week before each session. + +For Session 1 we recommend to have a GitHub account (https://coderefinery.github.io/installation/github/#github). There will be an optional exercise where you can build a lesson locally. This requires a basic Python environment (https://github.com/coderefinery/sphinx-lesson-template/blob/main/requirements.txt), but do not worry if you cannot or do not want to set up these, there will be plenty of other exercises. + +**Session 2:** +In general you will only need your brain for the exercises and discussions. To get the most out of this workshop day we recommend that you join the session with the same computer, display and microphone setup as you would usually use for teaching/ presenting. It may also help to get familar with the different options your computer and Zoom setup provides for screenshare and audio adjustments. +But it is not a must. + +**Session 3:** +In general you will only need your brain for the exercises and discussions. If you want to share some "cool gem" in the last episode of this workshop day, please update your registration (link to edit can be found in the registration confirmation e-mail sent by support@coderefinery.org or noreply@neic.org). This is very low barrier, you do not have to be the developer of a tool or technique to share with the group what makes it useful for you; and it does not even have to be cool, sometimes the small "normal" things are the best. You can check out some topics that have been proposed so far in this GitHub issue (#90), you can also comment there if you want to add or change your topic. These will be lightning talk length, so something between 2-5 min depending on how many are interested to share something, but we can collect them all in the collaborative notes for further exploration/reading. +But it is not a must. + +**Session 4:** +This upcoming session (session number 4) will cover the technical aspects of CodeRefinery-style online teaching. These topics have never before been covered in this much detail, so if it's interesting to you, don't miss it. (You might also want to pass this on to others who are interested in technical production of online events; registration is still open!). + +First, we talk about why we stream (how we got here, advantages, disadvantages, how to be an instructor in a livestreamed workshop, and what it looks like from a broad level from the production side) + +Then, we show how we are able to release videos so quickly. This is useful far beyond CodeRefinery, and there are also some hands-on exercises. Come prepared to set up a Python environment and the ffmpeg command line tool if you want to try these. + +Finally, we see details about how to set up Zoom→Livestream environment for yourself. There isn't time to do this as a proper exercise, but it's the starting point and the instructor will offer help after the course for those interested. If you want to try this out during the session, install OBS Studio in advance. + + diff --git a/_sources/index.md.txt b/_sources/index.md.txt new file mode 100644 index 0000000..6adb709 --- /dev/null +++ b/_sources/index.md.txt @@ -0,0 +1,122 @@ +# Train the trainer workshop + +::::{admonition} August/September 2024 CodeRefinery train the trainer workshop + +Do you teach the use of computers and computational tools? Are you curious about scaling your training and learn about tested and proven practices from CodeRefinery workshops and other trainers? Join us for the CodeRefinery train the trainer workshop: four self-contained sessions on tools and techniques for computational training offer a great chance to enhance your teaching skills and learn about new tools and practices. What you will learn is also used a lot outside CodeRefinery, whenever good beginner friendly training is needed. + +**Learning objectives:** +- Learn about tools and techniques and practice to create engaging online teaching experiences (screenshare, audio, etc.). +- Become mentally ready to be an instructor in a collaborative interactive online workshop (not only large workshops but in general). +- Learn how to design and develop lesson material collaboratively. + +**Target audience:** +- Everyone teaching online workshops about computational topics or interested in teaching. +- Previous and future instructors and helpers of CodeRefinery workshops. + +**Prerequisites:** +An interest in teaching. + +**Workshop structure:** +We aim for a mix of modular presentations and work in small groups. The latter will be done in breakoutrooms - +be prepared to switch on your camera and have a fruitful exchange with fellow participants! + +**Organizers and instructors:** + +The workshop is organized by [partner organizations of the CodeRefinery project](https://coderefinery.org/about/partners/). + +Facilitators and instructors: + +- Radovan Bast +- Richard Darst +- Bjørn Lindi +- Dhanya Pushpadas +- Jarno Rantaharju +- Stephan Smuts +- Stepas Toliautas +- Samantha Wittke + + +**Content and timing:** + +The workshop consists of four sessions every Tuesday between August +13th and September 3rd 2024, +{localtime}`09:00 13 August 2024 +02:00 (HH:mm)` to +{localtime}`12:00 13 August 2024 +02:00 (HH:mm z/zzz)`: + +- Session 1: About lesson design, deployment and iterative improvement (Aug 13) +- Session 2: Tools and techniques adopted in CodeRefinery workshops (Aug 20) +- Session 3: About teaching & cool things we all would like to share (Aug 27) +- Session 4: Workshop streaming practices and post-workshop tasks (Sep 3) + +You can join all sessions, or the just the ones that interest you. More details on each session will be shared later. + +The workshop is **free of charge for everyone**, please register below to get the Zoom link and other useful information for the workshop. + +The workshop is over and registration is closed now. + +If you have any questions, please write to . +:::: + +```{admonition} +You can find materials of previous similar trainings using the links below: + +- First version of the course in 2019 and then in 2020: + +- Reworked material for our summer workshop 2022 and +for the CarpentryCon 2022 workshop: + +``` + +```{toctree} +:maxdepth: 1 +:caption: Session 1 + +lesson-development +lessons-with-git +feedback-and-impact +``` + +```{toctree} +:maxdepth: 1 +:caption: Session 2 + +coderefinery-intro +collaborative-notes +overview +sound +screenshare +``` + +```{toctree} +:maxdepth: 1 +:caption: Session 3 + +computational-thinking +teaching-philosophies +co-teaching +cool-gems +``` + +```{toctree} +:maxdepth: 1 +:caption: Session 4 + +session-4-intro +why-we-stream +streaming +video-editing +obs +obs-config +streaming-whats-next +``` + +```{toctree} +:maxdepth: 1 +:caption: Resources + +notes-archive +guide +All lessons +CodeRefinery +Reusing +``` diff --git a/_sources/lesson-development.md.txt b/_sources/lesson-development.md.txt new file mode 100644 index 0000000..76e79bf --- /dev/null +++ b/_sources/lesson-development.md.txt @@ -0,0 +1,204 @@ +(lesson-design)= + +# Lesson design and development + +:::{objectives} +- We share our design processes for teaching material and presentations. +- Learn how to design lessons "backwards", starting from learning objectives + and learner personas. +- Learn good practices for improving existing material based on feedback. +::: + +:::{instructor-note} +- Discussion: 20 min +- Exercises: 35 min +::: + + +## Exercise: How do you design your teaching material? + +:::{exercise} We collect notes using a shared document (5 min) +- When you start preparing a new lesson or training material, where do you start? +- What tricks help you with "writer's block" or the empty page problem? +- Maybe you haven't designed training material yet. But how do you start when creating a new presentation? +- If your design process has changed over time, please describe what you used to do and what you do now instead. +- What do you know now about preparing lessons/training/presentations that you wish you knew earlier? +::: + + +## Creating new teaching material + + +### Typical problems + +- Someone creates a lesson, but they think about what is interesting to them, + not what is important for the learners. +- "I want to show a number of things which I think are cool about + tool X - how do I press these into 90 minutes?" +- Write down material you want to cover and then sprinkle in some exercises. +- Thinking about how I work, not how the learners work. +- Trying to bring learners to their level/setup, not trying to meet the learners + where they are. +- Not really knowing the learning objectives or the learner personas. + + +### Better approach + +Good questions to ask and discuss with a group of colleagues **from diverse backgrounds**: +- What is the expected educational level of my audience? +- Have they been already exposed to the technologies I am planning to teach? +- What tools do they already use? +- What are the main issues they are currently experiencing? +- What do they need to remember/understand/apply/analyze/evaluate/create + ([Bloom's taxonomy](https://en.wikipedia.org/wiki/Bloom%27s_taxonomy))? +- Define learner personas. +- It may be an advantage to share an imperfect lesson with others early to + collect feedback and suggestions before the lesson “solidifies” too much. + Draft it and collect feedback. The result will probably be better than + working in isolation towards a "perfect" lesson. + + +### The process of designing a lesson "backwards" + +As described in ["A lesson design process" in the book Teaching Tech +Together](https://teachtogether.tech/en/index.html#s:process): + +1. Understand your learners. +1. Brainstorm rough ideas. +1. Create an summative assessment to know your overall goal. + > [Think of the things your learners will be able to do at the end of the lesson] +1. Create formative assessments to go from the starting point to this. + > [Think of some engaging and active exercises] +1. Order the formative assessments (exercises) into a reasonable order. +1. Write just enough material to get from one assessment (exercise) to + another. +1. Describe the course so the learners know if it is relevant to them. + + +## Improving existing lessons + +:::{discussion} All CodeRefinery lessons are on GitHub +- Overview: +- All are shared under CC-BY license and we encourage [reuse and modification](https://coderefinery.org/lessons/reusing/). +- Sources are all on GitHub: +- Web pages are generated from Markdown using [Sphinx](https://www.sphinx-doc.org/) + (more about that in the episode {ref}`lessons-with-git`). +- We track ideas and problems in GitHub issues. +::: + +Collect feedback during the workshop: +- Collect feedback from learners and instructors ([Example from a past + workshop](https://coderefinery.github.io/2024-03-12-workshop/questions/)). +- Convert feedback about lessons and suggestions for improvements into issues + so that these don't get lost and stay close to the lesson material. + +Collect feedback before you start a big rewrite: +- First open an issue and describe your idea and collect feedback before you + start with an extensive rewrite. +- For things still under construction, open a draft pull/merge request to collect + feedback and to signal to others what you are working on. + +Small picture changes vs. big picture changes: +- Lesson changes should be accompanied with instructor guide changes (it’s like + a documentation for the lesson material). +- Instructor guide is essential for new instructors. +- Before making larger changes, talk with somebody and discuss these changes. + + +## Use case: our lessons + +As an example to demonstrate the process of designing and improving lessons, we +will have a look at one of our own lessons: [Introduction to version control +with Git](https://coderefinery.github.io/git-intro/). + +- Initial 2014-2016 version + - and + - Amazingly they are still findable! + - Format: Slides and live coding. + - Exercises were separate, during afternoon sessions. +- Some time in 2014-2015 attended Carpentries instructor training. +- 2016: CodeRefinery started. +- 2017: Started a new repository based on the Carpentries lesson template (at the time using Jekyll). + - Exercises become part of the lesson. + - We start in the **command line** and only later move to GitHub. +- 2019: A lot more thought about learning objectives and personas. + - Also license change to CC-BY. +- 2022: Convert lesson from Jekyll to Sphinx. + - Using the tools that we teach/advocate. + - We can have tabs and better code highlighting/emphasis. + - Easier local preview (Python environment instead of Ruby environment which we were not used to in our daily work). +- 2024: Big redesign. We move the lesson closer to where learners are. + - Start from GitHub instead of on the command line. + - Start from an existing repository instead of with an empty one. + - Offer several tracks to participate in the lesson (GitHub, VS Code, and command line) and learners can choose which one they want to follow. + - Blog post: [We have completely changed our Git lessons. Hopefully to the better.](https://coderefinery.org/blog/2024/04/19/git-lesson-rewrite/) +- Next steps? + - Making the lesson citable following + [our blog post](https://coderefinery.org/blog/2024/07/30/lesson-cffs/). + - Improvements based on what we learn from this workshop. + +The overarching trend was to make the lesson simpler and more accessible - to +meet the learners where they are instead of pulling them to the tool choices of +the instructors. Looking back, we learned a lot and the learning process is +not over yet. + + +## Exercise: Discussion about learning objectives and exercise design + +:::{exercise} We work in groups but use the shared document as result (20 min) +1. As a group **pick a lesson topic**. It can be one of the topics listed here but + you can also choose something else that your group is interested in, or a topic + that you have taught before or would like to teach. Some suggestions: + - Git: Creating a repository and porting your project to Git and GitHub + - Git: Basic commands + - Git: Branching and merging + - Git: Recovering from typical mistakes + - Code documentation + - Jupyter Notebooks + - Collaboration using Git and GitHub/GitLab + - Using GitHub without the command line + - Project organization + - Automated testing + - Data transfer + - Data management and versioning + - Code quality and good practices + - Modular code development + - How to release and publish your code + - How to document and track code dependencies + - Recording environments in containers + - Profiling memory and CPU usage + - Strategies for parallelization + - Conda environments + - Data processing using workflow managers + - Regular expressions + - Making papers in LaTeX + - Making figures in your favorite programming language + - Linux shell basics + - Something non-technical, such as painting a room + - Introduction to high-performance computing + - A lesson you always wanted to teach + - ... +1. Try to define 2-3 learning objectives for the lesson and write them down. + You can think of these as "three simple enough messages that someone will + remember the next day" - **they need to be pretty simple**. +1. Can you come up with one or two engaging exercises that could be used to + demonstrate one of those objectives? + **They should be simple** enough people can actually do them. Creating simple exercises is not easy. + Some standard exercise types: + - Multiple choice (easy to get feedback via a classroom tool - try to design each wrong answer so that it identifies a specific misconception). + - Code yourself (traditional programming) + - Code yourself + multiple choice to see what the answer is (allows you to get feedback) + - Inverted coding (given code, have to debug) + - Parsons problems (working solution but lines in random order, learner must only put in proper order) + - Fill in the blank + - Discussions, self directed learning exercises +::: + + +## Great resources + +- [Teaching Tech Together](http://teachtogether.tech/) +- [Our summary of Teaching Tech Together](https://coderefinery.github.io/manuals/teaching-tech-together/) +- [Ten quick tips for creating an effective lesson](https://doi.org/10.1371/journal.pcbi.1006915) +- [Carpentries Curriculum Development Handbook](https://cdh.carpentries.org/) +- [Our manual on lesson design](https://coderefinery.github.io/manuals/lesson-design/) diff --git a/_sources/lessons-with-git.md.txt b/_sources/lessons-with-git.md.txt new file mode 100644 index 0000000..f91a0e9 --- /dev/null +++ b/_sources/lessons-with-git.md.txt @@ -0,0 +1,217 @@ +(lessons-with-git)= + +# Lessons with version control + +:::{objectives} +- Understand why version control is useful even for teaching material +- Understand how version control managed lessons can be modified. +- Understand how the CodeRefinery lesson template is used to create new lessons +::: + +:::{instructor-note} +- Discussion: 25 min +- Exercises or demos: 20 min +::: + + +## Why version control? + +- If you are in CodeRefinery TTT, you probably know what version + control is and why it is important. +- The benefits of version control also extend to lessons: + - Change history + - Others can submit contributions + - Others can make derived versions and sync up later + - Same workflow as everything else + - Write it like documentation: probably more reading after than + watching it as a presentation. +- Disadvantages + - "What you see is what you get" editing is hard + - Requires knowing version control + +:::{discussion} Accepting the smallest contribution + +Question: if someone wants to make a tiny fix to your material, can they? +::: + +## Tour of lesson templates options + +There are different ways to make lessons with git. Some dedicated to +teaching: + +- CodeRefinery + - Example: This lesson itself + - Based on the Sphinx documentation generator + - [sphinx-lesson](https://github.com/coderefinery/sphinx-lesson) is + *very* minimal extra functionality +- Carpentries + - Example: + - Based on R and Rmarkdown + +Our philosophy is that anything works: it doesn't have to be just +designed for lessons + +- Jupyter Book + - Example: https://jupyterbook.org/ + - Note: is based on sphinx, many extensions here are used in CR lessons +- Various ways to make slides out of Markdown +- Cicero: GitHub-hosted Markdown to slides easily + - [Demo: Asking for Help with + Supercomputers](https://cicero.xyz/v3/remark/0.14.0/github.com/bast/help-with-supercomputers/main/talk.md/#1) + [The source](https://github.com/bast/help-with-supercomputers/blob/main/talk.md) +- Whatever your existing documentation is. + +**We like the CodeRefinery format, but think that you should use +whatever fits your needs the most.** + + +## [Sphinx](https://www.sphinx-doc.org) + +- We build all our lesson material with Sphinx +- Generate HTML/PDF/LaTeX from RST and Markdown. +- Many Python projects use Sphinx for documentation but **Sphinx is not limited to Python**. +- [Read the docs](https://readthedocs.org) hosts public Sphinx documentation for free! +- Also hostable anywhere else, like Github pages, like our lesson material +- For code a selling point for Sphinx is that also API documentation + is possible. + +Sphinx is a doc generator, not HTML generator. It can: + +- Markdown, Jupyter, and ReST (and more...) inputs. Executable inputs. + - jupyter-book is Sphinx, so anything it can do we can do. This was one of the + inspirations for using Sphinx +- Good support for inline code. Much more than static code display, if + you want to look at extensions. +- Generate different output formats (html, single-page html, pdf, epub, etc.) +- Strong cross-referencing within and between projects + + +## [CodeRefinery lesson template](https://github.com/coderefinery/sphinx-lesson-template) + +It is "just a normal Sphinx project" - with extensions: +- [Sphinx lesson extension](https://github.com/coderefinery/sphinx-lesson) + - adds is various directives (boxes) tuned to lesson purposes + - provides a sample organization and template repo you can use so that lessons look consistent +- Sphinx gives us other nice features for free + - Tabs: they are very important for us and allow us to customize in-place instead of copying everything and fragmenting lessons + - Emphasize lines: they make it easier to spot what has changed in longer code snippets + - Various input formats + - Markdown (via the MyST-parser), ReStructured text, Jupyter + Notebooks. + - Many other features designed for presenting and interacting with code +- It's fine if you use some other static site generator or git-based lesson method. + +:::{demo} Instructors go through the building and contributing process + +Depending on the course, instructors will demo what is roughly +exercise 4 below. Or a course might go straight to exercises. + +- Instructors decide what change they would want to make +- Instructors clone the repository +- **Instructors make the change** +- **Instructors set up the build environment** +- **Instructors build and preview** +- Instructors command and send upstream +::: + + +## Exercises + +Some exercises have prerequisites (Git or Github accounts). Most +instances of this course will have you do **1 and 2** below. + +:::{exercise} Lesson-VCS-1: Present and discuss your own lesson formats + +We don't want to push everyone towards one format, but as long as you +use Git, it's easy to share and reuse. + +- Discuss what formats you do use +- Within your team, show examples of the lessons formats you use + now. Discuss what is good and to-be-improved about them. +- Look at how they source is managed and how easy it might be to edit. +::: + + +:::{exercise} Lesson-VCS-2: Tour a CodeRefinery or Carpentries lesson on Github +- Look at either a CodeRefinery or Carpentries lesson + - CodeRefinery Git-Intro: [Lesson](https://coderefinery.github.io/git-intro/), [Github repo](https://github.com/coderefinery/git-intro) + - Carpentries Linux shell: [Lesson](https://swcarpentry.github.io/shell-novice/), [Github repo](https://github.com/swcarpentry/shell-novice/) +- Can you find + - Where is the content of the lessons? + - What recent change propsals (pull requests) have been made? + - What are the open issues? + - How you would contribute something? + - How would you use this yourself? +::: + + +:::{exercise} Lesson-VCS-3: Modify a CodeRefinery example lesson on Github +In this, you will make a change to a lesson on Github, using only the +Github interface. (Github account required, and we assume some +knowledge of Github. Ask for help in your team if it is new to you!) + +- Navigate to the example lesson we have set up: + [repo](https://github.com/coderefinery/sphinx-lesson-scratch-space), [web](https://coderefinery.github.io/sphinx-lesson-scratch-space/) +- Go to some page and follow the link to go to the respective page on + Github. (Alternatively, you can find the page from the Github repo directly). +- Follow the Github flow to make a change, and open a Pull Request + with the change proposal: + - Click on the pencil icon + - Make a change + - Follow the flow to make a commit and change. You'll fork the + repository to make your own copy, add a message, and open a pull + request. + +We will look at these together and accept some changes. +::: + + +:::{exercise} Lesson-VCS-4: Clone and build a CodeRefinery lesson locally +In this exercise, you will use Git to clone one a CodeRefinery lesson +and try to preview it locally. It assumes installation and knowledge +of Git. + +- Use this sample repository: + [git-intro](https://github.com/coderefinery/git-intro) (or whatever + else you would like) +- Clone the repository to your own computer +- Create a virtual environment using the ``requirements.txt`` + contained within the repository. +- Build the lesson. + - Most people will probably run: `sphinx-build content/ _build/` + - If you have `make` installed you can `make html` + - Look in the `_build` directory for the built HTML files. + +Overall, this is pretty easy and straightforward, if you have a Python +environment set up. The [CodeRefinery documentation +lesson](https://coderefinery.github.io/documentation/sphinx/) teaches +this for every operating system. + +This same tool can be used to build documentation for other software +projects and is pretty standard. +::: + + +:::{exercise} Lesson-VCS-5: (advanced) Create your own lesson using the CodeRefinery format +In this lesson, you'll copy the CodeRefinery template and do basic +modifications for your own lesson. + +- Clone the lesson template: + https://github.com/coderefinery/sphinx-lesson-template +- Attempt to build it as it is (see the previous exercise) +- How can you do tabs? +- How can you highlight lines in code boxes? +- How can you change color, logo and fonts? +- What directives are available? + +::: + + +## Summary + +:::{keypoints} +- Version control takes teaching materials to the next level: + shareable and easy to contribute +- There are different formats that use version control, but we like + Sphinx with a sphinx-lesson extension. +::: diff --git a/_sources/notes-archive.md.txt b/_sources/notes-archive.md.txt new file mode 100644 index 0000000..178256f --- /dev/null +++ b/_sources/notes-archive.md.txt @@ -0,0 +1,1605 @@ +# Collaborative notes archives from workshops + +## August/September 2024 + +### Day1: Session 1 (13.08.24) - About lesson design, deployment and iterative improvement + +#### :calendar: Schedule + +| Time (CEST) | Title | EEST (UTC+3) | BST (UTC+1) | +|---------------|--------------------------------------------|---------------|---------------| +| 8.45 - 9.00 | Connecting time | 9.45 - 10.00 | 7.45 - 8.00 | +| 9.00 - 9.15 | Intro and Icebreaker | 10.00 - 10.15 | 8.00 - 8.15 | +| 9.15 - 10.00 | Lesson design and development | 10.15 - 11.00 | 8.15 - 9.00 | +| 10.00 - 10.15 | Break | 11.00 - 11.15 | 9.00 - 9.15 | +| 10.15 - 11.00 | Lessons with version control | 11.15 - 12.00 | 9.15 - 10.00 | +| 11.00 - 11.15 | Break | 12.00 - 12.15 | 10.00 - 10.15 | +| 11.15 - 12.00 | How we collect feedback and measure impact | 12.15 - 13.00 | 10.15 - 11.00 | + +#### :icecream: Icebreaker + +##### Check-in + +Which emoji best describes your current state of mind? [Emoji cheat sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) +- :Decaffed ... and going strong ... +- :coffee: 🤔 +- :100: (ironically!) :coffee: intake happening +- :smile: +- :tired_face: +- :coffee: :party: +- :coffee: :happy: +- 😪 +- just got zoom installed / before my coffee +- :smil- +- :sweat_smile: (+) +- :yawning_face: +- :is it morning already? +- :smile: +- :yawning_face: +- :nerded_face: +- 🥵 +- :smile: +- :sleeping: +- :sleepy: :coffee: :smiley_cat: +- 🥳 +- :coffee: +- :coffee: + +##### Introduction in breakoutrooms. + +- Name / Affiliation / Location + +##### About teaching + +What is the hardest thing about teaching for you? +- Knowing how "it's going", whether learners are happy or not (especially when teaching online) :+1: +- The preparation the night before. It is always much more that I would hope, no matter how prepared I want it to be :+1: :+1: +- Managing groups with vastly different academic backgrounds +- Teaching wide spectrum of skill level at the same time. :+1: :+1: :+1: :+1: +- Time management! (Knowing how much can fit in a sessions) :+1: :+1: +- General preparation time, how to fit it into the regular work schedule, and estimate how much time is needed for prep. +- How to reduce too much text into just the right amount +- Preparation of the session material and estimating the right amount of time for each section +- Getting learners to take the first step: sign up for and attend a workshop, when they don't think programming is a skill they can learn +- Getting learners to take the _second_ step: translating what they've learned in a workshop into something they can apply +- preparation and time management +- Engaging with the students which was much easier for me when I used to coach +- Finding the right depth for an unknown audience for "my topic" +- education background of participants and their learning objectives + +What is the best thing about teaching for you? +- Seeing when learner gets interested/curious about something and takes inspiration from the course. :+1: +- Seeing it works and someone can do something new. +- Motivated students grasping new stuff +- Students picking up and running with the matertial and skills I give them and using it for their own work. :+1: +- The "ah-ha!" moment when a student gets it! :+1::100: :+1: +- Learning from students who know about some topic more than you do. :+1: +- Being able to help people reach their goals, by showing them something new. +- Teaching is optimism acted out in the hope of making a difference both ways I suppose. +- The feeling of accomplishment when you see learning grow and implement the learnings :book: +- mutual learning and impact on learners :+1: +- Results and feedbacks / Mutual interests and interesting discussions +- mutual learning and I can also learn lots of things and new ideas from participants + + +#### :question: Questions + +##### General / Practicalities + +- Will the material be made available? + - Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/ + - Can I share them with a colleague + - Yes please :) + - Can I resuse them in my own teaching? + - Yes please :) +- Will these sessions be recorded? + - No, but the materials (see above) should include everything needed for self-learning. +- Can I get a certificate for this workshop? + - You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended. +- How often will we be talking in breakout rooms? I'm not in a place where I can talk, so if we're going to talk a lot I'll need to move offices + - We'll have about one breakoutroom session per episode +- +##### Episode 1: Lesson design and development + +Materials: https://coderefinery.github.io/train-the-trainer/lesson-development/ +**Discussion:** + +- When you start preparing a new lesson or training material, where do you start? + - I look at existing materials on the same topic, but chose/refine topics based on the perceived needs/interests of the presumed audience + - Outline of structure and Material collection for a new lesson :+1: + - What material I have already? (what other material is already out there?) + - Start by looking for related resources (documents, videos, courses, etc) to have a base data and better understanding of what have been done around the topic + - Know your audience + - Review existing material + - Think about learning objectives (to keep focus on essential things) + - Think of three things simple enough that they will be remembered the next day. Design around that. + - I write down the thoughts that I have and then go back and structure it. + +- What tricks help you with “writer’s block” or the empty page problem? + - Write anything down that comes to mind, sometimes draw something, looking out the window :) + - Do a mind map - what concepts do I want to get across? + - Starting small, for example a list of headings and then building around it. :+1: + - What does one know about the target audience and why should they be spending longer than 1 minute listening to what they will eventually get to hear? + - Get some inspiration from another source. + - Start with the three things above + - Start with the plan and the overview design + - Some kind of outline / main message(s) + - Start with three things. Three supporting points for each of these. +- Maybe you haven’t designed training material yet. But how do you start when creating a new presentation? + - Think about the learning objectives and try to break them down into steps + - Title, Objectives, target audience and Plan + - Some kind of outline / main message(s). Get as many images as I can, instead of words + - Draft an outline and use chatgpt to fill in details + - Example of how the teaching content is applied in a real-world context +- If your design process has changed over time, please describe what you used to do and what you do now instead. + - I look more at existing materials and try to get more information about the audience. Unfortunately getting information about the audience before the event is hard + - I used to start from the begginning and get from there but that often meant a very polished start and a rushed end. Now I try an overview first, then fil out sparsed details at every section + - Updating the data and tweak the presentation + - If I am teaching a small group (or one to one) talk to them before hand - find out what they know already, what they want to learn. +- What do you know now about preparing lessons/training/presentations that you wish you knew earlier? + - less is more. It's better to have 2-3 main messages rather than trying to show everything in one go :+1: :+1: :+1: :+1: + - how much practice time the learners need to master what's taught + - Don't worry about something going wrong. It often makes the lesson (and thus the material) more presistent in memory. :+1: + - Try and remove everything except what you want the person to learn + - That's a very tough part for me in the sense that I never know how much of an underlying "black box" is still ok.... + - Designing intermediate materials is hard, and requires putting some "gatekeeping" making sure that learners are directed to appropriate courses + - When I see a cool graphic, concept, slide, etc., download it and save it in my 'new-materials' folder to use later on! + - I have come to the conclusion that perhaps a more "agile" approach to developing materials (try to do design/teaching iterations quickly) might be the best way to go, but there are risks with this approach too + +**Questions** + +- From zoom chat: Can you expand on what a learner persona is? + - A defined example person described in terms of the materials you are preparing, making up a story about the background and interest of t + - Answer from chat: A learner persona is a blackbox which has a very simple algorithm inside: GIGO. + - Answer from chat: I think it's the same as ICP (Ideal customer persona) where you describe the learner as a customer + - Answer from chat: I'm a big fan of "How Learning Works" by Ambrose et al https://bookshop.org/p/books/how-learning-works-eight-research-based-principles-for-smart-teaching-michele-dipietro/18640868?ean=9781119861690 + - See also book: [Teaching tech together](http://teachtogether.tech/) +> CodeRefinery lessons: https://coderefinery.org/lessons/ +- From chat: Do you have an example of an instructor guide? + - One example from our [reproducible research lesson](https://coderefinery.github.io/reproducible-research/guide/) + - Another from git intro: https://coderefinery.github.io/git-intro/guide/ +- From zoom chat: Do you have a "measure" of how better are the new lesson compared to the old ones? Does it make sense to talk about measurements here? + - So far we only have daily feedback that we collect at the end of the day and we can compare that to earlier daily feedbacks. More about that in the last episode of today. But measuring this is indeed not easy and it also takes time to capture the effect during longer-term surveys. Some of the changes were more leap-of-faith than based on data. + - I guess that sometimes one can use "compelling arguments" instead of data to justify a decision +- Software Carpentry does teach using the command line, and gives a session on the command line before. What do you think about this approach? Are you stating that a 3-hour lesson about CLI is not sufficient to make people comfortable enough to use that for version control? + - Yes, good question. For CR we consider it a more advanced step: we do think people should learn command line, but it's for a different course. We accept some people might not know it or want to know it so adapt to that. + - In general, we've found the "you need X, but have to learn A, B, and C first" approach should be avoided if possible: people are busy, try to reach people where they are. + +:::danger +[Exercise](https://coderefinery.github.io/train-the-trainer/lesson-development/#exercise-discussion-about-learning-objectives-and-exercise-design) in breakoutrooms +::: + +- Room 1 + - Research data management + - Objectives + - Research life cycle + - FAIR principles (Findable, Accessible, Interoperable, Reusable) + - Exercise + - develop a data management plan (DMP) that outlines how their research data will be handled throughout its lifecycle. + +- Room 2: What is the difference between eating breakfast and sitting through a lecture? (Tip: Start by listing the similarities ...) +- Room2 : Making papers in LaTeX + - What is LaTex and how is it different from editors like Word + - Basic Structures + - How to find and use a template + - Including figure & table + - How to use references and labels + - Exercise: to create a new LaTeX document & edit it + - Excercise: common error messages: can you find the error in this code? + - Exce +- Room 3 + - GPU Programming (1 hour intro) + - Learning objectives: + - What is GPU programming. + - When is it usable, beneficial to use GPU programming? + - What are technologies to do GPU programming? + - [What are and how to manage typical issues] + +- Room 4 + - Git / Figures / Project management / data cleaning + - Chose data cleaning + - Three learning objectives: + 1. What do we mean by "clean"? How to identify it? + 2. Identify some common problems in a dataset + 3. Identifying and handling missing values/fields + - Exercise + 1. Discuss problems, find the most common ones + - In small groups + - What problems have you run into with datasets you've worked with? + - What problems can you imagine, or have you heard about from colleagues/news/social media? + - Report back, instructor collects all problems into a list + 2. Have a dataset to clean; a clean and a messy example + - (identifying) Using a visualisation or overviewing tool? + +- Room 5 + - Jupyter Notebooks + - Learning Objectives + - Can setup an enviroment you can reuse / can share with others / a project. + - The order you run the commands in needs to match the order of the code in the Notebook - otherwise you end up in a pickle. + - Why use a Jupyter Notebook? What are the advantages? Easy to use environment. + - Exercise + - Print variable assignments from different cells - show that the order you run the code is important. + - hand out a domain specific notebook that does some calculations and visualization to run and modify, to show that you can share easily + - show !pip install to add dependencies/features +- Room 6 + - Using GitHub without the command line + - Learning Outcomes: + - Be able to discuss changes before merging changes into the main repository. + - Publish a personal repository page ( I think its called intro repository) + - Share their script/notebook/code/small data on GitHub + - Homepage using GitHub pages or the README that becomes the "index page" of the GitHub user account page + - Learner personas: + - Check the Personas of the learners + - Somebody who has seen/heard of GitHub but hasn't used it yet + - Someone using it for their own work but struggling with collaboration + - Exercises: + - Upload/share an example dataset or script + - Review another collaborators pull request. + - Take part in the discussion on a pull request. +- Room 7 + Linux shell basics: why do we want to teach them? + (this took most of the time for the discussion) + - Learning objectives: + 1. Filesystem: Directory (CLI) - Folder (GUI) analogy + 1. Basic commands (which commands are basic? make a survey of shell histories and get the most common ones) + 1. Basic constructs (e.g., for loops, pipes, while loops... which ones are basic? See above) + +> Note from chat: Zoom timer: https://support.zoom.com/hc/en/article?id=zm_kb&sysparm_article=KB0068677 + +##### Episode 2: Lessons with version control + +Materials: https://coderefinery.github.io/train-the-trainer/lessons-with-git/ + +Poll options: I want to hear about: +- A: Why use version control for teaching materials +- B: Different template options +- C: How CodeRefinery does it; CodeRefinerys lesson template + +Poll vote (multi-select): add a `o` to your answer + - A: ooo + - B: oooooo + - C: oooooooo :ghost: + +Question to audience: if someone wants to make a tiny fix to your material, how hard is it? +- If my material is only in pdf format which is not online, then it is hard. +- I hope it is easy - my material is in GitHub. Nobody has ever done that though! +- Slides: hard to find, easy to edit; Git repos somewhat easy, unless they have to be built locally or with an action; HackMD easiest to edit. + - if you use something like google slides they are not that difficult to find + - known permanent address. Google docs et al fail on that/same for many pads. +- For this material today - very easy! e.g. https://github.com/coderefinery/train-the-trainer/pull/128 +- Template with an edit button in the HTML pointing to the source-code in the repo. + +**Questions/Discussion topics** +> Upcoming CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/ +> Please share with your networks, and let us know if you would like to co-teach a lesson (to support@coderefinery.org or in our [Zulip chat](https://coderefinery.zulipchat.com/)) + +- Changes to the material are sometimes not just tiny fixes. For example, one wants to present a slightly different selection of topics, but maybe some topics are "coupled" (perhaps naturally or perhaps just because of how they are presented), or change the general "theme" (e.g., life sciences vs theoretical physics) while keeping the actual topics the same. How could a lesson be developed to avoid having to do a huge rewrite? + - You can try to modularize your material and keep non topic specific parts non themed. E.g. where you explain the functionality, don't make reference to the example (not simple), so the example can be changed depending on the audience. +- What are the pros/cons of renaming a course / changing a repo name in GitHub? + - It should be relatively unproblematic since GitHub will forward to the new name. + - How long does Github keep the "old" name linked? Is there a max time it's blocked, or changed as soon as a new one appears with the name? + - in my experience it forwards "forever" until I create a new repo with the old name which will break the forward +- what should be in the readme for the git repo? (canonical address? contact points? license!) + - https://coderefinery.github.io/mini-workshop/2/documentation/#often-a-readme-is-enough-checklist + - I miss the url to the (main) repo in the readme + - Do you mean the link to the rendered (lesson) page? + - Link to rendered page: We often have this in the "about" section of the readme (see up right: https://github.com/coderefinery/train-the-trainer) + - this gets lost in a fork, doesn't it? so 20 folks forking and or reuploading the repo somewhere means the url gets lost? + - True, but they might want to have their own version rendered? + - yes, I have had issues finding and contributing to the "master" repo so all benefit. Else it gets cluttered. Both is valid + - Good point though, the link to rendered page should probably also be included in the readme for completeness; ah and the link to the repository too, yes + - so realistically we need a content folder and some more next to the readme as a best practice. sounds good! +- Is myst (markdown renderer) enabled by default in sphinx now? + - to my knowledge no. we add the "myst_parser" extension to conf.py. + +> Cicero: https://cicero.readthedocs.io/ +> Sphinx documentation: https://www.sphinx-doc.org/en/master/ +> Carpentries workbench for creating Carpentries lessons: https://carpentries.github.io/workbench/ +> This is the testing lesson Richard showed: https://coderefinery.github.io/testing/ +> And the corresponding repository: https://github.com/coderefinery/testing +> You can lean back and watch, exercise coming in a bit :) +> Richard will now edit our train the trainer material repository: https://github.com/coderefinery/train-the-trainer +> The Sphinx extension for CodeRefinery lessons: https://github.com/coderefinery/sphinx-lesson +> Empty lesson template to build your own lesson: https://github.com/coderefinery/sphinx-lesson-template + +**More questions** +- Does the coderefinery.org page built on sphinx? + - It's built also from markdown but it uses https://www.getzola.org/ (which is more optimized to render websites, but we could do teaching also with Zola or create the project page using Sphinx) + +- Is there a way to build and preview CR lessons without the command line? + - The GitHub workflow we use creates HTML from all branches. This means that one can push a branch to GitHub, preview it there, and then open a pull request. One thing that would be nice but we don't have yet is if a bot automatically posts the link to the preview to a pull request. + +- For VCS-2, for the Carpentries Linux shell example, Lesson, Github repo, to me it seemed as though the Sandpaper setup they have makes a very nice interface, complicates the relationship between source and output. E.g on the soucre page https://github.com/swcarpentry/shell-novice/blob/main/index.md I could only see to 'Prerequisits' and not 'Download files' on the page https://swcarpentry.github.io/shell-novice/. Perhaps I have missed something? + - I am sorry I don't know the new Sandpaper setup well enough to answer this question. + +- Do we have the instructions to build the lessons available somewhere to try out later? + - https://github.com/coderefinery/sphinx-lesson + +:::danger +Exercise VCS-1 (and VCS-2 (if time)) (https://coderefinery.github.io/train-the-trainer/lessons-with-git/#exercises) in breakoutrooms until xx:05 + +then short summary in main room and then break. + +Use the notes below. Collect a list of lesson formats and discuss what you like about each of them. +::: + +- PDF slides by a presentation program +- pdf slides with beamer in latex under source control. +- Markdown slides via Github +- CodeRefinery template +- Carpentries template +- Google Slides +- git-book +- [Jupyter Book](https://jupyterbook.org/) - allows creating a structured reference website using RST/Markdown, including Jupyter Notebooks to show result of running code +- [mdbook](https://rust-lang.github.io/mdBook/) - create simple/minimal website using Markdown +- [Binder](https://mybinder.org) - allows learners to run their own live version of a github repository with Jupyter Notebooks, with only a web browser +- Jupyter notebooks and jupyterhub platform +- Jupyter + Nbviewer and custom css (read only) + Binder link (hands on) +- RMarkdown +- Quarto Slides +- [Reveal.js](https://revealjs.com/) - write slides in HTML (also supports markdown) + - Example: https://bl-presentations.erambler.co.uk/2024-02-21-idcc24/ +- [Remark.js](https://remarkjs.com/) - write slides in markdown + - Example: https://bl-presentations.erambler.co.uk/2024-02-19-idcc-pids-workshop/ + + +Room discussions: +- Room 1 + - (https://smc-aau-cph.github.io/SPIS/README.html) + - CodeRefinery template + - Shared notes & blogs + +- Room 2 + - demo the exercise + +- Room 3 + - Mix of JupyterLab, Terminal within that, and traditional slides + - Jupyter + RISE (benefit: slides that are editable and executable live) + - Challenges + - present code in an interactive way + - handle lots of images/ figures without too much additional overhead when setting up the material + +- Room 4 + - Material and tools depend on instructors + - Some slide building tools + - https://revealjs.com/ + - https://remarkjs.com/ + - https://github.com/rust-lang/mdBook + - Using flat git repos without fancy styling to make it easier to edit but still version controlled + +- Room 5 + - Using R as a GIS: https://github.com/nickbearman/intro-r-spatial-analysis + - Workbook: RMarkdown, Slides: Quarto + - No continuous intergration + - Having a jupyter nbinder link to test the notebook + - repo lives on codeberg in this example + +- Room 7 + - Ex 1: + - Sphinx, similar to CR + - Sometimes pdfs generated with beamer package (or from pptx and odt), but blows up repository size if in version control + - Ex 2: + - Content + - CR: Content commonly found int the content folder + - SC: Mostly under episodes + - Question that came up: + - is CR/Sphinx approach mostly for technical topics? What about language. + - I guess by our nature it's focused there. But probably could be used for others (I guess it it's much easier to use git in a technical audience.) + + +##### Episode 3: How we collect feedback and measure impact + +Materials: https://coderefinery.github.io/train-the-trainer/feedback-and-impact/ + +**Questions to audience** + +- What tricks/techniques have you tried in your teaching or seen in someone else's teaching that you think have been particularly effective in collecting feedback from learners? + - preparing a survey and emailing it to participants as soon as the event ends (usually get <50% of answers but it's a representative enough sample) + - do engage with the audience, give them the time to get the courage to speak up + - Be the audience yourself + - yes! some problems/issues I don't notice as instructor, only as listener + - Have time (e.g. 5 min) in the session to fill out the feedback form + - If the course/workshop has several days/sections do a couple questions every change, then a full one afterwards + - "Traffic light" feedback (e.g. for pacing or progress on exercises): give each learner two different coloured post-it notes for in-person, or use emoji for online, to indicate a current status +- Can you give tips or share your experiences about how to convert feedback into changes or actionable items? + - ask questions about things you know you don't know + - “Don’t let the noise of others’ opinions drown out your own inner voice.” — Steve Jobs +- When people ask questions / get stuck with a specific step. Is there a typo I can change there and then in the workbook? + - Being able to fix small things on the fly helps sometimes, otherwise open issues if working on github + - If multiple people have the same question, then this is an indication that I should look at this in more detail +- How do you measure the impact of your teaching? Any tips or experiences about what you have tried or seen other courses do? + - "How likely are you to recommend this workshop to others? (0/5)" + - Check the 'Garbage Out' bin, what you find there will be what went across. The rest will be history... +- Anybody knows of good resources on survey design? Please link them here. + - "Our job is to figure out what they're going to want before they do... Our task is to read things that are not yet on the page." - Steve Jobs + +**Questions/Discussion points** + +- Feedback is necessary to design good lessons. Improvement can only be done iteratively. So the faster the iteration (design/teach), the better. But on the other hand, I cannot constantly bomb our community with training event emails. So I would like to try proposing a course many times a year, but I don't want to spam everybody many times a year. + - :+1: + - With CR we also have a calendar that can be imported to different calendar applications, where we add all workshops: https://github.com/coderefinery/calendar/ +- Does an even split of too fast / too slow mean speed is about right?! + - I take it to mean "it's roughly where it should be". Would be better to accomdate the sides better though... (we do try to design for a broad audience: some easy stuff, some advanced stuff, so people can make their own path) + - It could also indicate that the prerequisites/scope are not well defined :+1: + - Based on long term surveys we also know though that even though the workshop might have been to fast, people appreciate having "heard things before and know where to find them later" + - perhaps the even split between too fast/too slow is ok only if the majority of votes goes for "just right" :+1: +- One of the most important disciplines in journalism is to challenge your working premises. (Bill Keller) This applies equally to learning as well. + - Participants can be encouraged to write some posts on LinkedIn. If it is helpful some blurbs can be created for pre and post-workshop to generate more traction for Code Refinery and future participation. + - Ask participants if they use Dev.to, hashnode etc to blog their work or use twitter etc to have a memory of their work. +- Do you have any suggestions for prerequisites? I try to make them clear, but occasionally people attend who clearly do not meet them. :+1: + - I guess it depends how much it matters for the workshop itself. If you have group exercises etc, it probably matters? , lecture style maybe not so much?; important is that the participants themselves know that prerequisites exist and if they meet them + - Sometimese people that do not meet the prerequisites join to get to "know what they don't know", find out where to find information on topics they might get interested in future etc + - Other suggestions? Viewpoints? :) + - Thank you - things for me to think about there :-) + - With CR's latest ideas, we try to make the prerequisites clear, but there is no capicity limit: it's OK if people drop by and are less than prepared: it's livestream, anyone can come. We try to have something for these people, too: learn what you are missing, why you might want to study more in the future. + - Any thoughts on applying this to a more practical focused course, with a total capacity limit (i.e. not like CodeRefinery). +- Everytime you do a course on CodeRefinery, think of it as trying to bake a new cake with an old recipe with no idea about the individual taste preferences of the one you bake the cake for. Then, you will not experience too many surprises. Fine-tuning the recipe for one cohort still remains the 'old recipe' as far as the next 'new cohort' will be concerned. C'est la vie. + - nice analogy! +- Question from chat: For examples 2 & 4, would you also consider using something like a Likert scale? E.g. Rate how well you agree with the statement "My code is more reusable as a result of attending a CodeRefinery workshop" (from 1 Strongly disagree to 5 Strongly agree) + - Thanks! I am new to Likert scale and will read up on it. In my experience numbered answers can be useful for reporting. But I also like questions where we ask for what actually to change. +- Comment from chat: Richard, your point crowns the point of having CodeRefinery, With Radovan's and Samantha's acquiescence assured, I would like to suggest you wear a crown going forward, especially for the CodeRefinery session. Do we have a deal ? + - I don't quite understand this + - I *think* it's a tongue-in-cheek-comment (joke) but I am not sure..... +- What is the ideal way to allow people to interact while course is going on in the main online session, i.e. without a breakout room? Taking a pause or discussion in the background? + - I've had some success with WhatsApp groups for a course - particually ones that run over 4 (or 2) sessions. + - A quick survey/quiz + - Question to the audience that we take time to answer but it helps to show the answers +--- + +### Wrapup + +- Thank you for active participation :) + - We'll continue answering questions after the workshop and make the cleaned up (no names etc) available from the materials +- Next session **Tuesday August 20, 9 CEST: Tools and techniques adopted in CodeRefinery workshops** + - we will talk about on-boarding, install help, roles, screensharing, sound, collaborative notes +- All workshop materials will stay available (after the full workshop also on Zenodo :tools:) +- CodeRefinery community: https://coderefinery.zulipchat.com/ +- If you want to co-teach with us in the upcoming (or next) CodeRefinery workshop (https://coderefinery.github.io/2024-09-10-workshop/); or just want to learn more about this opportunity: Send your name and e-mail address to support@coderefinery.org; we will contact you! + +### Feedback about todays session + +What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session: +- Lesson design approach +- I liked the backwards lesson design, gives a name to a practice I've already been doing :+1: :+1: +- Lessons from code refinery on lesson design. Learning about Sphinx. +- Collaborative notes and anonymized archive of notes. +- it's nice to have a community to discuss these kinds of problems +- Hearing the variety of tools people use for slides (PDF, Quarto, Beamer etc.) +- Good intro of the tools, the jargon and the pedagogical philosophy of teaching tech. +- The absolute openess in having everything publicly available - materials ofc but also questions, discussions, feedback, ... +- Thinking about all content being available publicly and as a git repo +- Thanks for explaining the HedgeDoc interface, with view and edit options + - Is there anyway to come back to this document later (e.g. tomorrow) and see what has changed since now? So I can see if any other questions have been asked/answered? + - There is a "revision" point under "Menu" up right, which shows you different versions of this document +- Modesty: the gentle art of enhancing your charm by pretending not to be aware of it. - Oliver Herford +- + + + +What one thing would you improve about this session? +- Perhaps some more interactivity but can be hard to plan and time + - We'll see what we can do. +- _Maybe_ mix the breakout groups up for each breakout session (although there are advantages to consistency too) :+1: + - yes, pros and cons! For me, having consistency worked well this time. + - Likely we will have different participants next week, and a bit of mixing will happen naturally. +- The pace of the presentations could be a little tighter (the pace is good for a discussion though) +- Richard's voice was only 80% audible + - Sorry to hear that. It seemed fine on my end. Will check better for next session. +- Hands on simulation and collaborative notes +- I found it difficult to follow the presentation and the collaborative notes at the same time + - We will highlight the collaborative notes more in the next session. Our strategy usually is to say to focus on the "teaching part" and use the notes only when needed. Since you can go back and also check the notes later. + - My problem is that I want to follow both since I don't want to miss out on anything. As such, I have both windows (zoom and the notes) open side-by-side. Since there is near-constant real-time typing in the editor, and as such visible movement on screen, I get constantly distracted. This makes following the event quite exhausting. +- Heads up to participants on using the break out rooms on voice interaction and screen sharing. + - Do you mean that we should have mentioned it more clearly in the pre workshop email? +- I found it hard to follow with so many things going on at once... + - A collaborative document being changed at the same time as... + - Someone speaking and explaining content at the same time as... + - Chat in a different application at the same time as... + - Content changing in a termin application. + - Thank you for the feedback. We will remove the Zoom chat out for the next session and explain the use of the collaborative notes more. +- Make more use of defining and then making sure the learning objectives are met + - True we did not talk about them much, will pick that up better for next session. +- UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. - Dennis Ritchie. You need to do a lot to prove that to be wrong, simply put. +- Allocate some time for learners to type in the answers so that we don't have to listen and type at the same time. + +Any other comments? +- It's great to hear other people's experience + - Good to hear :) +- Looking to meet you onsite if there are any events and get more emails from you :) + - We will keep you informed :) +- Thanks for putting this together, I got a lot of inspiration for my own courses + - Good to hear :) +- I didn't know where to ask questions. It would work best *for me* to do it in zoom chat as that's the application that I'm watching in.. + - Sorry for that, just to figure out why: Did you join a bit late? + - No. Perhaps I just missed that or it was too quick for me or something? + - Ok, sorry. Will try to make this more clear in next session. + - Perhaps also because there were so many things going on and jumping around. For me, the zoom chat is the constant (and obvious) place to ask questions while watching a shared screen, trying to find the right place in a moving collaborative document is difficult. It tears my attention into too many pieces. :+1: +- Had a lot of content that assumed extant knowledge that I didn’t have. This wasn’t in the pre-requisites. + - Do you have examples? + - Yes! The code refinery templates and even just the way of doing that. I was expecting more on "when designing a lesson you should think about these steps" rather than this is how we do it and this is our tool for doing it. I guess I should have read the pre-workshop content better? + - Ok, thank you for your feedback. You are right that we actually had some content that for sure would have been easier to follow for people with background knowledge about a certain topic. + - "If you are in CodeRefinery TTT, you probably know what version control is and why it is important." - extant knowledge, why not just add a sentence or two? + - Please can you update in preparation for the next workshops so that I can decide whether or not they will be right for me? + - Yes, we will think more thoroughly about this and send the info in the next email going out Wed/Thu + - Thank you! +- Lots of the content was relevant to code refinery but not the wider topic (e.g. it was how to design a code refinery lesson and not how to design a lesson as stated in the session title) + - We thought of the content of showing one way of doing things, ie "what we have learned", if you have suggestions on how we could make that more clear on the event page, please let us know :) + - "in a code refinery lesson" in the lesson/workshop description? +- When you have pre-written “thank you for your active participation” it feels fake! + - He, that is true, did not think about that. Thank you for the feedback. I would not have added it if Radovan and Richard would not have provided good feedback from circling the rooms. +- I found it vague and disorganised and difficult to follow. It felt like the instructors were presenting the content for the first time and didn't know what to do next. + - Thank you for your feedback. This is not the first time we have this training, but it is the first time in this constellation/way. The way of teaching may also sometimes make it seem new to instructors. +- I really liked the active exchange with other participants, but I also would have enjoyed a bit more technical content in the presentations. In a sense it felt less like a 'training' and more like a get-together :+1:. + - Thank you for your feedback. We thought the name "workshop" would combine the training and exchange nature of this event. But maybe it didn't do so enough? Do you have suggestions on how to clarify it on the event page? + - Well, the 'train the trainer' title created the anticipation of being trained ;) don't get me wrong, I liked the exchange, but I felt that the training aspect fell a little short. imho the workshop would benefit from a little more (instructional) content that is presented in a more structured way by the instructors (as opposed to 'crowd-sourced knowledge' that is collated in a loose collection of questions, notes and links) + - Other than that, you could add another section on the main page, sth like 'Workshop structure: we aim for a mix of modular presentations and work in small groups. The latter will be done in breakout rooms - be prepared to switch on your camera and have a fruitful exchange with fellow participants!' + - Thank you for the suggestions, will add something like this :tools: + - > Added : https://github.com/coderefinery/train-the-trainer/commit/03308595436e636b3bb37ed9d1f0dee39eeccd0f +- My understanding (so far) of what (unlike the competition) CodeRefinery DOES NOT seek to exemplify - +https://images.ctfassets.net/rxqefefl3t5b/2k45BFtw4sBMlBfjr1OZ90/5c6ecd3628a43b0cdc79815f665e224a/Screenshot_2023-05-02_at_09.35.23.png?fl=progressive&q=80 +- My understanding of what (unlike the competition) today's session of CodeRefinery DID exemplify - Definition of 'Workshop' from the Oxford dictionary of the English language "a period of discussion and practical work on a particular subject, in which a group of people share their knowledge and experience" +- In my experience, even for the most seasoned Programmer coding, by its very nature, is nothing trivial, this being a simple straightforward fact just like there is no such thing as an egg which is a cube. I mean there is a reason why not just about everybody is a poet either. But, other minds have pointed this out without having to first explain why the universe is what it is in a way that could be understood without effort ... https://i.pinimg.com/originals/7b/7e/c4/7b7ec4b91d2cf9d8e1b064678d205467.jpg +- The inclusive environment feels very welcoming. Keep up the good work! + +**Thank you all for your feedback! Highly appreciated!** + +--- + +### Day 2 : Session 2 (20.08.24)- Tools and techniques adopted in CodeRefinery workshops + +#### :calendar: Schedule + +| Time (CEST) | Title | EEST (UTC+3) | BST (UTC+1) | +|---------------|---------------------------------------|---------------|---------------| +| 8.45 - 9.00 | Connecting time | 9.45 - 10.00 | 7.45 - 8.00 | +| 9.00 - 9.15 | Intro and Icebreaker | 10.00 - 10.15 | 8.00 - 8.15 | +| 9.15 - 9.25 | About CodeRefinery workshops | 10.15 - 10.25 | 8.15 - 8.25 | +| 9.25 - 9.55 | Collaborative notes and interaction | 10.25 - 10.55 | 8.25 - 8.55 | +| 9.55 - 10.10 | Break | 10.55 - 11.10 | 8.55 - 9.10 | +| 10.10 - 10.45 | Workshop overview, roles, onboarding | 11.10 - 11.45 | 9.10 - 9.45 | +| 10.45 - 11.05 | Sound | 11.45 - 12.05 | 9.45 - 10.05 | +| 11.05 - 11.20 | Break | 12.05 - 12.20 | 10.05 - 10.20 | +| 11.20 - 11.50 | How to prepare a quality screen-share | 12.20 - 12.50 | 10.20 - 10.50 | +| 11.50 - 12.00 | Outro and feedback | 12.50 - 13.00 | 10.50 - 11.00 | + + +#### :icecream: Icebreaker + +##### Check-in + +Which emoji best describes your current state of mind? [Emoji cheat sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) +- :-) +- https://media.istockphoto.com/id/148421550/vector/bored-emoticon.jpg?s=612x612&w=0&k=20&c=uo5KBTqdJZbBQb_Xldhzuovx5t08fHfGR7dw7TCk90I= +- :saluting_face: +- :sleepy: +- :coffee: +- :umbrella: +- :cocktail: :coffee: +- :seedling: +- :tired_face: +- :sun_with_face: +- 🥴 (:woozy_face: not converted?) +- :coffee: +- :sunflower: :book: +- :satisfied: +- :coffee: +- :coffee: +- 🥱:tired_face: +- :bread: - I am baking bread today so I have been kneading dough while listening! + +##### Introduction in breakoutrooms + +Name / Affiliation / Location + +##### Teaching + +- Do you teach and organize teaching alone or with others? What would you prefer and why? + - Coming together is a beginning; keeping together is progress; working together is success. – Edward Everett Hale + - These days always with others. Alone is easier to prepare but almost always is harder during it. + - Teaching with very diverse partners, it can be challenging to find a common language with people very different than you. + - I teach alone, in the future there will be more collaboration with multiple team members. Both approaches have their pros and cons. + - Both has its own distinct advantages + - Most of my teaching is on my own, as a freelancer its more expensive to work with colleagues than to deliever a course on my own. + - Teaching together, learns from each other, feedbacks to improve + - Not formally taught yet, only given presentations actually . + - collective teaching would benefit the teachers with collaborative curriculumn and experiences sharing. + + +- If applicable, have you seen any challenges when teaching together and how to overcome them? + - It actually requires preparation, + - Is it about teaching or about inspiring ? Discover the answer and get inspired ... + - It's like being in a band: you might be great at improvising and your band-partners might be great at improvising too, but a bit of rehearsing makes even the impro gig much better + - Need to plan before session, difficult if people don't 'plan' in the same way, e.g. with the same time frame. + - Heterogeneity in learners make it impossible to get the same result from everyone. + - In fact, the same applies to teachers :D + - Teaching together requires to have similar opinions on how to teach. I share vews only with ~40% of my colleagues I think. +- No Teaching experience but it is good to give the outline of the lessons beforehand and learning goals. + + +--- + +#### :question: Questions + +##### General / Practicalities + +- What is this document for? + - Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts) +- Will the material be made available? + - Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/ + - Can I share them with a colleague + - Yes please :) + - Can I resuse them in my own teaching? + - Yes please :) +- Will these sessions be recorded? + - No, but the materials (see above) should include everything needed for self-learning. +- Can I get a certificate for this workshop? + - You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended. +- How often will we be talking in breakout rooms? + - We'll have about one breakoutroom session per episode + - BR 1 : The Zoom chat does not work for the breakout room so we should take note of that. No webcam/mic = expect silence. + - Thanks for notifying! This was not intended. Turned the chat back on. + + + + +--- + +#### Episode 1: CodeRefinery + +Materials: https://coderefinery.github.io/train-the-trainer/coderefinery-intro/ + +- (questions continue here) +- Is there the plan to build capacity / be paid to deliever courses? + - We've discussed it but right now we don't have many people who could accept money to do this (and maybe shouldn't, because of their jobs). But, we would encourage others to use our materials as "independents" to deliver paid courses + - One idea we have had is that paid courses could be delivered through the DRA (link below), who we know. Basically, DRA could find instructors and handle the money transfers (If someone wanted a paid course, we could help find someone to do it through DRA or independently) + - :smile: +- Have you come across DRA, https://digital-research.academy/, Heidi Seibold, Joyce Kao who are doing similar work? I can connect you if you like. + - Yes we have been discussing about possible future collaborations and are already sending possible clients their way (we, as a project cannot take money) :+1: + - Excellent! :-D :smile: +- . + +#### Episode 2: Collaborative Notes + +Materials: https://coderefinery.github.io/train-the-trainer/collaborative-notes/ + +- So anyone can type anonymously? + - Yes, as long as you do not log in, you are Guest XXX + - And at least in our hedgedoc case you cannot log in so you will always be anonymous. You can do [name=xxx], to add your name to a comment + +- Test of +1 + - +1 :+1: :+1: + - :-1: a test + +- You are hosting your own version of HedgeDoc, and Hackmd.io is a similar (free) option. What are the limitations of the free hackmd.io? Should each center install their own HedgeDoc instance? + - It **seems** the free version of HackMD has gotten worse lately. It works still well enough with a few people editing at the same time. + +- Have there every been problems with the anonymity and CoC? + - We haven't had any issues so far. + - With a different anonymous tool in a bachelor course, we had issues with anonymous participants (participants were posting slurs and unsafe links). The course organiser decided to stop allowing anonymous tools. + +- Why not google documents? + - Google documents are actually setting a hard limit for simultaneous writing, no more than 100 concucurrent editors. I am unsure if microsoft onedrive word documents would allow more users writing at the same time. + +- What's the most people you have every had on HackMD / Hedgedoc? + - I believe about 200 active participants? + +- What are your thoughts on using the build-in Zoom Q&A? + - We haven't tried this, in part because the way we do streaming now (you'll see in session 4), participants aren't in Zoom so don't have access to that. The doc-format works pretty well though, when we keep it in this limited "write at end" format. + +- How do you see what has changed? e.g. if leave the session at the end, can I come back tomorrow and see X has been added? e.g. a diff for this maybe? + - In the menu up right there is revision, it does show the document and changes at different time step :+1: Thanks! + - We recommend people only write at the bottom (and since we answer things live), so as a first level approximation you find where you were and read below that. Think of it more like chat than a full document. (Yes, we do revise questions at the end) + +- How about flinga boards or similar tools? + - My take is that the simplicity of a simple text document wins over free-form in-person-workshop-like tools. + - There's miro, can be a bit confusing though + +- How does this work with small groups, e.g. 10-15 people? + - Good question: it can be hard if people aren't rigorous about it, people start only using chat/voice. So there seems to be some lower bound in size but we haven't tested this much + - And if the instructors never screenshare it to show what goes on it, then seems to be less used. + - And if there aren't other people to read/answer it during the session (perhaps less likely in a small course), it seems to be less used. + + +:::info +Breakoutrooms until xx:55 + +Exercise/discussion: https://coderefinery.github.io/train-the-trainer/collaborative-notes/#exercise +::: + +- Breakout room 1: + * Use of etherpad for collaborative discussion. + * Use of slido for polling and quizzing. + * Presemo as a slido alternative (https://www.aalto.fi/en/services/presemo-a-fully-web-based-classroom-participation-system) + * Use of text based approach for questions rather than live can be helpful if there is a language barrier issue. + - A good teaching session which had many questions coming spontaneously to the teacher is a non-entity of sorts. If the overall flow of feedback / questions increases it could indicate that the session will not prove to be a helpful experience. A signal that generates noise is, well, noise, if calling a spade a spade signals anything. Note that the 'overall' bit and the 'to the teacher' aspect are important. Both the best and the worst teaching session have two things in common: a teacher, and the fact that NO Materials of any kind are used, ie speech is the only channel of communication via a common language. The only difference is that it is not the same teacher, at least not in the same session at the same time. + + Another less mentioned, but perhaps more relevant indicator of a great session is the simple fact that at the end of the session EVERYONE feels empowered, NOT tired. This is not an easy to quantify thing, but screams out the quality of the experience loud. More often then not, such sessions differ little from each other, apart from in terms of the theme / topic and the participant mix. It ends up being the 'keep your cake and eat it too,' of sorts, not quite the far less amusing post-bombardment devastation scenario in the wake of a take it or leave it go at anything. + + - profanity in collaborative documents where people can add content anonymously could be a problem (happens very rarely, fortunately and somewhat surprisingly) + +- Breakout Room 2: + - Good experiences with Zoom polls + - Handling questions in hybrid setups: all participants (on-site and online) ask questions in written form + - Collaborative notes can be challenging when conducting a course alone (without teaching assistants) :+1: + - Providing a method to ask questions anonymously can make asking easier for shy participants + - Questions can give valuable feedback on how the course is going + - Online collaborative whiteboarding platforms such as Miro + - Large monitors are useful for this not to have to drag a "periscope" around + + + + +- Room 4 + - good experience with whatsapp chat for questions. since most learners have the app already and one thing less to install and set up + - reply to question is a way to handle multiple questions at the same time but it works well for smaller groups + - experience with collaborative docs in in-person workshops: voice questions might "win" over the document + - "seeding" questions may help to not have an empty document + - it can help somebody to start and create a structure which helps others to see and follow + - we discussed the Carpentries sticky notes system (red sticky note: signal tech issues and use for feedback, green sticky note: signal that exercise worked and for positive feedback) + - Nice summary of sticky notes system: https://teachtogether.tech/en/#s:classroom-sticky-notes :+1: + - What is the success rate of in-person workshops after COVID? Discussion: Teachers prefer in person and learners prefer remote or recorded to spool back and relearn. + + +- Room 5 + + - Good experience with Collaborative tools as HackMD and HedgeDoc while teaching with no bad feedback + - When used with smaller groups works best as one-way, like sharing links with students and so on + - Needs to be done as a team, quite difficult if teaching alone + - Most useful when online/hybrid + - Anonymisity is important for transparent feedback and no biasis in classrooms + - Not very collaborative but useful to share history or jupyter notebooks live https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush + - Used Flinga before that seems like Figma and also onsite teaching using sticky notes + - There's miro.com but can be a bit confusing, more for brainstorming than for teaching + - Using quizzes apps like Kahoot is beneficial while teaching to have more engaging students + - + +- Room 6 + - teaching teenagers (in presence) but using shared pad becomes quickly very chaotic, so only usable for short moments when answering very precise questions + - Yeah, I can imagine. For CR we try to keep it in this very limited format (all questions bullet points, only add to the end) and I think that helps. + - using shared notepad for small workshop (5-10 people) to explore common thematic (mainly technical) to keep a shared notes and condense aftwerward (and publish on wiki to archive) + - Difference between teaching in person and online. Some people prefer in-person and sometimes you have no option but to organise it online. + - There are sometimes cultural differences and learners feel shy to ask / question the knowledge of the Teacher, so shared notes are a good way to safely ask questions. + + +Questions continue: + +- Have we demonstrated how we do polls in HedgeDoc? Add your vote by adding an `o` + - yes: oooo *(in session 1)* + - no: + - :smile: + - not sure: o + + +#### Episode 3: One workshop, many perspectives + +Materials: https://coderefinery.github.io/train-the-trainer/overview/ +Next CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/ + + +:::info +#### Exercise until xx:39 +https://coderefinery.github.io/train-the-trainer/overview/#discussion +::: +- Room 1 + - Send pre-workshop email with pre-requisite instructions on what should be set-up beforehand. + - But, also mention that if help is needed for set-up, we will be ready before the session officially starts. + - Discussion on whether we push to work in a pre-ready environment (e.g. Binder, Colab) or in their own environment. + - Lots of help needed both before and after. + - Installations: as much as we can provide ready made environments for the learners, maybe installations will be something that the learners will face sooner or later. Maybe one should teach more about installations? + - My only cherished role in a teaching-learning session is the that of one who is living the moment as if there were no tomorrow. What cuts all ways really is that “By failing to prepare, you are preparing to fail.” ― Benjamin Franklin. A helpful motto: “When one teaches, two learn.” — Robert Heinlein. The best experience cannot be given, it can only be allowed to flow its way, so get out of its way. + + +- Room 2 + - Frequently, a single person fills all the roles for a single or multi-day workshop + - Collaboration with different centers/ universities can be challenging + - Preparing participants: it's essential for the instructor to go through the demos and be sure that they will work (no unpleasant surprises live). This can be extended to advance-prep for participants. + - Best experience is to hear (live or in feedback notes) some positive things directed at you :) + - Fully prepared environments (eg self-hosted JupyterHub) can make preparation for participants easy + + +- Room 3 + - Some students have problems with setuping the environment. Maybe having a step by step instructions could help. But some students don't want to "start" the course before hand. + - Preparing the environemnt before hand ensures everyone is onboard from day 1. The same thing happend in CSC training sessions and another session Peng attended. + + - Had experience in attending as teacher and student in previous workshops + +- Room 4 + - knowing the background of the audience is helpful + - Try and ask in advance of the background of the audience. Do a poll at the start of the workshop. In person one can do it interactive. + - among co-instructors: discuss topics and flow + - if more people are involved, it can help changing roles from time to time to see different perspectives + - preparation is key + - Circulate instructions beforehand + - Do a poll before session: Have you installed (QGIS) successfully? + - Push hard to do this in the welcome email + - communicate clearly to the participants + - +- Room 5 + - We've all taken most roles + - How to prepare in advance? + - Meet and discuss once or twice + - Make a pre-survey to check for interest and background + - Going through the materials + - Checking the toolkit (zoom) + - Agree on the reponsibilities and back-up plans (bit of scenarios planning) + - How to prepare trainings in advance? + - Collect resources and prepare the workshop plan + - Having the material readily available online ans sharing it + - Making a pre-survey + - What was the best workshop experience for you as learner, helper or instructor? What made it great? + - learner + - Engaging and practical workshop with more exercices and follow-up theoretical part explanations + - helper + - When the instructor is well prepared and as helper ther's only typos to fix and interesting questions to answer + - Assist the instructor, coordinate the collaborative notes, and make sure that the time is respected + - instructor + - I have a colleague whom I've ran the same workshop a few times already, goes quite smoothly now and we've made a few changes. Hard to reach that point with new colleagues but getting there + - Students/participants were engaging with the material and many good feedback collected even some of them asked for the next workshop + + +- Room 6 + - What has made a great experience for you as a learner/helper/instructor? + - Common ground between learners & teachers + - + - Motivation + - Teaching is much more enjoyable when the learners want to be there + - I spend a lot of time at the start of a workshop making sure learners feel that the content is possible for them to understand and master + + +Poll: I have joined a CodeRefinery workshop before: (add an `o` for your answer) +- yes (within last 2 years): ooooooo +- yes (longer time ago): oo +- no: oooooooo +- + + +(questions would continue below:) +- What is the motivation / advantages of streaming workshop versus using zoom? + - We'll cover this more in week 4, but roughly: zoom became unmanageable and essentially quiet once things got big. Streaming allowed "one to many" communication with no limit, and collab notes allowed better interaction anyway. By separating the rooms, it was more pleasant to teach. Videos could be released immediately since there was no risk of privacy of participants. There could still be in-person/online small groups who have "watching parties." +- What are the blue red and green font colors here, does it symbolify anything or just a convention HedgeDoc uses? + - Visual separation of formatting, mostly. (It helps to quickly realize you've missed/ mistyped a control Markdown symbol etc.) + - Yeah, it's bascically "code highlighting" for markdown. No special meaning but quite convenient for us. +- Is this next workshop only for team leads or also open for helpers and coordinators? + - You mean the next session of this workshop or the upcoming "CodeRefinery workshop"(this one: https://coderefinery.github.io/2024-09-10-workshop/)? + - The upcoming workshop coordinators are alredy working, but can be joined if you are interested + - As helper roles we currently only have "collaborative notes helper", which is all about helping to answer questions in the collaborative notes + - We do have some co-teaching slots open :) + - If interested: join the discussion in our chat: https://coderefinery.zulipchat.com/#narrow/stream/316508-coderefinery-tools-workshop/topic/Fall.202024.20CodeRefinery.20workshop + +- Can a person have multiple roles in a workshop as a helper and a teacher? + - Yes, many teachers also contribute to the rest of the workshop by answering questions in collaborative notes. :+1: + - Some teachers also host a local classroom in week one and do their teaching in week two of the workshop + - Roles that do not go well together are broadcaster/director/host and instructor (goes well until there is a problem; co-teaching solves that partly) + + +#### Episode 4: Sound +https://coderefinery.github.io/train-the-trainer/sound/ + +- To me, Richard is a bit quieter than the other two :+1: :+1: :+1: + - to elaborate: I think that the audio coming from him is missing some mids + - Do you have any links about this kind of evaluation and adjustment? + +- Do you suggest / recommend a specific headset(s) with mounted microphone? + - in our experience headsets with a microphone will almost always be better than a separate microphone sitting on the desk or in the monitor + - + +- Speakers have different tones of voice and speaking styles, is there a recommendation or experience from CR workshops for how this is adjusted and catered to environemnts for listeners? + - Yeah, people's voices are different and we haven't gone as far as voice training or improving. + +- How to change the volume for speakers? Tried Zoom settings and system settings and didn't help. + - From linux I can use different pulsemixers `pavucontrol`, `pulsemixer` to set the gain to above 100%. I'm not sure the equivalent on other OSs but + +--- + +:::info + +Exercise until xx:10 +https://coderefinery.github.io/train-the-trainer/sound/#exercises +::: + +- room 1 + + - Practically, no typical headset is designed or can capture the technical purity of human voice within its natural environment. But one needs to understand the polar pattern of the (specific) microphone or how much of the signal will be picked up by the microphone from different directions, a sine qua non when it comes to mitigating unwanted sound sources to bleed into the signal. + +For best results, keep the right direction & distance to your (directional) mic. Usually, that’s between 15-30 cm to get get a natural sound. A microphone records everything it can, also silence, so check the headphone output BEFORE adjusting the gain, in some specific cases aim for a dry sound, ie the influence of the room or how audible the room is on the recording ! Finally, adjust the mix between dry and room sound, or change the frequency response in tandem using a compressor to reduce the dynamic range of a signal for a more consistent listening experience = the quietest parts of your signal will appear louder by reducing the loudest parts. + +It is all about one thing and one thing only - love your voice, let people fall in love with the acoustic quality of your charm. So remember: GIGO, it matters! + +- Room 3 + - Had different headsets and we could see the difference (bluetooth low quality) + - How to change the volume? + - It's surprisingly hard to get more control than the basic slider you see in the apps! You need to look. + +- room 4 + - headset is probably better listening experience but they can be uncomfortable to wear during long meeting days :+1: + - Yeah. Luckily only instructors + - Therefore breaks are non-negotiable + - loud keyboard can be an issue + - if one has a silent room that does not echo, it can be ok to teach without headset + - on Linux I am using `pulsemixer` to adjust levels and `pavucontrol` to change outputs/sources + - mic modes on mac + - check default microphone for zoom. + + - room 5 + - Most tricks help tuning yourself but hard to do it as a group. Perhaps doing a short recording. + - Yeah. Some independent recording/playing aronud, but also asking for advice. I would do small group/one-on-one things. + - Background noises cancellation tools or wise choice of quiet environments + - Audio check with colleagues or through the app with the audience saying numbers for example + - Zoom or Teams have sound checks but work different in the app than the browser. They also work different across Operating systems + - Some sound issues might be related to network speed or stability, also to RAM available. Worthwhile to try and control those as well + - Make it welcoming for the audience to give you feedback on the audio and other settings, give reminders + + +#### Episode 5: How to prepare a quality screen-share + +Materials: https://coderefinery.github.io/train-the-trainer/screenshare/ + +- If your Zoom does not support "share portion of screen", sharing a tab and resizing it to portrait for yourself is a possible workaround (this at least works when joining the call from Chromium browser) + - Another workaround is to use an editor/IDE that displays multiple panels in one window and can show a web page, code files and terminal session +10 +- Is 'share a portion of your screen' where you draw a box in Zoom to share a section? + - yes :+1: + + +- When using zsh, one can run something like this in a terminal + ``` + tail -n $NLASTCOMMANDS -f ~/.zsh_history | sed 's/^.............../LAST COMMAND:/g' + ``` + (I place this in a window under the main terminal, I use i3) + +- I am a bit confused on what platform you are putting this code? + - Radovan is using Linux with (I think) the "i3 window manager". It can be quite involved and there is lots of personal customization here. +- When teaching with a custom prompt, is it worth starting with the default (that your learners will see) and explicitly mentioning "I change these things to make it clearer when teaching" + - One should always comment on what may be different. Thing is "default" may look different for many people :+1: + - "I am _not_ going to teach you how to customise your prompt, but here's an online tutorial, be prepared to lose several days of your life..." :laughing: + + +- Now I can't see the last line in the terminal + - Yep, that's a problem. It can be good to keep a buffer on the bottom of the screen. + - If you move your mouse outside the Zoom window, the controls should go away. But still a good note. + - My mouse was on another screen. + - Ok, thanks. + - I think one can also make the zoom bars not auto-hide (then it won't display under), but that is annoying also since it wastes space. + + +- Does anybody still use shellshare? Does it work? + - We in CR haven't used it much but we have seen it. + +- Does the stacking of the screens work on windows? + - Don't know unfortunately + + + +:::info +Exercises (done together) +https://coderefinery.github.io/train-the-trainer/screenshare/#exercises + +Write your cool tips and ideas below. +Stay after xx:00, to +::: + +- To be safe, I have created on my computer an account that I use only for teaching, so I do not need to do any manual set up +- share history or jupyter notebooks live (5-10 secs refresh rate) into a git repo. Share the link with the learners so they can catch up https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush + +--- + +### Wrapup + +- Next session Tuesday August 27 9 CEST: About teaching & cool things we all would like to share +- All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development) +- CodeRefinery community: https://coderefinery.zulipchat.com/ +- Cool gems session: If you want to share something, please edit your registration and fill it in there (link to modify in registration confirmation); or e-mail to support@coderefinery.org +- If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14:00 (Europe/Stockholm time) + + +### Feedback about todays session + +What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session: +- Sound and screen share optimization as well as relevant tools and good practices for online instruction. “While you may be unable to control your users’ mindset, you can anticipate it, and make sure that your user experience caters to it.” - Jonathan Cherki +- Nice opportunity to (re)think about my online teaching setup :+1: :+1: :+1: +- Other ways to display command history :+1: +- Did not know that bluetooth gear had so much latency! :+1: +- A good reminder about headsets with microphones +- Nice and friendly teaching. Thank you! +- Screen share with command history and terminal customisation +- Really useful tips on sound and screen sharing :+1: +- Nice experience share +- very useful and practical tips! +- Easy to follow along and filled with useful tips on sound, video etc. +- + +What one thing would you improve about this session? +- Just digging to find something: I have read some of the things you have talked about here already in some blog posts, so perhaps these sessions are not as shokingly full of new content as I imagined (but actually sharing experiences is something I can't do by reading a blog post) + - Perhaps: could you link some blog posts or other sources for what you have discussed so far? If it makes sense. Not sure. +- Talking about interface optimization approaches, which applies to sound as much as to visuals or any other aspect either for that matter, it might offer a perspective to bear in mind the concept of introducing asymptotic complexity increment. The latter would mean the goal is measuring how fast the effort of engaging, on one or more of the three parallel levels of interaction, must change to reach higher levels of partial certainty on the correctness of the implementation of the method in question, in this case the pedagogical paradigm. For the former, lower is better I guess, or in this case, in the intended sense, slower is faster. Let us consider an abstract example: People liked using the search engine Google (a Google session to put it in a fancy way) in the early days because it was as simple as it could get, a literally featureless entry point with no bells and whistles. That was the level of its visible complexity, or rather Google set a bar as low as it one could have, and then any higher point of VISIBLE complexity that was to be introduced, such a move would only be on the path of an asymptotic curve curving towards the set bar, never reaching it, as far as the entry point is concerned. We still see the same level of complexity when we fire up google and we never feel distracted to start with, except for the rather forgivable nuisance of the GDPR conformity pop-up notice which appears only AFTER the first move has been made, and thankfully it works plain and simple from there on (unless one starts feeling lucky, pun intended). Now, think about Youtube ... the user experience complexity is a totally different matter, the same company today (unfortunately) yet one now has a steadily worsening engagement experience. Good learning sessions tend to be more of the Google search engine experience and a far cry from the current Youtube trend I would opine. Or, to sum it up and keep it sweet and simple, it helps to identify the limits of human-human and human-technology interaction, within the framework of any applicable technology-technology interaction and joy is the result of respecting those limits. Wishful thinking ? +- Bring the cat back! + - I wish it came, but it's been resting all morning! I don't bother it or stage apperances... +- Maybe having a digest/ summary of previous iterations of this session might be interesting. I feel a lot of experiences have been exchanged and a lot of techniques/ tools have been mentioned. Spending some time in compiling this into a selected list and adding it as content to the course itself might be worthwhile. + - Good idea! We will write a blog post about this workshop and will include a summary of all discussions there :) +- Possibly have some command line examples from Windows rather than (just) *nix? I will look at the screenshots after the session. :+1: :+1: + - Also, a thought if you do do breakout sessions with this work, do one for Unix, one for Windows, one for Mac as an option. +- I could not follow the part Radovan showed codes (Radovan is using Linux with (I think) the "i3 window manager".) +- .. + +Any other comments? +- Looking forward to the topics of following sessions. +- Looking forward to the next sessions! +- Thank you! +- Relax, nothing else matters, live a life and have fun ! If you obey all the rules you may end up missing all the fun. 'The best way to predict your future is to create it.' - Abraham Lincoln :+1: + + +### Day 3 : sessiion 3 (27.08.24) - "About teaching and cool things we all would like to share" + +#### :calendar: Schedule + +| Time (CEST) | Title | EEST (UTC+3) | BST (UTC+1) | +|---------------|---------------------------------------|---------------|---------------| +| 8.45 - 9.00 | Connecting time | 9.45 - 10.00 | 7.45 - 8.00 | +| 9.00 - 9.15 | Intro and Icebreaker | 10.00 - 10.15 | 8.00 - 8.15 | +| 9.15 - 9.45 | Computational thinking | 10.15 - 10.45| 8.15 - 8.45 | +| 9.45 - 10.00 | Break | 10.25 - 11.00 | 8.25 - 9.00 | +| 10.00 - 10.30| Teaching philosophies | 11.00 - 11.30 | 9.00 - 9.30 | +| 10.30 - 11.00 | Co-teaching | 11.30 - 12.00 | 9.30 - 10.00 | +| 11.00 - 11.15 | Break | 12.00 - 12.15 | 10.00 - 10.15 | +| 11.15 - 11.50 | Sharing teaching gems (voluntary) | 12.15 - 12.50 | 10.15 - 10.50 | +| 11.50 - 12.00 | Outro and feedback | 12.50 - 13.00 | 10.50 - 11.00 | + + +#### :icecream: Icebreaker + +##### Check-in + +Which emoji best describes your current state of mind? [Emoji cheat sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) +- ... +- :sleeping: +- :coffee:+2 +- :robot: +- Still little sleeppy :) +- 🥴 (:woozy_face: still not converted 🤷‍♂️) +- Our planet could be a cube. It has six sides to it. It must be a cube. A cube it is, this Blue Planet ... just wondering ... +- 🦾 +- :sweat_smile: +- computer says no :-) some network trouble +- running late, and participating from a :train2: + + +##### Introduction in breakoutrooms + +Name / Affiliation / Location + +##### Best classroom experiences + +As a learner or teacher; what was the best workshop/lesson/seminar you have attended? What made the experience great? + +- Room 1 + - First summer HPC streamed workshop (as a teacher). Somehow the first felt the best + - CSC HPC summer workshop + - story telling teaching approach +- Room 2 + - NVIDIA DLI Course on Deep Learning + - very enthusiastic instructor + - intuitive and very accessible way of showing technical details and fostering deeper understanding + - a lot of hands-on material and smaller coding exercises + - Anything as long as its interactive and somehow enjoyable from both teacher and learner sides +- Room 4: + - EPCC MPI Distributed training workshop. + - Lots of hand on coding / experience gained. + - Very interactive instructor who also discussed ideas for more personalised cases of distributed computing. + - Coderefinery RSE course + - relevance of topic to my current work. + - Dynamic / friendly / positive teaching style. + - Modular Code Development; very instructive + - Some CSC courses / LinkedIn learning courses + - up to date materials and topics. + - Good way to merge theory with practicalities without making learner feel bored (Example: Jonathan Reichental) + - Challenging information to learn more and research about the topic + - Trainers are the experts in the field + + +:::success + +##### Episode on teaching gems + +If you want to share or demo something about tools and techniques you have found helpful in your teaching, please add your name/initials and rough topic below for smooth transition. + +> Note: It does not have to be your tool or your idea, this episode is meant to share experiences and discover new things. You also do not need any slides or materials, a story will do fine :) +> Length of the stories will be depending on interest, but be prepared to fit it into 3 min (shortest possible). + +- RD: teaching clock +- RB: [Containerized teaching setup](https://github.com/bast/teaching-setup) + - Isolated home dir is a good idea! +- AVM: [Screenkey for showing keyboard shortcuts](https://www.thregr.org/wavexx/software/screenkey) + +::: + +--- + +### :question: Questions + +#### General / Practicalities + +- What is this document for? + - Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts) +- Will the material be made available? + - Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/ + - Can I share them with a colleague + - Yes please :) + - Can I resuse them in my own teaching? + - Yes please :) +- Will these sessions be recorded? + - No, but the materials (see above) should include everything needed for self-learning. +- Can I get a certificate for this workshop? + - You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended. +- How often will we be talking in breakout rooms? + - We'll have about one breakoutroom session per episode + + +--- + +#### Episode 1 : Computational thinking + +Materials: https://coderefinery.github.io/train-the-trainer/computational-thinking/ (Link to slides in the middle of material) + +##### Questions to audience + +How might breaking down a complex problem into smaller parts change your approach to problem-solving in your current projects? + +- Avoids cognitive overload +- I used to give an example about this in workshops of cutting long tree into pieces from top to avoid that it falls and destroy a house bloc. +- Easier to start on something small +- Each individual part is familiar and can take existing solutions. +- Only focus on the new things +- One can lose oversight of where is supposed to be getting to due to problems with summation of biases introduced during the solving of the parts. +- . + +Can you think of a research project where identifying patterns in your data led to new insights or breakthroughs? +- Multi-targeted drug design where you need to identify both chemical and biological pathways/patterns +- Distilling complex physics problems into simpler 1D statistics is very often done. +- I used to do bioinformatics, pretty much everything in biology is about patterns in strings of charachters (DNA, proteins). Finding those patterns and using them is the way to go +- Pattern recognition DOES NOT lead to new insight, it is new insight which allows for the recognition of a 'pattern', the latter being an allocation of possible bias. +- +- .. + +What challenges do you face when trying to simplify complex concepts in your field, and how do you decide which details to focus on? + +- Absence of a terminology / jargon to describe a new idea. :+1: +- Similar to above, when teaching often students know what they want to achive, but don't have the termonology to express it, so working through what they want is helpful, after teaching them some termonology. +- Whatever is most useful to the learner first? +- I work with researchers in different fields. I don't always fully understand their domain knowledge but I can take the basiscs or generalities and get code that works for them +- A very practical problem is trying to resist going for a coffee in the midst of taking a shot at a complex concept, in the hope that the true details are to be found in the coffee. +- not all information is easy to find or a lot of conflicting information or even sometimes imformation explosion + + +How do you determine the priority of tasks when designing algorithms for your academic projects, and what criteria do you use to ensure that the most critical tasks are addressed first? + +- Working chronologically when going through a problem - start at the beginning. +- What gives the more insight with the least effort can be a nice start +- Talk to colleagues and Subject matter experts to understand various perspective to decide and prioritize. +- Logic will get you from A to B. Imagination will take you everywhere. - Albert Einstein. +- .. + +##### Questions from the audience + +- About the 4 core concepts, is this based on the model of how human brain works and perceives vision / abstract ideas? + - I don't know if it's based on how the brain works, but it's related to creating a framework for solving programming programs that has been extrapolated to solve any other problem as well. + +- Devil's advocate question: cooking (by recipe) actually employs all four principles outlined here and has done so since before the advent of computers. Why then is this concept presented as "computational"? + - Random aside, this is an interesting connection to our "cooking metaphor to HPC" +- Devil's answer to the Devil's advocate: Great question, cooking, as far as the act happens in the Devil's kitchen, does not employ numerical algorithms. The Devil introduced the computer precisely to make man lose apetite for that what is cooked in the Devil's kitchen to be served to all. Only then can the Devil eat the cake and keep it too ... + - Well, an algorithm without numbers is still an algorithm, i.e. a set of rules :) + +- Are there other names for this technique? I may have missed something crucial, but it strikes me as 'logical thinking' in a way. + - Yes, you could also just see it as problem solving. Most people know how to do it and if you've worked with programming, you've probably applied it. It can be the case that it's very obvious to some, but not to others. + +- Any chance we can ge a link to the slides? + - They are in the course material: https://coderefinery.github.io/train-the-trainer/computational-thinking/ :thumbs_up: + + +##### Exercise questions to discuss + +1. Conceptually would the strategies provided by computational thinking help you in completing tasks more efficiently? +- Room 1: + - divide and conquer technique + - We discussed what happens if you *don't* use these, since they are so natural +- Room 2: + - in some cases yes, if the task is not too small + - not sure if more efficiently but it does help at least getting strted + - Computational thinking is an extension of what others have called solutionism: the belief that any given problem can be solved by the application of computation. Whatever the practical or social problem we face, there is an app for it. - James Bridle +- Room 3: + - Helps in starting the task. + - For many it is the normal way to do problem solving. Also in Agile & Scrum methodlogies. +- Room 4: + - Yes, it helped me during my scientific research to manage multiple projects and research publications simultaneously. + - + + +2. Do you think that the effectiveness of computational thinking depends on the person’s personality type? +- Room 1: + - yes, we agree it's quite different. But good vision and motivation this can be effective +- Room 2: + - yes, laying out all the steps necessary to achieve an overall goal can be very daunting; some people are not good at/ comfortable with following fine-grained instructions + - once the problem is broken down, different personalities might choose different ways to tackle the parts + - The degree to which something, that is a result of what one means by 'Computational Thinking,' is successful in producing a desired result, that is success, cannot be a function of personality. +- Room 3: + - Yes. Different people have different ways to communicate. + - Online tools vs pen and paper +- Room 4: + - We are all agree that it depends on the personality type but it could be learned and trained + +3. Would this type of thinking be an option for you to integrate into your current workflow? +- Room 1: + - Yes; we didn't know the name explicitly; but we use it + - It's quite important for +- Room 2: + - I'm already doing it implicitly :smile: :+1: :+1: + - Writing a program is like writing a song, its all about the tune, lyrics are merely the necessary nuisance a coder needs to put up with. The latter can, if so written, result in a lot of noise. +- Room 3: + - Easy if you are working alone. But different team may have their own ways of working (inertia). One way would be then to gradually show the rest of the team its effectiveness. + - https://teamtopologies.com/key-concepts + +- Room 4: + - We are using it in our daily life so it's already an option for us, only the terminologies are a bit new. + + +#### Episode 2 : Teaching philosophies + +Materials: https://coderefinery.github.io/train-the-trainer/teaching-philosophies/ + +Questions to discuss: +- Share your approach to teaching and your teaching philosophy with your group. +- Please share your tricks and solutions in the live document for others. + +Additional ice-breaker questions: +- What is your motivation for taking this training? +- How structured or informal are your own teaching needs? +- What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching? +- What other skills need to be taught, but academic teaching isn’t the right setting? + +#### Breakout Room exercise + +- Room1 + + - Motivation + - For best practices in teaching, learning from each other, collaboration + - Learning applied tech is like an apprecentiship: there is theory, but real learning happens by co-working with others. + - Worse is better: teach what can be used more quickly and it can be improved later + - + - I think there are two bits of teaching - teach the basics and terminology so people know what they want to know, and then teaching how to find out how to do things like Richard said - how to find answers yourself. + - Using Jupyter notebooks - good for learning a technique, but not for learning the basics. + - Possibly command line usage has a branding problem - "programming other programs"? + - the skills we learn in CR training are expected to stay , it is not exam oriented + +- Room 2 + - State objectives clearly and repeat them a few times + - Try to keep it informal, interactive, flexible + - Helps when having practical tasks in mind for the materials taught + - Leave some reasoning to the learner, not always giving full answers + - How to deal with frustration though: try some personal approaches, more clues... + - The mediocre teacher tells. The good teacher explains. The superior teacher demonstrates. The great teacher inspires. — William Arthur Ward + - Teaching kids to count is fine, but teaching them what counts is best. –Bob Talbert + +- Room 4 + - Question 1: What is your motivation for taking this training? + - Currently do instruction, wanting to improve as an instructor and helper when conducting software carpentries. + - Planning to start some side hustles providing online courses and why not joining the CR in the near future + - Question 2: How structured or informal are your own teaching needs? + - More recently, follow software carpentries, but look into what aspects can be tailored to keep to different time slots. + - I used to be more informal in the past, repetetive practice sessions. Would like to be more structured given the teaching tools. + - I've done life-coaching and some teaching but I feel i'm both of them + - Question 3: What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching? + - Smaller size, and more targetted. + - Collaborative tools and targeted audience working with small groups + - Academic probably focuses on an audience with a more focused/narrow background, while this style encompasses a wider audience. + - Academic teaching keeps theory and practical lab sessions very separate, whereas carpentries combine both. + - Question 4: What other skills need to be taught, but academic teaching isn’t the right setting? + - Public speaking, collaborative meeting skills + - Industrial cases and related work skills + + +#### Episode 3: Co-teaching + +Materials: https://coderefinery.github.io/train-the-trainer/co-teaching/ + +- In general: Co-teaching is a beast with at least two personalities each of which + * demand higher preparation requirements + * face remarkable complexity in terms of coteacher coordination + * in the virtual component face shortcomings related to the technical equipment and the failure of the human factor +* Co-teaching requires the framework of co-operative learning. Team teaching does not by default translate into parallel learning, and vice versa. + +- Re: CodeRefinery in-person beginnings -- I agree with the "didn't work so well in-person", I'm not sure if it's that we weren't as ready for it, or that the different characteristics made it not work so much + +- How do the downsides compare to a single instructor monologuing? + - That's a great question! The main difference is that a single instructor can teach himself to be good (i.e. not just boring monologuing) **alone**, while for teams of 2+ to work well, **everyone** needs to be baseline-competent. So the effort to avoid downsides gets reduced if (and only if) all team members share it. + + +:::info + +Exercise/Discussion: https://coderefinery.github.io/train-the-trainer/co-teaching/#exercise + +Questions: +- Have you already tried this or similar model in your teaching? +- Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best? +- Have you tried or seen a different model for two instructors to present? Please share with us how it works. +::: + +- room 1 + - We have tendend to do presenter/interviewer more + - challenges are co-teaching with different personalities +- room 2 + - Main challenge: finding enough personell :smile: + - It's not always possible/feasible to have colleagues co-teaching + - A combination of both, but presenter and interviewer could be difficult to plan an to follow + - Guide and demo-giver with technical / non-technical roles could be nice + - How to plan the guide and demo-giver + - First guide, then demo + - Demo, then guide describes + - Alternative model: main presenter + 'technical expert' + - main presenter introduces concepts from a birdseye view and passes on to the technical expert for additional details, experiences and answers to questions from the audience + - We frequently do a classical division: on person in presenting, one or more are answering questions in the chat; there is rarely any interaction between them however + +* As has been pointed out by Paolo Freire, in general, ‘education is suffering from narration sickness’ ... ‘The outstanding characteristic of this narrative education, then, is the sonority of words, not their transforming power’. Perhaps one approach could be to rephrase the question after having the answer: It is not apriori about the model implemented, it is about whether that what was implemented was judged aposteriori to have succeeded in becoming, or at least could pretend to have done so, the intended context matched model implementation it probably was computed to be. + +- room 4 + - the co-teaching approach does not seem to be widely practiced + - it can be interesting to see "mistakes" which are less likely to happen in solo-teaching? + - co-teaching can be nicer for audience but maybe more stress/anxiety for instructors to prepare? more stress in terms of not knowing all the questions in advance. less stress worrying about forgetting something. + + + +#### Teaching gems + +(scroll up to find the green box "Episode on teaching gems") + +What's your favorite way of teaching? Any nice tools you use? + +Has anyone found a nice online tool to draw? +- I love this tool suite https://excalideck.com/ + - For drawing https://excalidraw.com/ +- I have seen Miro ... +- I think the Code Refineries use something for their graphics that looks a bit 'cartoony' - but I cannot remember what it is called! + - Drawn on remarkable and then coloured and tidied up in Inkscape. :+1: +- I am a big fan of remarkable. I think sharing option is fairly good. Unfortunately bit expensive tool. + - true, for me it was worth it already for the pdf annotation for research papers, cannot read on computer screen +- https://webwhiteboard.com/ +- https://www.youtube.com/watch?v=4-l8MY5kYGc +- Figma and Kahoot are useful as well + +Screenkey: [Screenkey for showing keyboard shortcuts](https://www.thregr.org/wavexx/software/screenkey) +- Is there a Windows version people can recommend? + - I found this list of alternative for windows users like me: https://alternativeto.net/software/screenkey/ :+1: +- I sometimes use the on-screen keyboard already provided by the OS :+1: + +### Wrapup + +- Next session Tuesday September 3rd 9 CEST: About teaching & cool things we all would like to share +- All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development) +- CodeRefinery community: https://coderefinery.zulipchat.com/ +- If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14 CEST + +- Preparations for next week will be sent out by e-mail + +### Feedback about todays session + +What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session: +- The co-teaching lesson and experiences from others +- Discussions were quite good, had a nice group +- Breakout rooms and collaborative tools +- Computational thinking and co-teaching are interesting ideas! I have seen it before, but never knew or even recognized it was a method. +- Thanks for group discussions working with my chat only interaction! :smile: +- .. + +What one thing would you improve about this session? +- Minor point - it would be useful to have the teaching gmes box at the bottom of the document rather than the top - tricky to scroll between! In the end I opened two windows which was easier. + - Thanks, yes agree. Also had that problem, but did not want to move it in between. +- The meaning of teaching "philosophy" wasn't very clear, felt more like teaching "styles" + - Thank you, we will take that into consideration +- Some prepared slides to present for an intro about the topics + - You mean in addition to the materials? To use in the beginning of each session? +- The [*instructor views*](https://coderefinery.github.io/train-the-trainer/teaching-philosophies/#instructor-views) segment could be named as additional material, if it was not meant to be discussed within the course. + - Thank you, we will take that into consideration + +Any other comments? +- Keeping it short and sweet: If at first you don't succeed in teaching, try to explain it like you're talking to a room full of cats. Caveat: In a room full of computational thinkers maybe if you tell students that the brain is a computational device that is forbidden, they might get excited and start using it. + +### Day4: Session 4 (3.09.24) - Streaming and video editing + +#### :calendar: Schedule + Time (CEST) | Title | EEST (UTC+3) | BST (UTC+1) | +|---------------|---------------------------------------|---------------|---------------| +| 8.45 - 9.00 | Connecting time | 9.45 - 10.00 | 7.45 - 8.00 | +| 9.00 - 9.15 | Intro and Icebreaker | 10.00 - 10.15 | 8.00 - 8.15 | +| 9.15 - 10.00 | Why we stream & Behind the scenes | 10.15 - 11.00| 8.15 - 9.00 | +| 10.00 - 10.15 | Break | 11.00 - 11.15 | 9.00 - 9.15 | +| 10.15 - 10.35 | Video Editing | 11.15 - 11.35 | 9.15 - 9.35 | +| 10.35 - 10.55 | Exercise: Video Editing | 11.35 - 11.55 | 9.35 - 9.55 | +| 10.55 - 11.10 | Break | 11.55 - 12.10 | 9.55 - 10.10 | +| 11.10 - 11.30 | Open Broadcaster Software(OBS) introduction | 12.10 - 12.30 | 10.10 - 10.30 | +| 11:30 - 11:50 | OBS setup & what next | 12.30 - 12.50 | 10.30 - 10.50 | +| 11.50 - 12.00 | Outro and feedback | 12.50 - 13.00 | 10.50 - 11.00 | + +#### :icecream: Icebreaker + +##### Check-in + +Which emoji best describes your current state of mind? [Emoji cheat sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) +- :coffee: + +- :runner: +- :tired_face: Tired! +- :nerd_face:![](https://) +- ![](https://notes.coderefinery.org/uploads/58bfdc31-ac86-4172-aef4-b7b4bd762533.png) +- :cloud: :tea: + +##### Introduction in breakoutrooms + +- Name / Affiliation / Location + +What's the most number of people you have taught to? +- 20 at a time, with 1 asleep, 2 fidgiting with some silly device and the rest were... well... staring at their good luck... straight ahead it was of course, right before them. +- ~35 +- ~80 in a lecture in a previous (lecturer) role, 26 in a training course setting +- ~30 +- ~50 in training spaces and more than 100 for public audience talk +- 35 (software carpentry) +- CodeRefinery answer: The biggest ones are maybe 200-300 people. "small" for a stream is ~100 people. + +What's the most number of people you have taught with? +- 5 or so +- 2 or 3 in total +- 3, as in three, none of them smiling. I wish I could figure out why... it was such fun really... +- 7 +- 2 or 3 +- 3 (helpers, not really co-teaching) +- CodeRefinery answer: our biggest workshops are something like 10-20 people helping out in many different roles. + +How can you divide teaching into separate independent tasks? +- By content blocks, having roles like main and assistant... +- Having responsibility for different sections of the course. +- Wow, now thats what we call a question... bravo... indeed, how does one separate sleeping and snoring into separate independent tasks... +- Course, exercices, resources, tools and forms. +- Different people teach different topics +- CodeRefinery answer: the big logical blocks are instructors, in-person and breakout room helpers, and Notes-questions answers. + +What’s the most interesting or useful thing you’ve learned from an online workshop, and how have you applied it/planning to apply in your life or work +- Having breaks every hour or so +- New approach to screensharing, using the 'portrait' approach +- Manage breathing: reduce stress and use silence to let the audience grasp what you're saying +- Well, the most interesting or useful thing I’ve learned from online workshops is how not to conduct a workshop, or at least some elements of the same, and I have applied this understanding by engaging in the global effort to discover more about how not to conduct a workshop, or at least some elements of the same, with the motto: That's one small step for a man, one giant leap for mankind.. + +#### :question: Questions + +#### [Why we stream](https://coderefinery.github.io/train-the-trainer/why-we-stream/) + +- If during streaming there is no interaction between the teacher and the audience, why don't we just record the lectures and stream them? So one can do a better job, perhaps? + - Streaming it making it a "thing" that's a group experience. It feels good to be a part of it, so we hope that encourages people to actually attend. All the mass Q&A is fun, and the audience helps to make it easier to present. Still, this is a good question. + - I really appriciate it being "a thing". If it was just recorded, I would say I would watch it tomorrow, and then I never would. + - But then you can just fake it, and still have all the breakout rooms and collaborative document and so on. I appreciate the value of having a proper "event". + - I think I follow you, but if you pre-recorded the talking bits, then the presentors couldn't change what they do based on the feedback in the shared document. + - true, but I assumed that the teachers were too busy to actually do that. The more (less )division of labor between the teachers and the helpers (or collaborative document editors), the more (less) sense it makes to pre-record - IMHO +- What interaction options do 'streamers' use, e.g. on Twitch/YouTube (not Code Refinary)? + - I'm besides chat and things that happen in chat, I'm not sure. The Notes-doc is definitely unique to us. +- Streaming is a kind of exercise for the movie star type. If you cannot be one, act like one, pretend, fool the listener into thinking you are one, take their brains and emotions under control. And if they don't leave the session with tears of love for learning running down their chubby cheeks you know who to kick for doing a job just that bit worse than it should have been necessary. +- Have you kept track of streming stats? like how many people logged in and stayed troughout, how many interacted? + - Yes please, it would be good to see the stats + - Here is stats [repo](https://github.com/coderefinery/workshop-stats) + - Thanks, I get a 404 error, is it private? + - No, I don't think so. https://github.com/coderefinery/workshop-stats + - Still get 404. Does it work for anyone else? + - Yeah I think it's private. We need to fix this... +- How big is small (10-15), medium (~30-40)? + - I would say below 50 is small. +- Have you considered scaling to more events instead of to a larger audience? I mean, this seems the opposite of scaling, but this kind of content would be more useful the more often is it taught ("I need to learn GIT/Python/* in December!") + - We would, but right now we simply don't have enough time and people to do more small events. But yes, "scheduling conflict" is a big problem - the best we can do right now is written material+videos to follow up on (and hope it's interesting enough) + - [Python for Scientific Computing 5-7/November/2024](https://www.aalto.fi/en/events/python-for-scientific-computing-5-7november2024) + - This was just an example. I mean, if I am a PHD student that needs to start working on a topic on Month X which happens to be inconveniently placed in the year, I will not benefit as much from having a workshop at Month X+3 + - The materials are open and the videos are publically available on YouTube channel + - What's the ratio of people watching videos afterwards vs people attending the event? That ratio can give an idea of the popularity of the two possible approaches. + - The more you scale up the less interactive the course / workshop will need to be. It then becomes a question of priorities, and if teaching is a lower priority then learning than I guess there really should be no prizes for guessing which approach should reign the airwaves. +- I guess outside Europe / Africa, time zones could be a problem? + - yes, that is true + - +- Sorry, I might have missed this: have you been rehearsing and/or doing dry runs? + - With instructors I like to try to do a dry run. I often don't do a live broadcast dry run these days since I'm confidente enough, but when you are just starting, it's a good idea. +- Do you always use Zoom for the 'presenter end' or have you tried other things? Teams? Jitsi? etc.? + - we use mostly zoom + - It was first pioneered using Jitsi. You can probably use others, too. + +- A comment: for deRSE24 we have been using the [GWDG streaming service](https://docs.gwdg.de/doku.php?id=en:services:mobile_working:live_streaming:start) and OBS, it worked quite well (with a 20s delay or so) + - Cool! Yes, there is plenty of livestreaming options. Twitch+our OBS config gives us 2-3s of latency (which is low enough for live Notes interaction). You might be able to tune this if needed. + +#### Behind the stream + +- Does OBS take a lot of RAM or CPU? what are the specs on your machine? + - Richard have a relatively powerful computer with 8 AMD CPUs. + - 4 CPUs are relatively enough for a good OBS setup, most important is a stable internet connection (ideally wired). + - An extra monitor is recommended for the setup + - See the hardware notesrecommendation [here](https://coderefinery.github.io/train-the-trainer/obs/#hardware-requirements) +- Do you do a screenshare from Zoom -> OBS or OBS -> Zoom? + - Instructors share to Zoom, OBS captures Zoom, OBS sends to the world. + - When I am using OBS sfor a single-person presentation recording, I go the other way: OBS captures my desktop/camera, OBS generates the preview window, and then Zoom captures and broadcasts the preview window. + + +#### [Video editing](https://coderefinery.github.io/train-the-trainer/video-editing/) + +##### Poll +- Have you tried video editing? Add an`o` as answer below + - yes: ooooo + - no : + - Video editing makes all the difference. I have never known a way to avoid this sacred of steps, so to speak. In short, no recording can ever be production ready by default in the books of the wiser among the streamers. In fact, during the editing one can considerably refine and improve the learning experience in great ways. But then one would need to invest both time and effort. + +- If `yes` Which are the tools you use? + - Windows Movie Maker / ClipChamp + - (raw stream from Zoom) + - I think it was shotcut - I did only basic trimming + - Kdenlive + - Clipchamp, OpenShot, Sony Vegas + - also ffmpeg from command line to cut beginning and end + +##### Questions +- What is Whisper? + - Open-source model from OpenAI that converts speech to text transcripts. + - this one? https://openai.com/index/whisper/ + - curious if anyone has tried it with languages other than english + - I heard that one of my spanish colleague try it with another software. I don't remember the tool. But with AI bloom there are many licensed tools that can do it with fifferent language + +- What do you use to crop the videos? + - I see now, ffmpeg + +- how to merge multiple parts in one? I asked because you edited only the icebreaker part? + - you can manage it in input part, see ffmpeg-editlist readme. + +- Do you generate custom thumbnails for the video? + - no, because of the time, but its good to have. If we had a volunteer to manage that, then we should! + +- Does anyone recommend any other (GUI) tools that work well? ffmpeg is very new to me! + - if you want a basic trimming and editing , you can use Quicktime player/imovies on mac + - Clipchamp as the Microsoft video editor + - Thanks :smile: + +- How do subtitles get uploaded to YouTube? + - You upload the video and subtitles as part of upload. + - :+1: + +- How does codewhisperer compare against youtube's automatically generated subtitles? + - by experience, whisper was better couple of years ago. We haven't compared it recently + - I guess and advantage is that you can edit whisper subtitles in case something is odd or whatever, probs cannot do that in YouTube + + +#### [Open Broadcaster Software (OBS) introduction](https://coderefinery.github.io/train-the-trainer/obs/) & [setup](https://coderefinery.github.io/train-the-trainer/obs-config/) + +- Are the profiles public? + - Yes, you can see it [here](https://coderefinery.github.io/train-the-trainer/obs-config/#coderefinery-obs-configs) +- Does it work in Linux+Wayland? + - I think everything we do with OBS would. + +### Wrapup +- All workshop materials will stay available (and be put on Zenodo right after the workshop) +- Upcoming Workshops + - [CodeRefinery workshop September 10-12, 17-19, 2024](https://coderefinery.github.io/2024-09-10-workshop/) + - [Build Systems Course and Hackathon](https://www.kth.se/form/build-systems-course-and-hackathon-part-i) + - [Python for Scientific Computing](https://www.aalto.fi/en/events/python-for-scientific-computing-5-7november2024) + +- CodeRefinery community: https://coderefinery.zulipchat.com/ +- If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org +- A summary email will be sent out to all participants + +### Feedback about todays session + +What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session: + +- ffmpeg seems great, will give a try for fun! +- great to see everything in practice! +- Very insightful to see what happens behind the scenes. + +What one thing would you improve about this session? + +- Some more interactivity would've been nice but since most the group preferred demo instead of exercise perhaps it's only a personal opinion +- It would have been good to share the OBS profiles repo beforehand in the setup email - so I could have had it to hand. (https://github.com/coderefinery/obs-config) + - +1 good idea, we should do this next time +- Perhaps a simpler starter OBS setup? + - Good idea... I should have, but basically ran out of time to prepare. + +Any other comments? + +- Cool to see the switch from RSE to trainer to AV guy, impressive! + + + diff --git a/_sources/obs-config.md.txt b/_sources/obs-config.md.txt new file mode 100644 index 0000000..df5e530 --- /dev/null +++ b/_sources/obs-config.md.txt @@ -0,0 +1,93 @@ +(obs-config)= + +# Open Broadcaster Software (OBS) setup + +:::{objectives} +- See how to configure OBS using the pre-made CodeRefinery scene + collections +- Modify the collections to suit your needs. +::: + +:::{instructor-note} +- Teaching: ?? min +- Hands-on: ?? min +- Q&A: ?? min +::: + +:::{See also} +* The previous episode {doc}`obs` +* [OBS theory in CodeRefinery manuals](https://coderefinery.github.io/manuals/obs/) +::: + + +In this lesson, we'll see how to configure OBS from scratch for your +purposes. We'll do this by deleting the instructor's configuration +and trying to recreate it + +This section is short, since it has never been done before: we'll just +give it a short and update the lesson later. + + +## CodeRefinery OBS configs + +- CodeRefinery configs are shared in a repository: + +- These can be imported to pre-configure some things +- There are two types of configs: + - Profiles + - Servers, resolutions, audio, video, etc. + - Scene collections + - The graphical layouts. + + +## Installing the OBS config + +- Clone the git repository. +- Import the profile and scene collections under their respective + menus. + + +## Initial setup + +- Click through each menu and change anything that is needed +- Set the streaming server + +:::{demo} The instructor will go through the setup. + +- Reset configuration: `mv .config/obs-studio/ + .config/obs-studio-old/` +- Import `profiles/TeachingStreamingv3/` +- Import `scenes/TeachingStreamingZoomv3.json` +::: + + + +## Set up the remote control + +- Create a Python environment and install it: `pip install https://github.com/coderefinery/obs-cr/archive/refs/heads/master.zip` + +- Run it: `python obs_cr/control.py localhost:4445 TOKEN + --broadcaster` +- There are more options but let's not cover them yet... and leave + this for a hands-on session. + + +## Setup before each course + +- Re-confirm audio +- Re-confirm each scene +- Test everything +- rkdarst has a [rather long + checklist](https://docs.google.com/spreadsheets/d/1g8Bc_76OPcv1vYWtB54wz6HsXQcb3B1GtQFga4Oanw4/edit?gid=0#gid=0), + but each individual step is short. + + +## Q&A + +We'll answer audience questions. + + +:::{keypoints} +- Most of our configuration has been OBS may seem complicated, but it's a graphical application and most + pieces make sense once you know how it works. +::: diff --git a/_sources/obs.md.txt b/_sources/obs.md.txt new file mode 100644 index 0000000..8db24f4 --- /dev/null +++ b/_sources/obs.md.txt @@ -0,0 +1,74 @@ +(obs)= + +# Open Broadcaster Software (OBS) introduction + +:::{objectives} +- Understand that OBS is a video mixer. +- Understand the basic controls and features of OBS. +::: + +:::{instructor-note} +- Teaching: 15 min +- Q&A 5 min +::: + +:::{See also} +* [OBS theory in CodeRefinery manuals](https://coderefinery.github.io/manuals/obs/) +* The next episode {doc}`obs-config` +::: + +In this episode, you'll get more familiar with the OBS portion of the +streaming setup. You'll see how it's used, but not yet how to +configure it from scratch. You'll learn how to be a "director". + + +## What is OBS? + +- Formally "OBS Studio" +- Most commonly known as a livestreaming application. +- Open source, free. +- Cross-platform, easy to use screencasting and streaming application. +- Real-time video mixer. + + +## OBS user interface + +- We'll click through each view. +- What does each view do? +- Let's click through the buttons. +- Let's see the important config options. + + +## OBS during a course + +- What management is needed. +- The control panel. +- Audio. +- Adjusting windows and so on. + + +## Hardware requirements + +- Reasonably powerful broadcast computer + - CodeRefinerys streaming computer is 8 CPU AMD, 64GB memory + - That is way overkill: a powerful laptop can probably do this. +- Large second monitor for laying out the windows you capture +- Stable internet connection (wired preferable) + - CodeRefinery's broadcast is the slowest purchasable: 100 Mbit down / + 25Mbit up + + +## Q&A + +We'll answer audience questions. + + +## See also + +- The next episode {doc}`obs-config` which is about configuring OBS. + + +:::{keypoints} +- OBS may seem complicated, but it's a graphical application and most + pieces make sense once you know how it works. +::: diff --git a/_sources/overview.md.txt b/_sources/overview.md.txt new file mode 100644 index 0000000..aaa3395 --- /dev/null +++ b/_sources/overview.md.txt @@ -0,0 +1,185 @@ +(workshop-overview)= + +# A workshop seen from different perspectives + +:::{objectives} +- Understand the general structure of CodeRefinery workshops and why it is the way it is +- Get to know the different roles of a workshop and which ones are the most essential ones +- Understand the importance of installation instructions and how they contribute to learners success +- Understand the importance of onboarding and a welcoming community for volunteers in a workshop +::: + +:::{instructor-note} +- Teaching: 20 min +- Exercises: 15 min +- Roles journeys can be shortened to looking only at instructor role. +::: + +:::{note} +This episode focuses on the large scale streamed workshop setup. Some of the features can also be applied to smaller scale workshops though. +::: + +## Discussion + +:::{discussion} +In breakoutrooms: choose one or two questions to talk about your own experiences; summary in collaborative notes: +- What kind of roles have you been in yourself regarding workshops? +- How were you prepared for your role? +- What are the things you would like to know before a workshop? +- How are you preparing your participants for your trainings? +- What was the best workshop experience for you as learner, helper or instructor? What made it great? +::: + +## One workshop - many parts + +```{figure} img/CR_workshop_setup.png +Image showing the different phases of a CodeRefinery workshop described below. Also showing that while there is only two people teaching, many people work behind the scenes. +``` + +### Before the workshop + +- During winter/summer: "Someone" takes the coordinator role for the next workshop +- Coordinator fills other roles: + - Coordinator: collects necessary lesson updates, supports other coordinators + - Registration coordinator: Sets up web page, starts and manages registration + - Instructor coordinator: Finds instructors and onboards them + - Advertising coordinator: Prepares advertizement texts and finds people to distribute them + - Team coordinator: Gathers local organizers/teams + - Bring your own code session coordinator: If available, offer BYOC session after main workshop +- Instructor: Onboarding with (instructor-) coordinator and previous instructor of lesson; update of lesson materials (urgent issues and personal touches) +- Local organizer/Team lead: Group [onboarding](https://coderefinery.github.io/manuals/team-leaders/) ~ week/or two before workshop +- Learner: Gets [installation instructions](https://coderefinery.github.io/installation/), invited to installation help session, workshop info from event page and summary via e-mail +- Collaborative notes manager sets up the notes document + +:::{note} +#### [Onboarding manuals](https://coderefinery.github.io/manuals/team-leaders/) +- **Outline of what will happen during the workshop** +- Discussion of different strategies to handle the exercise sessions +- Lowering the barrier to ask for support by meeting some organizers +- Q&A +::: + +:::{note} +#### [Installation instructions](https://coderefinery.github.io/installation/) +- Instructions for all operating systems +- Goal: Learners leave the workshop and are ready to apply the learned tools and techniques to their own work +- Support session for installation challenges +::: + + + +### During the workshop + +```{figure} img/BYOC.png +Image showing the different ways learners can do the exercises. No matter which way they choose, they always watch the stream and interact with instructors and organizers via collaborative notes. Individual learners do the exercises alone, people in online or local classrooms in addition get to discuss with their peers. +``` + +- Everyone watches stream +- Co-instructors + - Present content + - Answer questions in collaborative notes +- Collaborative notes manager + - Keeps the collaborative notes clean + - Helps answering questions + - Adds sections + - Archives the document after each day +- Learners do exercises individually or in team +- Local organizer / Team lead + - Guides learners through exercises + - Facilitates discussion +- (Registration-) coordinator sends out e-mails to participants after each day (summary + preparation) +- Director/Broadcaster manages the streaming (see session 4) + +### After the workshop + +- Coordinator collects lessons learned based on experience and feedback and turns them into issues +- Coordinator organizes debriefing week after the workshop, where anyone can join to give feedback +- "Someone" sends out post-workshop survey half a year after workshop +- Coordinator organizes "Bring your own code" sessions +- Broadcaster prepares and shares recording (see session 4) + +:::{note} +#### Bring your own code sessions + +We want to support learners to apply what they have learned in the workshop to their own work by offering one/two sessions where they can drop in, and discuss challenges with CodeRefinery instructors and helpers. + +```{figure} img/welcome.png +Image showing a classroom learning about git leading to a discussion between student and teacher to start a welcoming environment for asking for help. +``` +::: + +## This sounds like a lot of people and time investment! + +- Many roles can be combined or adjusted as needed +- Some roles can be taken on by multiple people + +So how many people are needed for this kind of workshop? +- Recommended minimum: 2-3 people +- Optimum: ~ 4-5 people +The more people you involve, the more time goes into coordination work. + +## How did we get to this setup? + +- **Collaborative** in-person workshops since 2016 around the Nordics +- Moved online in 2020 +- Started with "traditional zoom" workshops, breakoutrooms, volunteer helpers +- Thought about scaling and ease of joining -> current setup (More about this in session 4) +- Continuous development + +We also still do smaller scale local workshops, if instructors are available. +**You can offer your own CodeRefinery workshop** by inviting other CodeRefinery instructors. +You can also reuse single lessons and integrate them into your own teaching. + +## Workshop roles and their journeys + +### Individual learner journey + +- Registration +- Installation +- (if appicable: Invited to local meetup) +- Workshop + - Watch stream + - Q&A in notes + - Exercises alone or in team + - Daily feedback +- Debrief/ Feedback session +- Post workshop survey + +### Instructor journey + +- Indicate interest in CodeRefinery chat +- Onboarding +- Lesson material updates +- Teaching +- (if wished: supports answering questions in notes) +- Debrief + +### Team lead / Local host journey + +- Registration +- (if applicable: run own registration) +- Onboarding +- Workshop + - Watch stream + - Facilitate exercises/discussions + - Daily feedback +- Debrief / feedback / survey + +### Other roles + +Director and broadcaster roles will be discussed in Session 4. +For more in-depth descriptions and other roles (host, instructor, registration coordinator, etc), see also our [CodeRefinery manuals](https://coderefinery.github.io/manuals/roles-overview/). + +## Different roles as stepping stones for community involvement + +```{figure} img/steps.png +Image showing a person jumping from step to step following learner, helper, expert helper, co-instructor, co-organizer. +``` +There is no "one way" to get involved. Do what feels right. +Interested in teaching with us? Let us know and we can discuss what is a suitable path **for you**! + +:::{keypoints} +- CodeRefinery workshops are a collaborative effort with many different roles +- Onboarding the different roles is one key aspect of our workshops +- Everyone has their own path +::: diff --git a/_sources/screenshare.md.txt b/_sources/screenshare.md.txt new file mode 100644 index 0000000..cdf552a --- /dev/null +++ b/_sources/screenshare.md.txt @@ -0,0 +1,370 @@ +(screenshare)= + +# How to prepare a quality screen-share + +:::{objectives} +- Discuss the importance of a well planned screen-share. +- Learn how to prepare and how to test your screen-share setup. +- Know about typical pitfalls and habits to avoid. +::: + +:::{instructor-note} +- Discussion: 15 min +- Exercises: 15 min +::: + + +## Share portrait layout instead of sharing entire screen when teaching online + +- Many learners will have a smaller screen than you. +- You should plan for learners with **only one small screen**. +- A learner will **need to focus on both your screen share and their + work**. +- Share a **portrait**/**vertical half of your screen** (840 × 1080 is our standard and your + maximum). +- Zoom provides a "Share a part of screen" that is good for this. + - Our latest streaming setup (day 4) can take the portrait part for + you so you can share landscape. + - Zoom + Linux + Wayland display manager doesn't have "Share a + portion of the screen" + - You can share a single window portrait. + - Or you can start your desktop session in "X11" or "Xorg" legacy + mode. + - Or possibly other workarounds (does anyone know other solutions?) + +:::{figure} screenshare/landscape.png +:width: 80% + +A FullHD 1920x1080 screen shared. Learners have to make this really small if +they want to have something else open. +::: + +:::{figure} screenshare/portrait.png +:width: 45% + +Portrait layout. Allows learners to have something else open in the other half. +::: + +Motivation for portrait layout: +- This makes it easier for you to look at some other notes or to coordinate + with other instructors at the same time + without distracting with too much information. +- This makes it possible for participants to have something else open in the + other screen half: terminal or browser or notebook. + + +### Instructor perspective + +:::{figure} screenshare/instructor.png +:width: 75% + +**I1**: +This is how it can look for the instructor. Zoom is sharing a portion of the left +side, the right side is free for following notes, chat, etc. +::: + + +### Learner perspective + +Here are three examples of how it can look for the learner. + +:::{figure} screenshare/learner-large.png +:width: 75% + +**L1**: +Learner with a large screen, Zoom in dual-monitor mode so that the instructor +pictures are not shown. Screen-share is on the left side, collaborative notes +at bottom left, terminal and web browser on the right. +::: + +:::{figure} screenshare/learner-normal.png +:width: 75% + +**L2**: +A learner with a single large screen (Zoom in "single monitor mode"). +Instructor screen share at right, learner stuff at left. +::: + +:::{figure} screenshare/learner-small.png +:width: 75% + +**L3**: +A learner with a particularly small screen. Instructor screen-share at left, +your windows at right. +::: + + +## Share the history of your commands + +Even if you type slowly it is almost impossible to follow every command. We +all get distracted or want to read up on something or while following a command +fails on the learner laptop while instructor gets no error. + +**Add pauses** and **share the commands that you have typed** so that one can catch up. + +Below are some examples (some more successful than others) of sharing history +of commands. + +:::{figure} screenshare/history-portrait.png +:width: 50% + +**H1**: +A vertical screen layout shared. Note the extra shell history at the top. The +web browser is at the bottom, because the Zoom toolbar can cover the bottom +bit. +::: + +:::{figure} screenshare/history-rsh.png +:width: 75% + +**H2**: +This isn't a screen-share from CodeRefinery, but may be instructive. Note the +horizontal layout and shell history at the bottom right. +::: + +:::{figure} screenshare/history-landscape-dark.png +:width: 75% + +**H3**: +Similar to above, but dark. Includes contents on the right. +::: + +:::{figure} screenshare/history-portrait-light.png +:width: 50% + +**H4**: +Jupyter + terminal, including the ``fish`` shell and the terminal history. +::: + +:::{figure} screenshare/history-portrait-dark.png +:width: 50% + +**H5**: +Lesson + terminal, ``tmux`` plus terminal history and dark background. +::: + +:::{figure} screenshare/portrait.png +:width: 50% + +**H6**: +HPC Kickstart course. Note the colors contrast of the windows and colors of +the prompt and text. The history is smaller and doesn't take up primary +working space. The working directory is in the window title bar. +::: + +:::{figure} https://raw.githubusercontent.com/bast/history-window/main/demo.gif +:width: 80% + +**H7**: +Show command history "picture-in-picture", in the same terminal window. +::: + + +## How to configure history sharing + +You need to find a way to show the recent commands you have entered, so that +learners can see the recent commands. Below are many solutions. Try them out +and see what works for you. + +- [prompt-log](): + It adds a interesting idea that the command you enter is in color and also + provides terminal history before the command returns. + +- **Simple**: The simple way is `PROMPT_COMMAND="history -a"` and then + `tail -f -n0 ~/.bash_history`, but this doesn't capture ssh, + sub-shells, and only shows the command after it is completed. + +- **Better yet still simple**: Many Software Carpentry instructors use + [this script](https://github.com/rgaiacs/swc-shell-split-window), + which sets the prompt, splits the terminal window using tmux and displays command history + in the upper panel. Requirement: [tmux](https://github.com/tmux/tmux/wiki) + +- **Better (bash)**: This prints the output before the command is run, + instead of after. Tail with `tail -f ~/demos.out`. + ``` + BASH_LOG=~/demos.out + bash_log_commands () { + # https://superuser.com/questions/175799 + [ -n "$COMP_LINE" ] && return # do nothing if completing + [[ "$PROMPT_COMMAND" =~ "$BASH_COMMAND" ]] && return # don't cause a preexec for $PROMPT_COMMAND + local this_command=`HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"`; + echo "$this_command" >> "$BASH_LOG" + } + trap 'bash_log_commands' DEBUG + ``` + +- **Better (zsh)**: This works like above, with zsh. Tail with `tail -f + ~/demos.out`. + ``` + preexec() { echo $1 >> ~/demos.out } + ``` + +- **Better (fish)**: This works like above, but for fish. Tail with + `tail -f ~/demos.out`. + ``` + function cmd_log --on-event fish_preexec ; echo "$argv" >> ~/demos.out ; end + ``` + +- **Better (tmuxp)**: This will save some typing. + [TmuxP](https://tmuxp.git-pull.com/) is a Python program (`pip install + tmuxp`) that gives you programmable `tmux` sessions. One configuration that + works (in this case for `fish` shell): + ```yaml + session_name: demo + windows: + - window_name: demo + layout: main-horizontal + options: + main-pane-height: 7 + panes: + - shell_command: + - touch /tmp/demo.history + - tail -f /tmp/demo.history + - shell_command: + - function cmd_log --on-event fish_preexec ; echo "$argv" >> /tmp/demo.history ; end + ``` + +- **Windows PowerShell**: In [Windows Terminal](https://docs.microsoft.com/en-us/windows/terminal/), + a split can be made by pressing `CTRL+SHIFT+=`. Then, in one of the splits, the following + PowerShell command will start tracking the shell history: + ``` + Get-Content (Get-PSReadlineOption).HistorySavePath -Wait + ``` + Unfortunately, this only shows commands after they have been executed. + +- [Tavatar: shell history mirroring teaching tool](https://github.com/Sabryr/Tavatar) can copy recent history to a remote server. + +- [history-window](https://github.com/bast/history-window): Show command + history "picture-in-picture" when teaching command line. Requires Bash. + + +## Font, colors, and prompt + +### Terminal color schemes + +- Dark text on light background, *not* dark theme. Research and our + experience says that dark-text-on-light is better in some cases and + similar in others. +- You might want to make the background light grey, to avoid + over-saturating people's eyes and provide some contrast to the pure + white web browser. (this was an accessibility recommendation when + looking for ideal color schemes) +- Do you have any yellows or reds in your prompt or program outputs? + Adjust colors if possible. + + +### Font size + +- Font should be large (a separate history terminal can have a smaller + font). +- Be prepared to resize the terminal and font as needed. Find out + the keyboard shortcuts to do this since you will need it. + + +### Prompt + +At the beginning of the workshop your goal is to have a shell +**as easy to follow as possible** and **as close to what learners will +see on their screens**: +- Your prompt should be minimal: few distractions, and not take up many + columns of text. +- [prompt-log]() does + this for you. +- The minimum to do is is `export PS1='\$ '`. +- Blank line between entries: `export PS1='\n\$ '`. +- Have a space after the `$` or `%` or whatever prompt character you + use. +- Strongly consider the Bash shell. This is what most new people will + use, and Bash will be less confusing to them. +- Eliminate menu bars and any other decoration that uses valuable + screen space. +- Add colors only if it simplifies the reading of the prompt. + +Later in the workshop or in more advanced lessons: +- Using other shells and being more adventurous is OK - learners will + know what is essential to the terminal and what is extra for your + environment. + +Try to find a good balance between: +- Showing a simple setup and showing a more realistic setup. +- Showing a consistent setup among all instructors and showing a + variety of setups. + + +## Habits we need to un-learn + +- **Do not clear the terminal**. Un-learn CTRL-L or `clear` if possible. + More people will wonder what + just got lost than are helped by seeing a blank screen. Push + ``ENTER`` a few times instead to add some white space. +- **Do not rapidly switch between windows** or navigate quickly between multiple + terminals, browser tabs, etc. This is useful during your own work when nobody + is watching, but it is very hard to follow for learners. +- Avoid using **aliases** or **shortcuts** that are not part of the + standard setup. Learners probably don't have them, and they will fail + if they try to follow your typing. Consider even to rename corresponding + files (`.bashrc`, `.gitconfig`, `.ssh/config`, `.ssh/authorized_keys`, `.conda/*`). +- Be careful about using **tab completion** or **reverse history search** if these + haven't been introduced yet. + + +## Desktop environment and browser + +- Try to remove window title bars if they take up lots of space + without adding value to the learner. +- Can you easily resize your windows for adjusting during teaching? +- Does your web browser have a way to reduce its menu bars and other + decoration size? + - Firefox-based browsers: go to `about:config` and set + `layout.css.devPixelsPerPx` to a value slightly smaller than one, + like `0.75`. Be careful you don't set it too small or large since + it might be hard to recover! When you set it to something smaller + than 1, all window decorations become smaller, and you compensate + by zooming in on the website more (you can set the default zoom to + be greater than 100% to compensate). Overall, you get more + information and less distraction. + + +## How to switch between teaching setup and work setup? + +- Make a dedicated "demos" profile in your terminal emulator, if + relevant. Or use a different terminal emulator just for demos. +- Same idea for the browser: Consider using a different browser profile for + teaching/demos. +- Another idea is to containerize the setup for teaching. + We might demonstrate this during the {ref}`cool-gems` session later. + +--- + +:::{keypoints} +- Share **portrait layout** instead of sharing entire screen +- **Adjust your prompt** to make commands easy to read +- **Readability** and beauty is important: adjust your setup for your audience +- **Share the history** of your commands +- Get set up a **few days in advance** and get feedback from someone else. + Feedback and time to improve is very important to make things clear and accessible. + 10 minutes before the session starts is typically too late. +::: + + +## Exercises + +:::{exercise} Evaluate screen captures (20 min) + +Evaluate screenshots on this page. Discuss the trade-offs of each one. Which +one do you prefer? Which are useful in each situation? + +Please take notes in the collaborative document. +::: + +:::{exercise} Set up your own environment (20 min) + +Set up your screen to teach something. Get some feedback from another learner +or your exercise group. +::: + + +## Other resources + +- +- diff --git a/_sources/session-4-intro.md.txt b/_sources/session-4-intro.md.txt new file mode 100644 index 0000000..15cf32e --- /dev/null +++ b/_sources/session-4-intro.md.txt @@ -0,0 +1,28 @@ +(session-4-intro)= + +# Session 4 intro + +This session covers streaming and technical production. Some +introductory notes: + +* (As of 2024) This is the first and only comprehensive introduction + to our online streaming. +* These practices are new and well-refined internally, but a + *different* kind of refinement is needed to teach and reuse them. +* The lessons have outlines of what to talk about, but it's just an + outline. It is *not* refined, since thees things are *new*. Many + things will have to be figured out as we talk. +* This session is a demo of lots of basics. + * Ask questions - otherwise it will be boring + * If you want to use this in real life: you will need *mentoring + sessions* and active help. Contact us to do that. + + +:::{warning} + +**Audio and video weirdness** + +We are setting up video and audio recording, but also capturing that +for re-sharing it. There may be anomalies as video or audio +feedback. Please be prepared. +::: diff --git a/_sources/sound.md.txt b/_sources/sound.md.txt new file mode 100644 index 0000000..bc4ba16 --- /dev/null +++ b/_sources/sound.md.txt @@ -0,0 +1,170 @@ +(sound)= + +# Sound + +:::{objectives} +- Understand that sound quality is very important +- Evaluate your and others sound quality and know how to improve it +- Test tips and tricks for achieving good sound quality +::: + +:::{instructor-note} +- Teaching: 10 min +- Exercises: 10 min +::: + + + +## The importance of audio + +- Pleasing audio quality makes events much more enjoyable +- Audio is one of the most important things you can control +- Things that can go wrong: + - Too quiet + - Too loud + - Instructors' volumes imbalanced + - Background noise + - Low-quality/breaking up audio hard to hear. + - "Ducking" (first words lower volume, or lower volume other times) + + + +## Tips for good sound quality + +- Have a headset with mounted microphone + - Even if you have a professional external microphone, it doesn't + matter if your room has bad acoustics. + - The close pickup can't be beat with normal tools. + - As long as it's headset mounted, price doesn't seem to matter + *that* much. +- Don't use Bluetooth + - Bluetooth can have too much latency (300-500ms) + - This may seem small but for interactive work, it's a lot + - Use a wired headset, or wireless with a non-Bluetooth USB plug + (like gaming headsets have). These have much lower latency. + - Bluetooth 5 can have much lower latency, but you probably + shouldn't count on that without testing. + - It can also have lower sound quality on some devices due to + bandwidth limitations. +- Once you have a headset, turn input noise cancellation to low + (wherever it might be: headphone, meeting software, etc.). + + + +## Balancing and dynamic adjustment + +- It's important that instructors volumes match. +- An exercise will go over a systematic procedure for matching + volumes. + - Practice so that you can do this quickly. +- May need re-adjusting when instructors swap out or start getting + excited. +- An exercise below will demonstrate our procedure. + + + +## Speak up when there are problems + +- If you notice someone with audio issues, let them know right away + (voice if bad, or chat/notes if less urgent). +- Take the time to fix it as soon as practical. +- Make a culture of *speaking up, helping, and not suffering*. + + + +## Recommendations + +- Procure some reasonable headset. +- Low/medium-priced gaming-type headsets have worked well for us. + - (gaming headsets usually aren't Bluetooth, because gaming needs + low latency.) +- Show this page to your workplace (if you have one) and call a good + headset work equipment. + + + +## Exercises + +:::{exercise} Sound-1: Evaluate sound quality +It's important to be able to discuss with others the quality of their +audio. They can't hear themselves, after all. + +- Within the teams, discuss each person's audio quality and what kind + of setup they have. +- Be respectful and constructive (and realize that people came + prepared to listen, not teach). +- Consider, for example + - Volume + - Clarity + - Background noise + - Noise cancellation artifacts + - "Ducking": first words at lower volume or missing +- Discuss how to bring this up during other courses and meetings. +::: + + +:::{exercise} Sound-2: Adjust volume up and down +In addition to individual quality, it is important that sound is +balanced among all instructors. Have you ever been to a event when +one person is too quiet and they can't make themselves any louder? +And they can't adjust it? + +You should ensure that you have a range of volumes available to you. +You might have to look into several different locations in order to +make the full adjustment (). + +- Go to your sound settings +- One by one, each person + - Adjusts their microphone volume so quiet that they can't be heard. + - Adjusts their microphone volume so that it is extremely loud (this + may require going beyond 100% if possible). +- Basically, make sure you aren't so close to either end that you have + no potential to make an adjustment in that direction. +- Everyone tries to set the volume to something reasonable, in + preparation for the next exercise. + +Once you know where these settings are , you won't be panicked when the +volume is too low or high during a course. +::: + + +:::{exercise} Sound-3: Do a balance check +It's important that instructor audio is balanced (the same volume). +But how can you do this? + +- Pick a leader. +- The leader decides the order ("I am first, then [name-1] and + [name-2]") +- The leader says "one". Everyone else says "one" in the order + specified. +- The leader says "two". Everyone else says "two" in the order. +- The leader asks for opinions on who they think is louder or softer. + If there are more than three people, you can figure it out + yourselves. With less than two, you have to ask someone in the + audience. + +Example: +- Leader: Let's do a sound check. I am first, then AAA and BBB. +- Leader: One +- AAA: One +- BBB: One +- Leader: Two +- AAA: Two +- BBB: Two +- Leader: Three +- AAA: Three +- BBB: Three +- Leader: How did that sound to everyone? +- [Someone else]: Leader and BBB were pretty similar but AAA is a bit + lower. +::: + + + +## Summary + +:::{keypoints} +- Audio quality is important and one of the most notable parts of the + workshop. +- Improving audio isn't hard or expensive, but does require preparation. +::: diff --git a/_sources/streaming-whats-next.md.txt b/_sources/streaming-whats-next.md.txt new file mode 100644 index 0000000..68a62d9 --- /dev/null +++ b/_sources/streaming-whats-next.md.txt @@ -0,0 +1,31 @@ +(streaming-whats-next)= + +# What's next? + +:::{objectives} +- Know next steps if you want to do streaming +::: + +:::{instructor-note} +- Teaching: 5 min +- Q&A 5 min +::: + +What comes next? + +- We talked a lot about theory, and gave demonstrations. +- Hands-on is very different. We recommend working with someone to + put it in practice. +- + + +- Work with someone who can show you the way +- Use it for smaller courses with a backup plan + + +## See also + +:::{keypoints} +- These lessons about streaming have been the theoretical part of +streaming training. +::: diff --git a/_sources/streaming.md.txt b/_sources/streaming.md.txt new file mode 100644 index 0000000..614b847 --- /dev/null +++ b/_sources/streaming.md.txt @@ -0,0 +1,94 @@ +(streaming)= + +# Behind the stream + +:::{objectives} +- Take a first look at the broadcaster's view. +- Get to know what happens "behind the stream" of a workshop +- See what the "broadcaster" sees and what they need to do. +- Not yet: learn details of how to do this. +::: + +:::{instructor-note} +- Teaching: 20 min +- Q&A 10 min +::: + +In this episode, you'll see an end-to-end view of streaming from the +broadcaster's point of view. It's a tour but not an explanation or +tutorial. + + + +## Who does what + +We have certain role definitions: + +- **Broadcaster**: Our term for the person who manages the streaming. +- **Director**: Person who is guiding the instructors to their + sessions, changing the scenes, calling the breaks, etc. + - Could be the same as broadcaster. +- **Instructor**: One who is teaching. They don't have to know + anything else about how streaming works. + +This lesson describes what the Broadcaster/Director sees. + + +## Window layouts + +What does the broadcaster see on their screen? + +- What are the main windows you see? +- What do each of them do? +- Which ones do you need to focus on? +- How do you keep all this straight in your head? + + +## CodeRefinery control panel + +- A custom application that controls scenes +- Based on OBS-websocket (remote control connection for OBS - we'll + learn about this later) +- Can also work remotely, so that you can have a remote director + + +## How scenes are controlled + +What has to be done during a course? + +- How do you start the stream? +- How do you change the view? +- How do you adjust things based on what the instructors share? +- How do you coordinate with the instructors? +- How do you know when to change the view? + + +## Getting it set up + +- How hard was it to figure this out? +- How hard is it to set it up for each new workshop? + + +## What can go wrong + +- What's the worst that has happened? +- What if you need to walk away for a bit? +- Someone broadcasts something unexpectedly + + +## Alternatives + +- Youtube vs Twitch +- Zoom stream directly to YouTube/Twitch +- Direct streaming platform, e.g. streamyard + + +## Q&A + +Q&A from audience + + +:::{keypoints} +- The broadcaster's view shouldn't be so scary. +- There is a lot to manage, but each individual part isn't that hard. +::: diff --git a/_sources/teaching-philosophies.md.txt b/_sources/teaching-philosophies.md.txt new file mode 100644 index 0000000..7609af2 --- /dev/null +++ b/_sources/teaching-philosophies.md.txt @@ -0,0 +1,155 @@ +(teaching-philosophies)= + +# CodeRefinery teaching philosophies + +:::{objectives} +- Get to know the teaching philosophies of CodeRefinery instructors +::: + +:::{instructor-note} +- Teaching: 10 min +- Discussion: 20 min +::: + + +## Introduction + +During this episode we split into breakoutrooms and discuss own teaching philosophies. +Collect your teaching philosophies in the collaborative document. We will be going through +these and the end of the lesson. + +:::{challenge} Ice-breaker in groups (20 minutes) +- Share your approach to teaching and your teaching philosophy with your group. +- Please share your tricks and solutions in the live document for others. + +Additional ice-breaker questions: +- What is your motivation for taking this training? +- How structured or informal are your own teaching needs? +- What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching? +- What other skills need to be taught, but academic teaching isn't the right setting? +::: + + +## Instructor views + +Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops. + +It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us. + +:::{prereq} Video recordings +We have recorded some of the below as videos: +::: + +:::{challenge} Bjørn Lindi +My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this "BLOB" (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the "BLOB", to be able to share it with others. + +In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic. + +When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson. + +Tools that I find useful in preparing a lesson is concept maps and Learner Personas (though I have developed too few of them): +- [Concept Maps](https://teachtogether.tech/#s:memory-concept-maps) +- [Learner Personas](https://teachtogether.tech/#s:process-personas) +::: + +:::{challenge} Radovan Bast +My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos. + +My goal for a lesson is to spark curiosity to try things after the lesson, both +for the novices ("This looks like a useful tool, I want to try using it after +the workshop.") and the more experienced participants ("Aha - I did not know +you could do this. I wonder whether I can make it work with X."). I like to +start lessons with a question because this makes participants look up from +their browsers. + +Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise. + +For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate the +answer. + +I try to avoid jargon and "war stories" from the professional developers' +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid "customer", +"production", also a lot of Agile jargon is hard to relate to. + +Less and clear is better than more and unclear. Simple examples are better than +complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +"simply", "just", "easy". If participants take home one or two points from a +lesson, that's for me success. + +I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don't want to be +surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or slide. +This allows me to skip and distill the essence and not read bullet point by +bullet point. + +I try to never deviate from the script and if I do, be very explicit about it. + +A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel listening to me. + +I very much like the co-teaching approach where the other person helps +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson. +::: + +:::{challenge} Sabry Razick +My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case. +::: + +:::{challenge} Richard Darst +Like many people, I've often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I've realized long ago that my most important lessons weren't +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I've realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds. + +My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I'm often start at the +very basics, because this is what I see missing most often. + +When teaching, I like lots of audience questions and don't mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don't have to know everything perfectly, just show how +you'd approach a problem. +::: + +:::{challenge} Stepas Toliautas +I aim for my learners to understand things (concepts, techniques...), instead of just memorizing them. The phrase I use from time to time when teaching information technology topics (be it hardware or software) is "there is no magic": everything can be explained if necessary. While CodeRefinery also emphasizes usefulness/ immediate applicability of the content, often having the correct notions actually helps to start using them sooner and with less mistakes. + +I try to guide my audience through the presented material with occasional questions related to previous topics and common knowledge -- to help them link the concepts already during the lesson. I'm also fully aware that waiting for someone to answer is quite uncomfortable in-person and doubly so in an online environment, especially if no one uses their cameras :) + +And if I get the question I don't have the answer for (or material to show it) at the moment, in university classes I prepare and come back to it next time. While with one-off workshops there might not be a "next time", open-source material used by CodeRefinery allows to have the same outcome: the latest and greatest version stays available for self-study afterwards. +::: + + +## Summary + +:::{keypoints} +- People have different viewpoints on teaching. +::: diff --git a/_sources/video-editing.md.txt b/_sources/video-editing.md.txt new file mode 100644 index 0000000..b41ee26 --- /dev/null +++ b/_sources/video-editing.md.txt @@ -0,0 +1,468 @@ +(video-editing)= + +# Video editing + +:::{objectives} +- Get to know ways of quick video editing to be able to provide + accessible videos +- Learn how video editing can be distributed and done the same day. +::: + +:::{instructor-note} +- Teaching: 20 min +- Exercises: 20 min +::: + + +Video recordings could be useful for people watching later, +but also are (perhaps more) useful for **immediate review and catching +up after missing a day in a workshop**. For this, they need to be +released immediately, within a few hours of the workshop. +CodeRefinery does this, and you can too. + +Hypothesis: videos must be processed the same evening as they were +recorded, otherwise (it may never happen) or (it's too late to be +useful). To do that, we have to make processing *good enough* (not +perfect) and *fast* and the work *distributeable*. + + + +## Primary articles + +* Video editor role description: + +* ffmpeg-editlist: the primary tool: + + * Example YAML editlists: + + + +## How this relates to streaming + +- If you stream, then the audience *can not* appear in the recorded + videos +- This allows you to release videos *very quickly* if you have the + right tools. +- When you have a large audience, the videos start helping more + (review a missed day, catch up later, review later) +- Thus + - If you would never want videos, there may never be a benefit to + streaming + - If you want videos, it gives motivation to stream. + + +## Summary + +* Basic principle: privacy is more important than any other factor. + If we can't guarantee privacy, we can't release videos at all. + + - Disclaimers such as "if you don't want to appear in a recording, + leave your video off and don't say anything", since a) accidents + happen especially when coming back from breakout rooms. b) it + creates an incentive to not interact or participate in the course. + +* Livestreaming is important here: by separating the instruction from + the audience audio/video, there is no privacy risk in the raw + recording. They could be released or shared unprocessed. + +* Our overall priorities + + 1) No learner (or anyone not staff) video, audio, names, etc. are + present in the recordings. + 2) Good descriptions. + 3) Removing breaks and other dead time. + 4) Splitting videos into useful chunks (e.g. per-episode), perhaps + equal with the next one: + 5) Good Table of Contents information so learners can jump to the + right spots (this also helps with “good description”.) + +* [ffmpeg-editlist](https://github.com/coderefinery/ffmpeg-editlist) + allows us to define an edit in a text file (crowdsourceable on + Github), and then generate videos very quickly. + + +## How we do it + +The full explanation is in the form of the exercises below. As a +summary: + +- Record raw video (if from a stream, audience can't possibly be in + it) +- Run Whisper to get good-enough subtitles. Distribute to someone for + checking and improving. +- Define the editing steps (which segments become which videos and + their descriptions) in a YAML file. +- Run ffmpeg-editlist, which takes combines the previous three steps + into final videos. + + + +## Exercises + +### Exercise A + +These exercises will take you through the whole sequence. + +:::::{exercise} Editing-1: Get your sample video + +Download a sample video: + +* Video (raw): +* Whisper subtitles (of raw video): + +* [Schedule of + workshop](https://scicomp.aalto.fi/training/scip/kickstart-2023/#schedule) + (day 1, 11:35--12:25) - used for making the descriptions. ::::: + + +:::::{exercise} Editing-2: Run Whisper to generate raw subtitles and test video. + +First off, install Whisper and generate the base subtitles, based +on the. Since this is probably too much to expect for a short +lesson, they are provided for you (above), but if you want you can +try using Whisper, or generating the subtitles some other way. + +You can start generating subtitles now, while you do the next +steps, so that they are ready by the time you are ready to apply +the editlist. ffmpeg-editlist can also slice up the subtitles from +the main video to make subtitles for each segment you cut out. + +Whisper is left as an exercise to the reader. + +::::{solution} + +Example Whisper command: + +```console +$ whisper --device cuda --output_format srt --initial_prompt="Welcome to CodeRefinery day four." --lang en --condition_on_previous_text False INPUT.mkv +``` + +An initial prompt like this make Whisper more likely to output +full sentences, instead of a stream of words with no +punctuation. +:::: +::::: + +:::::{exercise} Editing-3: Create the basic editlist.yaml file + +Install +[ffmpeg-editlist](https://github.com/coderefinery/ffmpeg-editlist) and +try to follow its instructions, to create an edit with these features: + +* The input definition. +* Two output sections: the "Intro to the course", and "From data + storage to your science" talks (Remember it said the recording + started at 11:35... look at the schedule for hints on when it + might start!). This should have a start/end timestamp from the + *original* video. + +A basic example: + +```yaml +- input: day1-raw.mkv + +# This is the output from one section. Your result should have two of these sections. +- output: part1.mkv + title: something + description: >- + some long + description of the + segment + editlist: + - start: 10:00 # start timestamp of the section, in *original* video + - end: 20:00 # end timestamp of the section, in the *original* video +``` + +::::{solution} + +This is an excerpt from our [actual editlist file of this +course](https://github.com/AaltoSciComp/video-editlists-asc/blob/master/kickstart-2023.yaml#L16-L53) + +```yaml +- input: day1-obs.mkv + +- output: day1-intro.mkv + title: 1.2 Introduction + description: >- + General introduction to the workshop. + + https://scicomp.aalto.fi/training/kickstart/intro/ + + editlist: + - start: 00:24:10 + - end: 00:37:31 + + +- output: day1-from-data-storage-to-your-science.mkv + title: "1.3 From data storage to your science" + description: >- + Data is how most computational work starts, whether it is + externally collected, simulation code, or generated. And these + days, you can work on data even remotely, and these workflows + aren't obvious. We discuss how data storage choices lead to + computational workflows. + + https://hackmd.io/@AaltoSciComp/SciCompIntro + + editlist: + - start: 00:37:43 + - end: 00:50:05 +``` +:::: +::::: + +:::::{admonition} Discussion: what makes a video easy to edit? +--- +class: discussion +--- + +* Clear speaking and have high audio quality. +* For subtitle generation: Separate sentences cleanly, otherwise it + gets in a "stream of words" instead of "punctuated sentences" + mode. +* Clearly screen-sharing the place you are at, including section + name. +* Clear transitions, "OK, now let's move on to the next lesson, + LESSON-NAME. Going back to the main page, we see it here." +* Clearly indicate where the transitions are +* Hover mouse cursor over the area you are currently talking about. +* Scroll screen when you move on to a new topic. +* Accurate course webpage and sticking to the schedule + +All of these are also good for learners. By editing videos, you +become an advocate for good teaching overall. +::::: + + +:::::{exercise} Editing-4: Run ffmpeg-editlist + +Install ffmpeg-editlist: ``pip install ffmpeg-editlist[srt]`` (you +may want to use a virtual environment, but these are very minimal +dependencies). + +The ``ffmpeg`` command line tool must be available in your +``PATH``. + +::::{solution} + +It can be run with (where ``.`` is the directory containing the +input files): + +```console +$ ffmpeg-editlist editlist.yaml . +``` + +Just running like this is quick and works, but the stream may be +garbled in the first few seconds (because it's missing a key +frame). (A future exercise will go over fixing this. +Basically, add the ``--reencode`` option, which re-encodes the +video (this is **slow**). Don't do it yet. + +Look at the ``.info.txt`` files that come out. +:::: +::::: + + +:::::{exercise} Editing-5: Add more features + +* Several chapter definitions.(re-run and you should see a + ``.info.txt`` file also generated). Video chapter definitions + are timestamps of the *original* video, that get translated to + timestamps of the *output* video. + + ```yaml + + - output: part1.mkv + editlist: + - start: 10:00 + - -: Introduction # <-- New, `-` means "at start time" + - 10:45: Part 1 # <-- New + - 15:00: Part 2 # <-- New + - end: 20:00 + ``` + + Look at the ``.info.txt`` files that come out now. What is new in it? + +* Add in "workshop title", "workshop description", and see the + ``.info.txt`` files that come out now. This is ready for + copy-pasting into a YouTube description (first line is the title, + rest is the description). + + Look at the new ``.info.txt`` files. What is new? + +::::{solution} + +* This course actually didn't have chapters for the first day + sessions, but you can [see chapters for day 2 + here](https://github.com/AaltoSciComp/video-editlists-asc/blob/master/kickstart-2023.yaml#L239-L262), + for example. +* [Example of the workshop description for this + course](https://github.com/AaltoSciComp/video-editlists-asc/blob/master/kickstart-2023.yaml#L1-L13) +* Example info.txt file for the general introduction to the + course. The part after the ``-----`` is the workshop description. + + ``` + 1.2 Introduction - HPC/SciComp Kickstart summer 2023 + + General introduction to the workshop. + + https://scicomp.aalto.fi/training/kickstart/intro/ + + 00:00 Begin introduction <-- Invented for the exercise demo, not real + 03:25 Ways to attend <-- Invented for the exercise demo, not real + 07:12 What if you get lost <-- Invented for the exercise demo, not real + + ----- + + This is part of the Aalto Scientific Computing "Getting + started with Scientific Computing and HPC Kickstart" 2023 + workshop. The videos are available to everyone, but may be + most useful to the people who attended the workshop and want + to review later. + + Playlist: + https://www.youtube.com/playlist?list=PLZLVmS9rf3nMKR2jMglaN4su3ojWtWMVw + + Workshop webpage: + https://scicomp.aalto.fi/training/scip/kickstart-2023/ + + Aalto Scientific Computing: https://scicomp.aalto.fi/ + ``` +:::: +::::: + +:::::{exercise} Editing-6: Subtitles + +Re-run ffmpeg-editlist with the ``--srt`` option (you have to +install it with ``pip install ffmpeg-editlist[srt]`` to pull in the +necessary dependency). Notice how ``.srt`` files come out now. + +Use some subtitle editor to edit the *original* subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use ``subtitle-editor`` on Linux, or find some other +tool. + +What do you learn from editing the subtitles? + +::::{solution} + +```console +$ ffmpeg-editlist --srt editlist.yaml +``` + +There should now be a ``.srt`` file also generated. It +generated by finding the ``.srt`` of the original video, and +cutting it the same way it cuts the video. Look and you see it +aligns with the original. + +This means that someone could have been working on fixing the +Whisper subtitles while someone else was doing the yaml-editing. +:::: +::::: + + +:::::{exercise} Editing-6: Subtitles + +Re-run ffmpeg-editlist with the ``--srt`` option (you have to +install it with ``pip install ffmpeg-editlist[srt]`` to pull in the +necessary dependency). Notice how ``.srt`` files come out now. + +Use some subtitle editor to edit the *original* subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use ``subtitle-editor`` on Linux, or find some other +tool. + +What do you learn from editing the subtitles? +::::: + + +:::::{exercise} Editing-7: Generate the final output file. + +* Run ffmpeg-editlist with the ``--reencode`` option: this + re-encodes the video and makes sure that there is no black point + at the start. + +* If you re-run with ``--check``, it won't output a new video file, + but it *will* re-output the ``.info.txt`` and ``.srt`` files. + This is useful when you adjust descriptions or chapters. +::::: + + +:::::{admonition} Discussion: how to distribute this? +--- +class: discussion +--- + +Create a flowchat of all the parts that need to be done, and which +parts can be done in parallel. Don't forget things that you might +need to do before the workshop starts. + +How hard was this editing? Was it worth it? +::::: + + +### Exercise B + + +This is a more limited (and older) version of the above exercise, +using an synthetic example video. + +:::::{exercise} Use ffmpeg-editlist to edit this sample video + +Prerequisites: ``ffmpeg`` must be installed on your computer +outside of Python. Be able to install ffmpeg-editlist. This is +simple in a Python virtual environment, but if not the only +dependency is ``PyYAML``. + +* Download the sample video: +* Copy a sample editlist YAML +* Modify it to cut out the dead time at the beginning and the end. +* If desired, add a description and table-of-contents to the + video. +* Run ffmpeg-editlist to produce a processed video. + +::::{solution} + +```yaml +- input: sample-video-to-edit.raw.mkv +- output: sample-video-to-edit.processed.mkv + description: > + editlist: + - start: 00:16 + - 00:15: demonstration + - 00:20: discussion + - stop: 00:25 +``` + +```console +$ ffmpeg-editlist editlist.yaml video/ -o video/ +``` + +Along with the processed video, we get +``sample-video-to-edit.processed.mkv.info.txt``:: + +``` +This is a sample video + + +00:00 Demonstration +00:04 Discussion +``` +:::: +::::: + +## See also + +* ffmpeg-editlist demo: +* Full demo of producing videos (everything in these exercises): +* Example YAML editlists: + + + + + +:::{keypoints} +- Video editing is very useful for learning +- Set your time budget and make it good enough in that time +- Reviewing videos improves your teaching, too. +::: diff --git a/_sources/why-we-stream.md.txt b/_sources/why-we-stream.md.txt new file mode 100644 index 0000000..56d5e5e --- /dev/null +++ b/_sources/why-we-stream.md.txt @@ -0,0 +1,100 @@ +(why-we-stream)= + +# Why we stream + +:::{objectives} +- Learn the general history of CodeRefinery streaming. +- Discuss the benefits of streaming and recording +- Discuss the downsides and difficulties +::: + +:::{instructor-note} +- Discussion: 10 min +- Q&A: 5 min +- Exercises: 0 min +::: + + +This is a general discussion of the topics of the day, focused on the +history of why we stream and record, how we got here, and how people +feel about it. We won't focus on how anything is done. + + +## Icebreaker questions + +- What is the most people you have taught for? +- What are the distinct parts of teaching, that can be + separated? (teaching, helping, etc) + + +## What is streaming and recording? + +- Streaming is mass communication: one to many + - Interaction audience→presenters is more limited (but different) +- Using consumer-grade tools, normal people can reach huge audiences + by Twitch/YouTube/etc. +- This isn't actually that hard: people with much less training than + us do it all the time. +- They reach huge audiences and maintain engagement for long events. + +**Recording and rapid video editing is useful even without +streaming.** + + +## History + +- In-person workshops + - 3 × full day, required travel, infrequent, one-shot +- Covid and remote teaching + - Traditional "Zoom" teaching several times +- Mega-CodeRefinery workshop + - 100-person Zoom teaching + - Emphasis on teams +- Research Software Hour + - Livestream free-form discussions on Twitch +- Streamed "HPC Kickstart" courses + + + +## Benefits and disadvantages + +Benefits: +- Larger size gives more (but different) interaction possibility + - "Notes" for async Q&A +- Recording (with no privacy risk) allows instant reviews +- Stream-scale allows for many of the things you have learned about in + days 1-3. + +Disadvantages: +- Requires training for using the tools +- Requires a certain scale to be worth it +- Coordination is much harder for big events + +When would I recommend it? +- No: For small courses +- Questionable: Medium sized courses with no videos +- Yes: When you want the largest audience +- Yes: When you want without registration required +- Yes: When you want good reusability/fast videos + + +## Future prospects (briefly) + +- Streaming probably stays as a CodeRefinery tool +- We *can* scale our courses much larger than they are now. Why don't + we, together with others? +- These tools are useful in other places too + - I've used them to record my own talks to make videos of my + single-person presentations or record conference talks nicer than Zoom. + + +## Q&A + +Q&A from audience + + +:::{keypoints} +- Streaming optimizes a course for different things +- The disadvantages can be compensated for +- There are benefits and disadvantages +::: diff --git a/_sphinx_design_static/design-tabs.js b/_sphinx_design_static/design-tabs.js new file mode 100644 index 0000000..b25bd6a --- /dev/null +++ b/_sphinx_design_static/design-tabs.js @@ -0,0 +1,101 @@ +// @ts-check + +// Extra JS capability for selected tabs to be synced +// The selection is stored in local storage so that it persists across page loads. + +/** + * @type {Record} + */ +let sd_id_to_elements = {}; +const storageKeyPrefix = "sphinx-design-tab-id-"; + +/** + * Create a key for a tab element. + * @param {HTMLElement} el - The tab element. + * @returns {[string, string, string] | null} - The key. + * + */ +function create_key(el) { + let syncId = el.getAttribute("data-sync-id"); + let syncGroup = el.getAttribute("data-sync-group"); + if (!syncId || !syncGroup) return null; + return [syncGroup, syncId, syncGroup + "--" + syncId]; +} + +/** + * Initialize the tab selection. + * + */ +function ready() { + // Find all tabs with sync data + + /** @type {string[]} */ + let groups = []; + + document.querySelectorAll(".sd-tab-label").forEach((label) => { + if (label instanceof HTMLElement) { + let data = create_key(label); + if (data) { + let [group, id, key] = data; + + // add click event listener + // @ts-ignore + label.onclick = onSDLabelClick; + + // store map of key to elements + if (!sd_id_to_elements[key]) { + sd_id_to_elements[key] = []; + } + sd_id_to_elements[key].push(label); + + if (groups.indexOf(group) === -1) { + groups.push(group); + // Check if a specific tab has been selected via URL parameter + const tabParam = new URLSearchParams(window.location.search).get( + group + ); + if (tabParam) { + console.log( + "sphinx-design: Selecting tab id for group '" + + group + + "' from URL parameter: " + + tabParam + ); + window.sessionStorage.setItem(storageKeyPrefix + group, tabParam); + } + } + + // Check is a specific tab has been selected previously + let previousId = window.sessionStorage.getItem( + storageKeyPrefix + group + ); + if (previousId === id) { + // console.log( + // "sphinx-design: Selecting tab from session storage: " + id + // ); + // @ts-ignore + label.previousElementSibling.checked = true; + } + } + } + }); +} + +/** + * Activate other tabs with the same sync id. + * + * @this {HTMLElement} - The element that was clicked. + */ +function onSDLabelClick() { + let data = create_key(this); + if (!data) return; + let [group, id, key] = data; + for (const label of sd_id_to_elements[key]) { + if (label === this) continue; + // @ts-ignore + label.previousElementSibling.checked = true; + } + window.sessionStorage.setItem(storageKeyPrefix + group, id); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/_sphinx_design_static/sphinx-design.min.css b/_sphinx_design_static/sphinx-design.min.css new file mode 100644 index 0000000..860c36d --- /dev/null +++ b/_sphinx_design_static/sphinx-design.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative;font-size:var(--sd-fontsize-dropdown)}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary.sd-summary-title{padding:.5em .6em .5em 1em;font-size:var(--sd-fontsize-dropdown-title);font-weight:var(--sd-fontweight-dropdown-title);user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;list-style:none;display:inline-flex;justify-content:space-between}details.sd-dropdown summary.sd-summary-title::-webkit-details-marker{display:none}details.sd-dropdown summary.sd-summary-title:focus{outline:none}details.sd-dropdown summary.sd-summary-title .sd-summary-icon{margin-right:.6em;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary.sd-summary-title .sd-summary-text{flex-grow:1;line-height:1.5;padding-right:.5rem}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker{pointer-events:none;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker svg{opacity:.6}details.sd-dropdown summary.sd-summary-title:hover .sd-summary-state-marker svg{opacity:1;transform:scale(1.1)}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown .sd-summary-chevron-right{transition:.25s}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-right{transform:rotate(90deg)}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-down{transform:rotate(180deg)}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-bg: rgba(0, 113, 188, 0.2);--sd-color-secondary-bg: rgba(108, 117, 125, 0.2);--sd-color-success-bg: rgba(40, 167, 69, 0.2);--sd-color-info-bg: rgba(23, 162, 184, 0.2);--sd-color-warning-bg: rgba(240, 179, 126, 0.2);--sd-color-danger-bg: rgba(220, 53, 69, 0.2);--sd-color-light-bg: rgba(248, 249, 250, 0.2);--sd-color-muted-bg: rgba(108, 117, 125, 0.2);--sd-color-dark-bg: rgba(33, 37, 41, 0.2);--sd-color-black-bg: rgba(0, 0, 0, 0.2);--sd-color-white-bg: rgba(255, 255, 255, 0.2);--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem;--sd-fontsize-dropdown: inherit;--sd-fontsize-dropdown-title: 1rem;--sd-fontweight-dropdown-title: 700} diff --git a/_static/_sphinx_javascript_frameworks_compat.js b/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 0000000..8141580 --- /dev/null +++ b/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 0000000..f316efc --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/check-solid.svg b/_static/check-solid.svg new file mode 100644 index 0000000..92fad4b --- /dev/null +++ b/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/_static/clipboard.min.js b/_static/clipboard.min.js new file mode 100644 index 0000000..54b3c46 --- /dev/null +++ b/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/_static/copybutton.css b/_static/copybutton.css new file mode 100644 index 0000000..f1916ec --- /dev/null +++ b/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/_static/copybutton.js b/_static/copybutton.js new file mode 100644 index 0000000..2ea7ff3 --- /dev/null +++ b/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/_static/copybutton_funcs.js b/_static/copybutton_funcs.js new file mode 100644 index 0000000..dbe1aaa --- /dev/null +++ b/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/_static/css/badge_only.css b/_static/css/badge_only.css new file mode 100644 index 0000000..c718cee --- /dev/null +++ b/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/_static/css/fonts/Roboto-Slab-Bold.woff b/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/_static/css/fonts/Roboto-Slab-Bold.woff2 b/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/_static/css/fonts/Roboto-Slab-Regular.woff b/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/_static/css/fonts/Roboto-Slab-Regular.woff2 b/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/_static/css/fonts/fontawesome-webfont.eot b/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/_static/css/fonts/fontawesome-webfont.svg b/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_static/css/fonts/fontawesome-webfont.ttf b/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/_static/css/fonts/fontawesome-webfont.woff b/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/_static/css/fonts/fontawesome-webfont.woff2 b/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/_static/css/fonts/lato-bold-italic.woff b/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/_static/css/fonts/lato-bold-italic.woff differ diff --git a/_static/css/fonts/lato-bold-italic.woff2 b/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/_static/css/fonts/lato-bold.woff b/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/_static/css/fonts/lato-bold.woff differ diff --git a/_static/css/fonts/lato-bold.woff2 b/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/_static/css/fonts/lato-bold.woff2 differ diff --git a/_static/css/fonts/lato-normal-italic.woff b/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/_static/css/fonts/lato-normal-italic.woff differ diff --git a/_static/css/fonts/lato-normal-italic.woff2 b/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/_static/css/fonts/lato-normal.woff b/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/_static/css/fonts/lato-normal.woff differ diff --git a/_static/css/fonts/lato-normal.woff2 b/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/_static/css/fonts/lato-normal.woff2 differ diff --git a/_static/css/theme.css b/_static/css/theme.css new file mode 100644 index 0000000..19a446a --- /dev/null +++ b/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/_static/design-tabs.js b/_static/design-tabs.js new file mode 100644 index 0000000..b25bd6a --- /dev/null +++ b/_static/design-tabs.js @@ -0,0 +1,101 @@ +// @ts-check + +// Extra JS capability for selected tabs to be synced +// The selection is stored in local storage so that it persists across page loads. + +/** + * @type {Record} + */ +let sd_id_to_elements = {}; +const storageKeyPrefix = "sphinx-design-tab-id-"; + +/** + * Create a key for a tab element. + * @param {HTMLElement} el - The tab element. + * @returns {[string, string, string] | null} - The key. + * + */ +function create_key(el) { + let syncId = el.getAttribute("data-sync-id"); + let syncGroup = el.getAttribute("data-sync-group"); + if (!syncId || !syncGroup) return null; + return [syncGroup, syncId, syncGroup + "--" + syncId]; +} + +/** + * Initialize the tab selection. + * + */ +function ready() { + // Find all tabs with sync data + + /** @type {string[]} */ + let groups = []; + + document.querySelectorAll(".sd-tab-label").forEach((label) => { + if (label instanceof HTMLElement) { + let data = create_key(label); + if (data) { + let [group, id, key] = data; + + // add click event listener + // @ts-ignore + label.onclick = onSDLabelClick; + + // store map of key to elements + if (!sd_id_to_elements[key]) { + sd_id_to_elements[key] = []; + } + sd_id_to_elements[key].push(label); + + if (groups.indexOf(group) === -1) { + groups.push(group); + // Check if a specific tab has been selected via URL parameter + const tabParam = new URLSearchParams(window.location.search).get( + group + ); + if (tabParam) { + console.log( + "sphinx-design: Selecting tab id for group '" + + group + + "' from URL parameter: " + + tabParam + ); + window.sessionStorage.setItem(storageKeyPrefix + group, tabParam); + } + } + + // Check is a specific tab has been selected previously + let previousId = window.sessionStorage.getItem( + storageKeyPrefix + group + ); + if (previousId === id) { + // console.log( + // "sphinx-design: Selecting tab from session storage: " + id + // ); + // @ts-ignore + label.previousElementSibling.checked = true; + } + } + } + }); +} + +/** + * Activate other tabs with the same sync id. + * + * @this {HTMLElement} - The element that was clicked. + */ +function onSDLabelClick() { + let data = create_key(this); + if (!data) return; + let [group, id, key] = data; + for (const label of sd_id_to_elements[key]) { + if (label === this) continue; + // @ts-ignore + label.previousElementSibling.checked = true; + } + window.sessionStorage.setItem(storageKeyPrefix + group, id); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 0000000..4d67807 --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 0000000..87fc516 --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'dirhtml', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/_static/file.png differ diff --git a/_static/jquery.js b/_static/jquery.js new file mode 100644 index 0000000..c4c6022 --- /dev/null +++ b/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!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(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=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,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).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 w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\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(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.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,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){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 H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.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--)b.attrHandle[n[r]]=t}function pe(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 de(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 d=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")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.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}},b.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[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.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},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),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(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.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},j=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)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(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==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(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?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{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 G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.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("(^|"+M+")"+e+"("+M+"|$)"))&&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:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.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 S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(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").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.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),m(t)&&(t=t.call(e,n,S.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)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.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"===S.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"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.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)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.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?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.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)}}),S.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){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/_static/js/html5shiv.min.js b/_static/js/html5shiv.min.js new file mode 100644 index 0000000..cd1c674 --- /dev/null +++ b/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/_static/js/theme.js b/_static/js/theme.js new file mode 100644 index 0000000..1fddb6e --- /dev/null +++ b/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/_static/minipres.js b/_static/minipres.js new file mode 100644 index 0000000..ad11c87 --- /dev/null +++ b/_static/minipres.js @@ -0,0 +1,223 @@ +// Add goTo method to elements +// http://stackoverflow.com/questions/4801655/how-to-go-to-a-specific-element-on-page +(function($) { + $.fn.goTo = function() { + $('html, body').animate({ + scrollTop: $(this).offset().top //+ 'px' + }, 'fast'); + return this; // for chaining... + } +})(jQuery); + +// NO good way to do this!. Copy a hack from here +// https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript +// https://stackoverflow.com/a/2880929 +var urlParams; +(window.onpopstate = function () { + var match, + pl = /\+/g, // Regex for replacing addition symbol with a space + search = /([^&=]+)=?([^&]*)/g, + decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, + query = window.location.search.substring(1); + urlParams = {}; + while (match = search.exec(query)) + urlParams[decode(match[1])] = decode(match[2]); +})(); + +// Select heading levels +var maxHeading = urlParams['h'] +if (maxHeading === undefined) maxHeading = 2 +var headingLevels = []; +for (h=2 ; h (sections.length-1) ) { + // if we would scroll past bottom, or above top, do nothing + return; + } + + console.log('xxxxxx'); + var targetSection = sections[targetPos]; + console.log(targetSection, typeof(targetSection)); + + // Return targetSection top and height + var secProperties = section_top_and_height(targetSection); + var top = secProperties['top']; + var height = secProperties['height'] + var win_height = window.innerHeight; + //console.info(top, height, win_height) + + var scroll_to = 0; + if (height >= win_height || height == 0) { + scroll_to = top; + } else { + scroll_to = top - (win_height-height)/3.; + } + //console.info(top, height, win_height, scroll_to) + + $('html, body').animate({ + scrollTop: scroll_to //+ 'px' + }, 'fast'); + +} + + +function minipres() { + /* Enable the minipres mode: + - call the hide() function + - set up the scrolling listener + */ + document.addEventListener('keydown', function (event) { + switch(event.which) { + case 37: // left + switch_slide(-1); + event.preventDefault(); + return false; + break; + //case 38: // up + case 39: // right + switch_slide(+1); + event.preventDefault(); + return false; + break; + //case 40: // down + default: + return; // exit this handler for other keys + } + }, true) + + hide() + + // Increase space between sections + //$("div .section").css('margin-bottom', '50%'); + $(sectionSelector).css('margin-top', '50%'); + + // Reduce size/color of other sections + if (hiddenSectionSelector.length > 0) { + var hideNodes = $(hiddenSectionSelector); + console.log(typeof hideNodes, hideNodes); + for (node in hideNodes) { + console.log("a", typeof node, node); + node = hideNodes[node]; // what's right way to iterate values? + console.log("b", typeof node, node); + if (node.parentNode && node.parentNode.className == "section") { + node = node.parentNode; + console.log("c", typeof node, node); + //node.css['transform'] = 'scale(.5)'; + //node.css['transform-origin'] = 'top center'; + $(node).css('color', 'lightgrey'); + //$(node).css('font-size', '20%'); + //$(node).css('visibility', 'collapse'); + //ntahousnatouhasno; + } + } + } +} + +function hide() { + /* Hide all non-essential elements on the page + */ + + // This is for sphinx_rst_theme and readthedocs + $(".wy-nav-side").remove(); + $(".wy-nav-content-wrap").css('margin-left', 0); + $('.rst-versions').remove(); // readthedocs version selector + + // Add other formats here. +} + + +var slideshow = minipres; + +if (window.location.search.match(/[?&](minipres|slideshow|pres)([=&]|$)/) ) { + //minipres() + window.addEventListener("load", minipres); +} else if (window.location.search.match(/[?&](plain)([=&]|$)/) ) { + window.addEventListener("load", hide); +} diff --git a/_static/minus.png b/_static/minus.png new file mode 100644 index 0000000..d96755f Binary files /dev/null and b/_static/minus.png differ diff --git a/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css b/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css new file mode 100644 index 0000000..3356631 --- /dev/null +++ b/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css @@ -0,0 +1,2342 @@ +/* Variables */ +:root { + --mystnb-source-bg-color: #f7f7f7; + --mystnb-stdout-bg-color: #fcfcfc; + --mystnb-stderr-bg-color: #fdd; + --mystnb-traceback-bg-color: #fcfcfc; + --mystnb-source-border-color: #ccc; + --mystnb-source-margin-color: green; + --mystnb-stdout-border-color: #f7f7f7; + --mystnb-stderr-border-color: #f7f7f7; + --mystnb-traceback-border-color: #ffd6d6; + --mystnb-hide-prompt-opacity: 70%; + --mystnb-source-border-radius: .4em; + --mystnb-source-border-width: 1px; +} + +/* Whole cell */ +div.container.cell { + padding-left: 0; + margin-bottom: 1em; +} + +/* Removing all background formatting so we can control at the div level */ +.cell_input div.highlight, +.cell_output pre, +.cell_input pre, +.cell_output .output { + border: none; + box-shadow: none; +} + +.cell_output .output pre, +.cell_input pre { + margin: 0px; +} + +/* Input cells */ +div.cell div.cell_input, +div.cell details.above-input>summary { + padding-left: 0em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + background-color: var(--mystnb-source-bg-color); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; + border-radius: var(--mystnb-source-border-radius); +} + +div.cell_input>div, +div.cell_output div.output>div.highlight { + margin: 0em !important; + border: none !important; +} + +/* All cell outputs */ +.cell_output { + padding-left: 1em; + padding-right: 0em; + margin-top: 1em; +} + +/* Text outputs from cells */ +.cell_output .output.text_plain, +.cell_output .output.traceback, +.cell_output .output.stream, +.cell_output .output.stderr { + margin-top: 1em; + margin-bottom: 0em; + box-shadow: none; +} + +.cell_output .output.text_plain, +.cell_output .output.stream { + background: var(--mystnb-stdout-bg-color); + border: 1px solid var(--mystnb-stdout-border-color); +} + +.cell_output .output.stderr { + background: var(--mystnb-stderr-bg-color); + border: 1px solid var(--mystnb-stderr-border-color); +} + +.cell_output .output.traceback { + background: var(--mystnb-traceback-bg-color); + border: 1px solid var(--mystnb-traceback-border-color); +} + +/* Collapsible cell content */ +div.cell details.above-input div.cell_input { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-top: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; +} + +div.cell div.cell_input.above-output-prompt { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +div.cell details.above-input>summary { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; + padding-left: 1em; + margin-bottom: 0; +} + +div.cell details.above-output>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.below-input>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-top: none; + border-bottom-left-radius: var(--mystnb-source-border-radius); + border-bottom-right-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.hide>summary>span { + opacity: var(--mystnb-hide-prompt-opacity); +} + +div.cell details.hide[open]>summary>span.collapsed { + display: none; +} + +div.cell details.hide:not([open])>summary>span.expanded { + display: none; +} + +@keyframes collapsed-fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} +div.cell details.hide[open]>summary~* { + -moz-animation: collapsed-fade-in 0.3s ease-in-out; + -webkit-animation: collapsed-fade-in 0.3s ease-in-out; + animation: collapsed-fade-in 0.3s ease-in-out; +} + +/* Math align to the left */ +.cell_output .MathJax_Display { + text-align: left !important; +} + +/* Pandas tables. Pulled from the Jupyter / nbsphinx CSS */ +div.cell_output table { + border: none; + border-collapse: collapse; + border-spacing: 0; + color: black; + font-size: 1em; + table-layout: fixed; +} + +div.cell_output thead { + border-bottom: 1px solid black; + vertical-align: bottom; +} + +div.cell_output tr, +div.cell_output th, +div.cell_output td { + text-align: right; + vertical-align: middle; + padding: 0.5em 0.5em; + line-height: normal; + white-space: normal; + max-width: none; + border: none; +} + +div.cell_output th { + font-weight: bold; +} + +div.cell_output tbody tr:nth-child(odd) { + background: #f5f5f5; +} + +div.cell_output tbody tr:hover { + background: rgba(66, 165, 245, 0.2); +} + +/** source code line numbers **/ +span.linenos { + opacity: 0.5; +} + +/* Inline text from `paste` operation */ + +span.pasted-text { + font-weight: bold; +} + +span.pasted-inline img { + max-height: 2em; +} + +tbody span.pasted-inline img { + max-height: none; +} + +/* Font colors for translated ANSI escape sequences +Color values are copied from Jupyter Notebook +https://github.com/jupyter/notebook/blob/52581f8eda9b319eb0390ac77fe5903c38f81e3e/notebook/static/notebook/less/ansicolors.less#L14-L21 +Background colors from +https://nbsphinx.readthedocs.io/en/latest/code-cells.html#ANSI-Colors +*/ +div.highlight .-Color-Bold { + font-weight: bold; +} + +div.highlight .-Color[class*=-Black] { + color: #3E424D +} + +div.highlight .-Color[class*=-Red] { + color: #E75C58 +} + +div.highlight .-Color[class*=-Green] { + color: #00A250 +} + +div.highlight .-Color[class*=-Yellow] { + color: #DDB62B +} + +div.highlight .-Color[class*=-Blue] { + color: #208FFB +} + +div.highlight .-Color[class*=-Magenta] { + color: #D160C4 +} + +div.highlight .-Color[class*=-Cyan] { + color: #60C6C8 +} + +div.highlight .-Color[class*=-White] { + color: #C5C1B4 +} + +div.highlight .-Color[class*=-BGBlack] { + background-color: #3E424D +} + +div.highlight .-Color[class*=-BGRed] { + background-color: #E75C58 +} + +div.highlight .-Color[class*=-BGGreen] { + background-color: #00A250 +} + +div.highlight .-Color[class*=-BGYellow] { + background-color: #DDB62B +} + +div.highlight .-Color[class*=-BGBlue] { + background-color: #208FFB +} + +div.highlight .-Color[class*=-BGMagenta] { + background-color: #D160C4 +} + +div.highlight .-Color[class*=-BGCyan] { + background-color: #60C6C8 +} + +div.highlight .-Color[class*=-BGWhite] { + background-color: #C5C1B4 +} + +/* Font colors for 8-bit ANSI */ + +div.highlight .-Color[class*=-C0] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC0] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C1] { + color: #800000 +} + +div.highlight .-Color[class*=-BGC1] { + background-color: #800000 +} + +div.highlight .-Color[class*=-C2] { + color: #008000 +} + +div.highlight .-Color[class*=-BGC2] { + background-color: #008000 +} + +div.highlight .-Color[class*=-C3] { + color: #808000 +} + +div.highlight .-Color[class*=-BGC3] { + background-color: #808000 +} + +div.highlight .-Color[class*=-C4] { + color: #000080 +} + +div.highlight .-Color[class*=-BGC4] { + background-color: #000080 +} + +div.highlight .-Color[class*=-C5] { + color: #800080 +} + +div.highlight .-Color[class*=-BGC5] { + background-color: #800080 +} + +div.highlight .-Color[class*=-C6] { + color: #008080 +} + +div.highlight .-Color[class*=-BGC6] { + background-color: #008080 +} + +div.highlight .-Color[class*=-C7] { + color: #C0C0C0 +} + +div.highlight .-Color[class*=-BGC7] { + background-color: #C0C0C0 +} + +div.highlight .-Color[class*=-C8] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC8] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C9] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC9] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C10] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC10] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C11] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC11] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C12] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC12] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C13] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC13] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C14] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC14] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C15] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC15] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C16] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC16] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C17] { + color: #00005F +} + +div.highlight .-Color[class*=-BGC17] { + background-color: #00005F +} + +div.highlight .-Color[class*=-C18] { + color: #000087 +} + +div.highlight .-Color[class*=-BGC18] { + background-color: #000087 +} + +div.highlight .-Color[class*=-C19] { + color: #0000AF +} + +div.highlight .-Color[class*=-BGC19] { + background-color: #0000AF +} + +div.highlight .-Color[class*=-C20] { + color: #0000D7 +} + +div.highlight .-Color[class*=-BGC20] { + background-color: #0000D7 +} + +div.highlight .-Color[class*=-C21] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC21] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C22] { + color: #005F00 +} + +div.highlight .-Color[class*=-BGC22] { + background-color: #005F00 +} + +div.highlight .-Color[class*=-C23] { + color: #005F5F +} + +div.highlight .-Color[class*=-BGC23] { + background-color: #005F5F +} + +div.highlight .-Color[class*=-C24] { + color: #005F87 +} + +div.highlight .-Color[class*=-BGC24] { + background-color: #005F87 +} + +div.highlight .-Color[class*=-C25] { + color: #005FAF +} + +div.highlight .-Color[class*=-BGC25] { + background-color: #005FAF +} + +div.highlight .-Color[class*=-C26] { + color: #005FD7 +} + +div.highlight .-Color[class*=-BGC26] { + background-color: #005FD7 +} + +div.highlight .-Color[class*=-C27] { + color: #005FFF +} + +div.highlight .-Color[class*=-BGC27] { + background-color: #005FFF +} + +div.highlight .-Color[class*=-C28] { + color: #008700 +} + +div.highlight .-Color[class*=-BGC28] { + background-color: #008700 +} + +div.highlight .-Color[class*=-C29] { + color: #00875F +} + +div.highlight .-Color[class*=-BGC29] { + background-color: #00875F +} + +div.highlight .-Color[class*=-C30] { + color: #008787 +} + +div.highlight .-Color[class*=-BGC30] { + background-color: #008787 +} + +div.highlight .-Color[class*=-C31] { + color: #0087AF +} + +div.highlight .-Color[class*=-BGC31] { + background-color: #0087AF +} + +div.highlight .-Color[class*=-C32] { + color: #0087D7 +} + +div.highlight .-Color[class*=-BGC32] { + background-color: #0087D7 +} + +div.highlight .-Color[class*=-C33] { + color: #0087FF +} + +div.highlight .-Color[class*=-BGC33] { + background-color: #0087FF +} + +div.highlight .-Color[class*=-C34] { + color: #00AF00 +} + +div.highlight .-Color[class*=-BGC34] { + background-color: #00AF00 +} + +div.highlight .-Color[class*=-C35] { + color: #00AF5F +} + +div.highlight .-Color[class*=-BGC35] { + background-color: #00AF5F +} + +div.highlight .-Color[class*=-C36] { + color: #00AF87 +} + +div.highlight .-Color[class*=-BGC36] { + background-color: #00AF87 +} + +div.highlight .-Color[class*=-C37] { + color: #00AFAF +} + +div.highlight .-Color[class*=-BGC37] { + background-color: #00AFAF +} + +div.highlight .-Color[class*=-C38] { + color: #00AFD7 +} + +div.highlight .-Color[class*=-BGC38] { + background-color: #00AFD7 +} + +div.highlight .-Color[class*=-C39] { + color: #00AFFF +} + +div.highlight .-Color[class*=-BGC39] { + background-color: #00AFFF +} + +div.highlight .-Color[class*=-C40] { + color: #00D700 +} + +div.highlight .-Color[class*=-BGC40] { + background-color: #00D700 +} + +div.highlight .-Color[class*=-C41] { + color: #00D75F +} + +div.highlight .-Color[class*=-BGC41] { + background-color: #00D75F +} + +div.highlight .-Color[class*=-C42] { + color: #00D787 +} + +div.highlight .-Color[class*=-BGC42] { + background-color: #00D787 +} + +div.highlight .-Color[class*=-C43] { + color: #00D7AF +} + +div.highlight .-Color[class*=-BGC43] { + background-color: #00D7AF +} + +div.highlight .-Color[class*=-C44] { + color: #00D7D7 +} + +div.highlight .-Color[class*=-BGC44] { + background-color: #00D7D7 +} + +div.highlight .-Color[class*=-C45] { + color: #00D7FF +} + +div.highlight .-Color[class*=-BGC45] { + background-color: #00D7FF +} + +div.highlight .-Color[class*=-C46] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC46] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C47] { + color: #00FF5F +} + +div.highlight .-Color[class*=-BGC47] { + background-color: #00FF5F +} + +div.highlight .-Color[class*=-C48] { + color: #00FF87 +} + +div.highlight .-Color[class*=-BGC48] { + background-color: #00FF87 +} + +div.highlight .-Color[class*=-C49] { + color: #00FFAF +} + +div.highlight .-Color[class*=-BGC49] { + background-color: #00FFAF +} + +div.highlight .-Color[class*=-C50] { + color: #00FFD7 +} + +div.highlight .-Color[class*=-BGC50] { + background-color: #00FFD7 +} + +div.highlight .-Color[class*=-C51] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC51] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C52] { + color: #5F0000 +} + +div.highlight .-Color[class*=-BGC52] { + background-color: #5F0000 +} + +div.highlight .-Color[class*=-C53] { + color: #5F005F +} + +div.highlight .-Color[class*=-BGC53] { + background-color: #5F005F +} + +div.highlight .-Color[class*=-C54] { + color: #5F0087 +} + +div.highlight .-Color[class*=-BGC54] { + background-color: #5F0087 +} + +div.highlight .-Color[class*=-C55] { + color: #5F00AF +} + +div.highlight .-Color[class*=-BGC55] { + background-color: #5F00AF +} + +div.highlight .-Color[class*=-C56] { + color: #5F00D7 +} + +div.highlight .-Color[class*=-BGC56] { + background-color: #5F00D7 +} + +div.highlight .-Color[class*=-C57] { + color: #5F00FF +} + +div.highlight .-Color[class*=-BGC57] { + background-color: #5F00FF +} + +div.highlight .-Color[class*=-C58] { + color: #5F5F00 +} + +div.highlight .-Color[class*=-BGC58] { + background-color: #5F5F00 +} + +div.highlight .-Color[class*=-C59] { + color: #5F5F5F +} + +div.highlight .-Color[class*=-BGC59] { + background-color: #5F5F5F +} + +div.highlight .-Color[class*=-C60] { + color: #5F5F87 +} + +div.highlight .-Color[class*=-BGC60] { + background-color: #5F5F87 +} + +div.highlight .-Color[class*=-C61] { + color: #5F5FAF +} + +div.highlight .-Color[class*=-BGC61] { + background-color: #5F5FAF +} + +div.highlight .-Color[class*=-C62] { + color: #5F5FD7 +} + +div.highlight .-Color[class*=-BGC62] { + background-color: #5F5FD7 +} + +div.highlight .-Color[class*=-C63] { + color: #5F5FFF +} + +div.highlight .-Color[class*=-BGC63] { + background-color: #5F5FFF +} + +div.highlight .-Color[class*=-C64] { + color: #5F8700 +} + +div.highlight .-Color[class*=-BGC64] { + background-color: #5F8700 +} + +div.highlight .-Color[class*=-C65] { + color: #5F875F +} + +div.highlight .-Color[class*=-BGC65] { + background-color: #5F875F +} + +div.highlight .-Color[class*=-C66] { + color: #5F8787 +} + +div.highlight .-Color[class*=-BGC66] { + background-color: #5F8787 +} + +div.highlight .-Color[class*=-C67] { + color: #5F87AF +} + +div.highlight .-Color[class*=-BGC67] { + background-color: #5F87AF +} + +div.highlight .-Color[class*=-C68] { + color: #5F87D7 +} + +div.highlight .-Color[class*=-BGC68] { + background-color: #5F87D7 +} + +div.highlight .-Color[class*=-C69] { + color: #5F87FF +} + +div.highlight .-Color[class*=-BGC69] { + background-color: #5F87FF +} + +div.highlight .-Color[class*=-C70] { + color: #5FAF00 +} + +div.highlight .-Color[class*=-BGC70] { + background-color: #5FAF00 +} + +div.highlight .-Color[class*=-C71] { + color: #5FAF5F +} + +div.highlight .-Color[class*=-BGC71] { + background-color: #5FAF5F +} + +div.highlight .-Color[class*=-C72] { + color: #5FAF87 +} + +div.highlight .-Color[class*=-BGC72] { + background-color: #5FAF87 +} + +div.highlight .-Color[class*=-C73] { + color: #5FAFAF +} + +div.highlight .-Color[class*=-BGC73] { + background-color: #5FAFAF +} + +div.highlight .-Color[class*=-C74] { + color: #5FAFD7 +} + +div.highlight .-Color[class*=-BGC74] { + background-color: #5FAFD7 +} + +div.highlight .-Color[class*=-C75] { + color: #5FAFFF +} + +div.highlight .-Color[class*=-BGC75] { + background-color: #5FAFFF +} + +div.highlight .-Color[class*=-C76] { + color: #5FD700 +} + +div.highlight .-Color[class*=-BGC76] { + background-color: #5FD700 +} + +div.highlight .-Color[class*=-C77] { + color: #5FD75F +} + +div.highlight .-Color[class*=-BGC77] { + background-color: #5FD75F +} + +div.highlight .-Color[class*=-C78] { + color: #5FD787 +} + +div.highlight .-Color[class*=-BGC78] { + background-color: #5FD787 +} + +div.highlight .-Color[class*=-C79] { + color: #5FD7AF +} + +div.highlight .-Color[class*=-BGC79] { + background-color: #5FD7AF +} + +div.highlight .-Color[class*=-C80] { + color: #5FD7D7 +} + +div.highlight .-Color[class*=-BGC80] { + background-color: #5FD7D7 +} + +div.highlight .-Color[class*=-C81] { + color: #5FD7FF +} + +div.highlight .-Color[class*=-BGC81] { + background-color: #5FD7FF +} + +div.highlight .-Color[class*=-C82] { + color: #5FFF00 +} + +div.highlight .-Color[class*=-BGC82] { + background-color: #5FFF00 +} + +div.highlight .-Color[class*=-C83] { + color: #5FFF5F +} + +div.highlight .-Color[class*=-BGC83] { + background-color: #5FFF5F +} + +div.highlight .-Color[class*=-C84] { + color: #5FFF87 +} + +div.highlight .-Color[class*=-BGC84] { + background-color: #5FFF87 +} + +div.highlight .-Color[class*=-C85] { + color: #5FFFAF +} + +div.highlight .-Color[class*=-BGC85] { + background-color: #5FFFAF +} + +div.highlight .-Color[class*=-C86] { + color: #5FFFD7 +} + +div.highlight .-Color[class*=-BGC86] { + background-color: #5FFFD7 +} + +div.highlight .-Color[class*=-C87] { + color: #5FFFFF +} + +div.highlight .-Color[class*=-BGC87] { + background-color: #5FFFFF +} + +div.highlight .-Color[class*=-C88] { + color: #870000 +} + +div.highlight .-Color[class*=-BGC88] { + background-color: #870000 +} + +div.highlight .-Color[class*=-C89] { + color: #87005F +} + +div.highlight .-Color[class*=-BGC89] { + background-color: #87005F +} + +div.highlight .-Color[class*=-C90] { + color: #870087 +} + +div.highlight .-Color[class*=-BGC90] { + background-color: #870087 +} + +div.highlight .-Color[class*=-C91] { + color: #8700AF +} + +div.highlight .-Color[class*=-BGC91] { + background-color: #8700AF +} + +div.highlight .-Color[class*=-C92] { + color: #8700D7 +} + +div.highlight .-Color[class*=-BGC92] { + background-color: #8700D7 +} + +div.highlight .-Color[class*=-C93] { + color: #8700FF +} + +div.highlight .-Color[class*=-BGC93] { + background-color: #8700FF +} + +div.highlight .-Color[class*=-C94] { + color: #875F00 +} + +div.highlight .-Color[class*=-BGC94] { + background-color: #875F00 +} + +div.highlight .-Color[class*=-C95] { + color: #875F5F +} + +div.highlight .-Color[class*=-BGC95] { + background-color: #875F5F +} + +div.highlight .-Color[class*=-C96] { + color: #875F87 +} + +div.highlight .-Color[class*=-BGC96] { + background-color: #875F87 +} + +div.highlight .-Color[class*=-C97] { + color: #875FAF +} + +div.highlight .-Color[class*=-BGC97] { + background-color: #875FAF +} + +div.highlight .-Color[class*=-C98] { + color: #875FD7 +} + +div.highlight .-Color[class*=-BGC98] { + background-color: #875FD7 +} + +div.highlight .-Color[class*=-C99] { + color: #875FFF +} + +div.highlight .-Color[class*=-BGC99] { + background-color: #875FFF +} + +div.highlight .-Color[class*=-C100] { + color: #878700 +} + +div.highlight .-Color[class*=-BGC100] { + background-color: #878700 +} + +div.highlight .-Color[class*=-C101] { + color: #87875F +} + +div.highlight .-Color[class*=-BGC101] { + background-color: #87875F +} + +div.highlight .-Color[class*=-C102] { + color: #878787 +} + +div.highlight .-Color[class*=-BGC102] { + background-color: #878787 +} + +div.highlight .-Color[class*=-C103] { + color: #8787AF +} + +div.highlight .-Color[class*=-BGC103] { + background-color: #8787AF +} + +div.highlight .-Color[class*=-C104] { + color: #8787D7 +} + +div.highlight .-Color[class*=-BGC104] { + background-color: #8787D7 +} + +div.highlight .-Color[class*=-C105] { + color: #8787FF +} + +div.highlight .-Color[class*=-BGC105] { + background-color: #8787FF +} + +div.highlight .-Color[class*=-C106] { + color: #87AF00 +} + +div.highlight .-Color[class*=-BGC106] { + background-color: #87AF00 +} + +div.highlight .-Color[class*=-C107] { + color: #87AF5F +} + +div.highlight .-Color[class*=-BGC107] { + background-color: #87AF5F +} + +div.highlight .-Color[class*=-C108] { + color: #87AF87 +} + +div.highlight .-Color[class*=-BGC108] { + background-color: #87AF87 +} + +div.highlight .-Color[class*=-C109] { + color: #87AFAF +} + +div.highlight .-Color[class*=-BGC109] { + background-color: #87AFAF +} + +div.highlight .-Color[class*=-C110] { + color: #87AFD7 +} + +div.highlight .-Color[class*=-BGC110] { + background-color: #87AFD7 +} + +div.highlight .-Color[class*=-C111] { + color: #87AFFF +} + +div.highlight .-Color[class*=-BGC111] { + background-color: #87AFFF +} + +div.highlight .-Color[class*=-C112] { + color: #87D700 +} + +div.highlight .-Color[class*=-BGC112] { + background-color: #87D700 +} + +div.highlight .-Color[class*=-C113] { + color: #87D75F +} + +div.highlight .-Color[class*=-BGC113] { + background-color: #87D75F +} + +div.highlight .-Color[class*=-C114] { + color: #87D787 +} + +div.highlight .-Color[class*=-BGC114] { + background-color: #87D787 +} + +div.highlight .-Color[class*=-C115] { + color: #87D7AF +} + +div.highlight .-Color[class*=-BGC115] { + background-color: #87D7AF +} + +div.highlight .-Color[class*=-C116] { + color: #87D7D7 +} + +div.highlight .-Color[class*=-BGC116] { + background-color: #87D7D7 +} + +div.highlight .-Color[class*=-C117] { + color: #87D7FF +} + +div.highlight .-Color[class*=-BGC117] { + background-color: #87D7FF +} + +div.highlight .-Color[class*=-C118] { + color: #87FF00 +} + +div.highlight .-Color[class*=-BGC118] { + background-color: #87FF00 +} + +div.highlight .-Color[class*=-C119] { + color: #87FF5F +} + +div.highlight .-Color[class*=-BGC119] { + background-color: #87FF5F +} + +div.highlight .-Color[class*=-C120] { + color: #87FF87 +} + +div.highlight .-Color[class*=-BGC120] { + background-color: #87FF87 +} + +div.highlight .-Color[class*=-C121] { + color: #87FFAF +} + +div.highlight .-Color[class*=-BGC121] { + background-color: #87FFAF +} + +div.highlight .-Color[class*=-C122] { + color: #87FFD7 +} + +div.highlight .-Color[class*=-BGC122] { + background-color: #87FFD7 +} + +div.highlight .-Color[class*=-C123] { + color: #87FFFF +} + +div.highlight .-Color[class*=-BGC123] { + background-color: #87FFFF +} + +div.highlight .-Color[class*=-C124] { + color: #AF0000 +} + +div.highlight .-Color[class*=-BGC124] { + background-color: #AF0000 +} + +div.highlight .-Color[class*=-C125] { + color: #AF005F +} + +div.highlight .-Color[class*=-BGC125] { + background-color: #AF005F +} + +div.highlight .-Color[class*=-C126] { + color: #AF0087 +} + +div.highlight .-Color[class*=-BGC126] { + background-color: #AF0087 +} + +div.highlight .-Color[class*=-C127] { + color: #AF00AF +} + +div.highlight .-Color[class*=-BGC127] { + background-color: #AF00AF +} + +div.highlight .-Color[class*=-C128] { + color: #AF00D7 +} + +div.highlight .-Color[class*=-BGC128] { + background-color: #AF00D7 +} + +div.highlight .-Color[class*=-C129] { + color: #AF00FF +} + +div.highlight .-Color[class*=-BGC129] { + background-color: #AF00FF +} + +div.highlight .-Color[class*=-C130] { + color: #AF5F00 +} + +div.highlight .-Color[class*=-BGC130] { + background-color: #AF5F00 +} + +div.highlight .-Color[class*=-C131] { + color: #AF5F5F +} + +div.highlight .-Color[class*=-BGC131] { + background-color: #AF5F5F +} + +div.highlight .-Color[class*=-C132] { + color: #AF5F87 +} + +div.highlight .-Color[class*=-BGC132] { + background-color: #AF5F87 +} + +div.highlight .-Color[class*=-C133] { + color: #AF5FAF +} + +div.highlight .-Color[class*=-BGC133] { + background-color: #AF5FAF +} + +div.highlight .-Color[class*=-C134] { + color: #AF5FD7 +} + +div.highlight .-Color[class*=-BGC134] { + background-color: #AF5FD7 +} + +div.highlight .-Color[class*=-C135] { + color: #AF5FFF +} + +div.highlight .-Color[class*=-BGC135] { + background-color: #AF5FFF +} + +div.highlight .-Color[class*=-C136] { + color: #AF8700 +} + +div.highlight .-Color[class*=-BGC136] { + background-color: #AF8700 +} + +div.highlight .-Color[class*=-C137] { + color: #AF875F +} + +div.highlight .-Color[class*=-BGC137] { + background-color: #AF875F +} + +div.highlight .-Color[class*=-C138] { + color: #AF8787 +} + +div.highlight .-Color[class*=-BGC138] { + background-color: #AF8787 +} + +div.highlight .-Color[class*=-C139] { + color: #AF87AF +} + +div.highlight .-Color[class*=-BGC139] { + background-color: #AF87AF +} + +div.highlight .-Color[class*=-C140] { + color: #AF87D7 +} + +div.highlight .-Color[class*=-BGC140] { + background-color: #AF87D7 +} + +div.highlight .-Color[class*=-C141] { + color: #AF87FF +} + +div.highlight .-Color[class*=-BGC141] { + background-color: #AF87FF +} + +div.highlight .-Color[class*=-C142] { + color: #AFAF00 +} + +div.highlight .-Color[class*=-BGC142] { + background-color: #AFAF00 +} + +div.highlight .-Color[class*=-C143] { + color: #AFAF5F +} + +div.highlight .-Color[class*=-BGC143] { + background-color: #AFAF5F +} + +div.highlight .-Color[class*=-C144] { + color: #AFAF87 +} + +div.highlight .-Color[class*=-BGC144] { + background-color: #AFAF87 +} + +div.highlight .-Color[class*=-C145] { + color: #AFAFAF +} + +div.highlight .-Color[class*=-BGC145] { + background-color: #AFAFAF +} + +div.highlight .-Color[class*=-C146] { + color: #AFAFD7 +} + +div.highlight .-Color[class*=-BGC146] { + background-color: #AFAFD7 +} + +div.highlight .-Color[class*=-C147] { + color: #AFAFFF +} + +div.highlight .-Color[class*=-BGC147] { + background-color: #AFAFFF +} + +div.highlight .-Color[class*=-C148] { + color: #AFD700 +} + +div.highlight .-Color[class*=-BGC148] { + background-color: #AFD700 +} + +div.highlight .-Color[class*=-C149] { + color: #AFD75F +} + +div.highlight .-Color[class*=-BGC149] { + background-color: #AFD75F +} + +div.highlight .-Color[class*=-C150] { + color: #AFD787 +} + +div.highlight .-Color[class*=-BGC150] { + background-color: #AFD787 +} + +div.highlight .-Color[class*=-C151] { + color: #AFD7AF +} + +div.highlight .-Color[class*=-BGC151] { + background-color: #AFD7AF +} + +div.highlight .-Color[class*=-C152] { + color: #AFD7D7 +} + +div.highlight .-Color[class*=-BGC152] { + background-color: #AFD7D7 +} + +div.highlight .-Color[class*=-C153] { + color: #AFD7FF +} + +div.highlight .-Color[class*=-BGC153] { + background-color: #AFD7FF +} + +div.highlight .-Color[class*=-C154] { + color: #AFFF00 +} + +div.highlight .-Color[class*=-BGC154] { + background-color: #AFFF00 +} + +div.highlight .-Color[class*=-C155] { + color: #AFFF5F +} + +div.highlight .-Color[class*=-BGC155] { + background-color: #AFFF5F +} + +div.highlight .-Color[class*=-C156] { + color: #AFFF87 +} + +div.highlight .-Color[class*=-BGC156] { + background-color: #AFFF87 +} + +div.highlight .-Color[class*=-C157] { + color: #AFFFAF +} + +div.highlight .-Color[class*=-BGC157] { + background-color: #AFFFAF +} + +div.highlight .-Color[class*=-C158] { + color: #AFFFD7 +} + +div.highlight .-Color[class*=-BGC158] { + background-color: #AFFFD7 +} + +div.highlight .-Color[class*=-C159] { + color: #AFFFFF +} + +div.highlight .-Color[class*=-BGC159] { + background-color: #AFFFFF +} + +div.highlight .-Color[class*=-C160] { + color: #D70000 +} + +div.highlight .-Color[class*=-BGC160] { + background-color: #D70000 +} + +div.highlight .-Color[class*=-C161] { + color: #D7005F +} + +div.highlight .-Color[class*=-BGC161] { + background-color: #D7005F +} + +div.highlight .-Color[class*=-C162] { + color: #D70087 +} + +div.highlight .-Color[class*=-BGC162] { + background-color: #D70087 +} + +div.highlight .-Color[class*=-C163] { + color: #D700AF +} + +div.highlight .-Color[class*=-BGC163] { + background-color: #D700AF +} + +div.highlight .-Color[class*=-C164] { + color: #D700D7 +} + +div.highlight .-Color[class*=-BGC164] { + background-color: #D700D7 +} + +div.highlight .-Color[class*=-C165] { + color: #D700FF +} + +div.highlight .-Color[class*=-BGC165] { + background-color: #D700FF +} + +div.highlight .-Color[class*=-C166] { + color: #D75F00 +} + +div.highlight .-Color[class*=-BGC166] { + background-color: #D75F00 +} + +div.highlight .-Color[class*=-C167] { + color: #D75F5F +} + +div.highlight .-Color[class*=-BGC167] { + background-color: #D75F5F +} + +div.highlight .-Color[class*=-C168] { + color: #D75F87 +} + +div.highlight .-Color[class*=-BGC168] { + background-color: #D75F87 +} + +div.highlight .-Color[class*=-C169] { + color: #D75FAF +} + +div.highlight .-Color[class*=-BGC169] { + background-color: #D75FAF +} + +div.highlight .-Color[class*=-C170] { + color: #D75FD7 +} + +div.highlight .-Color[class*=-BGC170] { + background-color: #D75FD7 +} + +div.highlight .-Color[class*=-C171] { + color: #D75FFF +} + +div.highlight .-Color[class*=-BGC171] { + background-color: #D75FFF +} + +div.highlight .-Color[class*=-C172] { + color: #D78700 +} + +div.highlight .-Color[class*=-BGC172] { + background-color: #D78700 +} + +div.highlight .-Color[class*=-C173] { + color: #D7875F +} + +div.highlight .-Color[class*=-BGC173] { + background-color: #D7875F +} + +div.highlight .-Color[class*=-C174] { + color: #D78787 +} + +div.highlight .-Color[class*=-BGC174] { + background-color: #D78787 +} + +div.highlight .-Color[class*=-C175] { + color: #D787AF +} + +div.highlight .-Color[class*=-BGC175] { + background-color: #D787AF +} + +div.highlight .-Color[class*=-C176] { + color: #D787D7 +} + +div.highlight .-Color[class*=-BGC176] { + background-color: #D787D7 +} + +div.highlight .-Color[class*=-C177] { + color: #D787FF +} + +div.highlight .-Color[class*=-BGC177] { + background-color: #D787FF +} + +div.highlight .-Color[class*=-C178] { + color: #D7AF00 +} + +div.highlight .-Color[class*=-BGC178] { + background-color: #D7AF00 +} + +div.highlight .-Color[class*=-C179] { + color: #D7AF5F +} + +div.highlight .-Color[class*=-BGC179] { + background-color: #D7AF5F +} + +div.highlight .-Color[class*=-C180] { + color: #D7AF87 +} + +div.highlight .-Color[class*=-BGC180] { + background-color: #D7AF87 +} + +div.highlight .-Color[class*=-C181] { + color: #D7AFAF +} + +div.highlight .-Color[class*=-BGC181] { + background-color: #D7AFAF +} + +div.highlight .-Color[class*=-C182] { + color: #D7AFD7 +} + +div.highlight .-Color[class*=-BGC182] { + background-color: #D7AFD7 +} + +div.highlight .-Color[class*=-C183] { + color: #D7AFFF +} + +div.highlight .-Color[class*=-BGC183] { + background-color: #D7AFFF +} + +div.highlight .-Color[class*=-C184] { + color: #D7D700 +} + +div.highlight .-Color[class*=-BGC184] { + background-color: #D7D700 +} + +div.highlight .-Color[class*=-C185] { + color: #D7D75F +} + +div.highlight .-Color[class*=-BGC185] { + background-color: #D7D75F +} + +div.highlight .-Color[class*=-C186] { + color: #D7D787 +} + +div.highlight .-Color[class*=-BGC186] { + background-color: #D7D787 +} + +div.highlight .-Color[class*=-C187] { + color: #D7D7AF +} + +div.highlight .-Color[class*=-BGC187] { + background-color: #D7D7AF +} + +div.highlight .-Color[class*=-C188] { + color: #D7D7D7 +} + +div.highlight .-Color[class*=-BGC188] { + background-color: #D7D7D7 +} + +div.highlight .-Color[class*=-C189] { + color: #D7D7FF +} + +div.highlight .-Color[class*=-BGC189] { + background-color: #D7D7FF +} + +div.highlight .-Color[class*=-C190] { + color: #D7FF00 +} + +div.highlight .-Color[class*=-BGC190] { + background-color: #D7FF00 +} + +div.highlight .-Color[class*=-C191] { + color: #D7FF5F +} + +div.highlight .-Color[class*=-BGC191] { + background-color: #D7FF5F +} + +div.highlight .-Color[class*=-C192] { + color: #D7FF87 +} + +div.highlight .-Color[class*=-BGC192] { + background-color: #D7FF87 +} + +div.highlight .-Color[class*=-C193] { + color: #D7FFAF +} + +div.highlight .-Color[class*=-BGC193] { + background-color: #D7FFAF +} + +div.highlight .-Color[class*=-C194] { + color: #D7FFD7 +} + +div.highlight .-Color[class*=-BGC194] { + background-color: #D7FFD7 +} + +div.highlight .-Color[class*=-C195] { + color: #D7FFFF +} + +div.highlight .-Color[class*=-BGC195] { + background-color: #D7FFFF +} + +div.highlight .-Color[class*=-C196] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC196] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C197] { + color: #FF005F +} + +div.highlight .-Color[class*=-BGC197] { + background-color: #FF005F +} + +div.highlight .-Color[class*=-C198] { + color: #FF0087 +} + +div.highlight .-Color[class*=-BGC198] { + background-color: #FF0087 +} + +div.highlight .-Color[class*=-C199] { + color: #FF00AF +} + +div.highlight .-Color[class*=-BGC199] { + background-color: #FF00AF +} + +div.highlight .-Color[class*=-C200] { + color: #FF00D7 +} + +div.highlight .-Color[class*=-BGC200] { + background-color: #FF00D7 +} + +div.highlight .-Color[class*=-C201] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC201] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C202] { + color: #FF5F00 +} + +div.highlight .-Color[class*=-BGC202] { + background-color: #FF5F00 +} + +div.highlight .-Color[class*=-C203] { + color: #FF5F5F +} + +div.highlight .-Color[class*=-BGC203] { + background-color: #FF5F5F +} + +div.highlight .-Color[class*=-C204] { + color: #FF5F87 +} + +div.highlight .-Color[class*=-BGC204] { + background-color: #FF5F87 +} + +div.highlight .-Color[class*=-C205] { + color: #FF5FAF +} + +div.highlight .-Color[class*=-BGC205] { + background-color: #FF5FAF +} + +div.highlight .-Color[class*=-C206] { + color: #FF5FD7 +} + +div.highlight .-Color[class*=-BGC206] { + background-color: #FF5FD7 +} + +div.highlight .-Color[class*=-C207] { + color: #FF5FFF +} + +div.highlight .-Color[class*=-BGC207] { + background-color: #FF5FFF +} + +div.highlight .-Color[class*=-C208] { + color: #FF8700 +} + +div.highlight .-Color[class*=-BGC208] { + background-color: #FF8700 +} + +div.highlight .-Color[class*=-C209] { + color: #FF875F +} + +div.highlight .-Color[class*=-BGC209] { + background-color: #FF875F +} + +div.highlight .-Color[class*=-C210] { + color: #FF8787 +} + +div.highlight .-Color[class*=-BGC210] { + background-color: #FF8787 +} + +div.highlight .-Color[class*=-C211] { + color: #FF87AF +} + +div.highlight .-Color[class*=-BGC211] { + background-color: #FF87AF +} + +div.highlight .-Color[class*=-C212] { + color: #FF87D7 +} + +div.highlight .-Color[class*=-BGC212] { + background-color: #FF87D7 +} + +div.highlight .-Color[class*=-C213] { + color: #FF87FF +} + +div.highlight .-Color[class*=-BGC213] { + background-color: #FF87FF +} + +div.highlight .-Color[class*=-C214] { + color: #FFAF00 +} + +div.highlight .-Color[class*=-BGC214] { + background-color: #FFAF00 +} + +div.highlight .-Color[class*=-C215] { + color: #FFAF5F +} + +div.highlight .-Color[class*=-BGC215] { + background-color: #FFAF5F +} + +div.highlight .-Color[class*=-C216] { + color: #FFAF87 +} + +div.highlight .-Color[class*=-BGC216] { + background-color: #FFAF87 +} + +div.highlight .-Color[class*=-C217] { + color: #FFAFAF +} + +div.highlight .-Color[class*=-BGC217] { + background-color: #FFAFAF +} + +div.highlight .-Color[class*=-C218] { + color: #FFAFD7 +} + +div.highlight .-Color[class*=-BGC218] { + background-color: #FFAFD7 +} + +div.highlight .-Color[class*=-C219] { + color: #FFAFFF +} + +div.highlight .-Color[class*=-BGC219] { + background-color: #FFAFFF +} + +div.highlight .-Color[class*=-C220] { + color: #FFD700 +} + +div.highlight .-Color[class*=-BGC220] { + background-color: #FFD700 +} + +div.highlight .-Color[class*=-C221] { + color: #FFD75F +} + +div.highlight .-Color[class*=-BGC221] { + background-color: #FFD75F +} + +div.highlight .-Color[class*=-C222] { + color: #FFD787 +} + +div.highlight .-Color[class*=-BGC222] { + background-color: #FFD787 +} + +div.highlight .-Color[class*=-C223] { + color: #FFD7AF +} + +div.highlight .-Color[class*=-BGC223] { + background-color: #FFD7AF +} + +div.highlight .-Color[class*=-C224] { + color: #FFD7D7 +} + +div.highlight .-Color[class*=-BGC224] { + background-color: #FFD7D7 +} + +div.highlight .-Color[class*=-C225] { + color: #FFD7FF +} + +div.highlight .-Color[class*=-BGC225] { + background-color: #FFD7FF +} + +div.highlight .-Color[class*=-C226] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC226] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C227] { + color: #FFFF5F +} + +div.highlight .-Color[class*=-BGC227] { + background-color: #FFFF5F +} + +div.highlight .-Color[class*=-C228] { + color: #FFFF87 +} + +div.highlight .-Color[class*=-BGC228] { + background-color: #FFFF87 +} + +div.highlight .-Color[class*=-C229] { + color: #FFFFAF +} + +div.highlight .-Color[class*=-BGC229] { + background-color: #FFFFAF +} + +div.highlight .-Color[class*=-C230] { + color: #FFFFD7 +} + +div.highlight .-Color[class*=-BGC230] { + background-color: #FFFFD7 +} + +div.highlight .-Color[class*=-C231] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC231] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C232] { + color: #080808 +} + +div.highlight .-Color[class*=-BGC232] { + background-color: #080808 +} + +div.highlight .-Color[class*=-C233] { + color: #121212 +} + +div.highlight .-Color[class*=-BGC233] { + background-color: #121212 +} + +div.highlight .-Color[class*=-C234] { + color: #1C1C1C +} + +div.highlight .-Color[class*=-BGC234] { + background-color: #1C1C1C +} + +div.highlight .-Color[class*=-C235] { + color: #262626 +} + +div.highlight .-Color[class*=-BGC235] { + background-color: #262626 +} + +div.highlight .-Color[class*=-C236] { + color: #303030 +} + +div.highlight .-Color[class*=-BGC236] { + background-color: #303030 +} + +div.highlight .-Color[class*=-C237] { + color: #3A3A3A +} + +div.highlight .-Color[class*=-BGC237] { + background-color: #3A3A3A +} + +div.highlight .-Color[class*=-C238] { + color: #444444 +} + +div.highlight .-Color[class*=-BGC238] { + background-color: #444444 +} + +div.highlight .-Color[class*=-C239] { + color: #4E4E4E +} + +div.highlight .-Color[class*=-BGC239] { + background-color: #4E4E4E +} + +div.highlight .-Color[class*=-C240] { + color: #585858 +} + +div.highlight .-Color[class*=-BGC240] { + background-color: #585858 +} + +div.highlight .-Color[class*=-C241] { + color: #626262 +} + +div.highlight .-Color[class*=-BGC241] { + background-color: #626262 +} + +div.highlight .-Color[class*=-C242] { + color: #6C6C6C +} + +div.highlight .-Color[class*=-BGC242] { + background-color: #6C6C6C +} + +div.highlight .-Color[class*=-C243] { + color: #767676 +} + +div.highlight .-Color[class*=-BGC243] { + background-color: #767676 +} + +div.highlight .-Color[class*=-C244] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC244] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C245] { + color: #8A8A8A +} + +div.highlight .-Color[class*=-BGC245] { + background-color: #8A8A8A +} + +div.highlight .-Color[class*=-C246] { + color: #949494 +} + +div.highlight .-Color[class*=-BGC246] { + background-color: #949494 +} + +div.highlight .-Color[class*=-C247] { + color: #9E9E9E +} + +div.highlight .-Color[class*=-BGC247] { + background-color: #9E9E9E +} + +div.highlight .-Color[class*=-C248] { + color: #A8A8A8 +} + +div.highlight .-Color[class*=-BGC248] { + background-color: #A8A8A8 +} + +div.highlight .-Color[class*=-C249] { + color: #B2B2B2 +} + +div.highlight .-Color[class*=-BGC249] { + background-color: #B2B2B2 +} + +div.highlight .-Color[class*=-C250] { + color: #BCBCBC +} + +div.highlight .-Color[class*=-BGC250] { + background-color: #BCBCBC +} + +div.highlight .-Color[class*=-C251] { + color: #C6C6C6 +} + +div.highlight .-Color[class*=-BGC251] { + background-color: #C6C6C6 +} + +div.highlight .-Color[class*=-C252] { + color: #D0D0D0 +} + +div.highlight .-Color[class*=-BGC252] { + background-color: #D0D0D0 +} + +div.highlight .-Color[class*=-C253] { + color: #DADADA +} + +div.highlight .-Color[class*=-BGC253] { + background-color: #DADADA +} + +div.highlight .-Color[class*=-C254] { + color: #E4E4E4 +} + +div.highlight .-Color[class*=-BGC254] { + background-color: #E4E4E4 +} + +div.highlight .-Color[class*=-C255] { + color: #EEEEEE +} + +div.highlight .-Color[class*=-BGC255] { + background-color: #EEEEEE +} diff --git a/_static/plus.png b/_static/plus.png new file mode 100644 index 0000000..7107cec Binary files /dev/null and b/_static/plus.png differ diff --git a/_static/pygments.css b/_static/pygments.css new file mode 100644 index 0000000..84ab303 --- /dev/null +++ b/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/_static/searchtools.js b/_static/searchtools.js new file mode 100644 index 0000000..b08d58c --- /dev/null +++ b/_static/searchtools.js @@ -0,0 +1,620 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/_static/sphinx-design.min.css b/_static/sphinx-design.min.css new file mode 100644 index 0000000..860c36d --- /dev/null +++ b/_static/sphinx-design.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative;font-size:var(--sd-fontsize-dropdown)}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary.sd-summary-title{padding:.5em .6em .5em 1em;font-size:var(--sd-fontsize-dropdown-title);font-weight:var(--sd-fontweight-dropdown-title);user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;list-style:none;display:inline-flex;justify-content:space-between}details.sd-dropdown summary.sd-summary-title::-webkit-details-marker{display:none}details.sd-dropdown summary.sd-summary-title:focus{outline:none}details.sd-dropdown summary.sd-summary-title .sd-summary-icon{margin-right:.6em;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary.sd-summary-title .sd-summary-text{flex-grow:1;line-height:1.5;padding-right:.5rem}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker{pointer-events:none;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker svg{opacity:.6}details.sd-dropdown summary.sd-summary-title:hover .sd-summary-state-marker svg{opacity:1;transform:scale(1.1)}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown .sd-summary-chevron-right{transition:.25s}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-right{transform:rotate(90deg)}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-down{transform:rotate(180deg)}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-bg: rgba(0, 113, 188, 0.2);--sd-color-secondary-bg: rgba(108, 117, 125, 0.2);--sd-color-success-bg: rgba(40, 167, 69, 0.2);--sd-color-info-bg: rgba(23, 162, 184, 0.2);--sd-color-warning-bg: rgba(240, 179, 126, 0.2);--sd-color-danger-bg: rgba(220, 53, 69, 0.2);--sd-color-light-bg: rgba(248, 249, 250, 0.2);--sd-color-muted-bg: rgba(108, 117, 125, 0.2);--sd-color-dark-bg: rgba(33, 37, 41, 0.2);--sd-color-black-bg: rgba(0, 0, 0, 0.2);--sd-color-white-bg: rgba(255, 255, 255, 0.2);--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem;--sd-fontsize-dropdown: inherit;--sd-fontsize-dropdown-title: 1rem;--sd-fontweight-dropdown-title: 700} diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js new file mode 100644 index 0000000..8a96c69 --- /dev/null +++ b/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/_static/sphinx_lesson.css b/_static/sphinx_lesson.css new file mode 100644 index 0000000..14b20c6 --- /dev/null +++ b/_static/sphinx_lesson.css @@ -0,0 +1,51 @@ +/* sphinx_lesson.css */ + +body.wy-body-for-nav img.with-border { + border: 2px solid; +} + +.rst-content .admonition-no-content { + padding-bottom: 0px; +} + +.rst-content .demo > .admonition-title::before { + content: "\01F440"; /* Eyes */ } +.rst-content .type-along > .admonition-title::before { + content: "\02328\0FE0F"; /* Keyboard */ } +.rst-content .exercise > .admonition-title::before { + content: "\0270D\0FE0F"; /* Hand */ } +.rst-content .solution > .admonition-title::before { + content: "\02714\0FE0E"; /* Check mark */ } +.rst-content .homework > .admonition-title::before { + content: "\01F4DD"; /* Memo */ } +.rst-content .discussion > .admonition-title::before { + content: "\01F4AC"; /* Speech balloon */ } +.rst-content .questions > .admonition-title::before { + content: "\02753\0FE0E"; /* Question mark */ } +.rst-content .prerequisites > .admonition-title::before { + content: "\02699"; /* Gear */ } +.rst-content .seealso > .admonition-title::before { + content: "\027A1\0FE0E"; /* Question mark */ } + + +/* instructor-note */ +.rst-content .instructor-note { + background: #e7e7e7; +} +.rst-content .instructor-note > .admonition-title { + background: #6a6a6a; +} +.rst-content .instructor-note > .admonition-title::before { + content: ""; +} + + +/* sphinx_toggle_button, make the font white */ +.rst-content .toggle.admonition button.toggle-button { + color: white; +} + +/* sphinx-togglebutton, remove underflow when toggled to hidden mode */ +.rst-content .admonition.toggle-hidden { + padding-bottom: 0px; +} diff --git a/_static/sphinx_rtd_theme_ext_color_contrast.css b/_static/sphinx_rtd_theme_ext_color_contrast.css new file mode 100644 index 0000000..e68feb8 --- /dev/null +++ b/_static/sphinx_rtd_theme_ext_color_contrast.css @@ -0,0 +1,47 @@ +/* The following are for web accessibility of sphinx_rtd_theme: they + * solve some of the most frequent contrast issues. Remove when this + * solved: + * https://github.com/readthedocs/sphinx_rtd_theme/issues/971 + */ +/* background: #fcfcfc, note boxes #E7F2FA */ +a { color: #2573A7; } /* original #2980B9, #1F5C84; */ +body { color: #242424; } /* original #404040, #383838 */ +.wy-side-nav-search>a, .wy-side-nav-search .wy-dropdown>a { + color: #ffffff; +} /* original #fcfcfc */ +footer { color: #737373; } /* original gray=#808080*/ +footer span.commit code, footer span.commit .rst-content tt, .rst-content footer span.commit tt { + color: #737373; +} /* original gray=#808080*/ +.rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal { + color: #AB2314; +} +/* Sidebar background */ +.wy-side-nav-search { background-color: #277CB4;} + +/* Same, but for pygments */ +.highlight .ch { color: #3E7A89; } /* #! line */ +.highlight .c1 { color: #3E7A89; } /* also comments */ +.highlight .nv { color: #AD3ECC; } /* variable */ +.highlight .gp { color: #B45608; } /* prompt character, $*/ +.highlight .si { color: #3975B1; } /* ${} variable text */ +.highlight .nc { color: #0C78A7; } + +/* Sphinx admonitions */ +/* warning */ +.wy-alert.wy-alert-warning .wy-alert-title, .rst-content .wy-alert-warning.note .wy-alert-title, .rst-content .attention .wy-alert-title, .rst-content .caution .wy-alert-title, .rst-content .wy-alert-warning.danger .wy-alert-title, .rst-content .wy-alert-warning.error .wy-alert-title, .rst-content .wy-alert-warning.hint .wy-alert-title, .rst-content .wy-alert-warning.important .wy-alert-title, .rst-content .wy-alert-warning.tip .wy-alert-title, .rst-content .warning .wy-alert-title, .rst-content .wy-alert-warning.seealso .wy-alert-title, .rst-content .admonition-todo .wy-alert-title, .rst-content .wy-alert-warning.admonition .wy-alert-title, .wy-alert.wy-alert-warning .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-warning .admonition-title, .rst-content .wy-alert-warning.note .admonition-title, .rst-content .attention .admonition-title, .rst-content .caution .admonition-title, .rst-content .wy-alert-warning.danger .admonition-title, .rst-content .wy-alert-warning.error .admonition-title, .rst-content .wy-alert-warning.hint .admonition-title, .rst-content .wy-alert-warning.important .admonition-title, .rst-content .wy-alert-warning.tip .admonition-title, .rst-content .warning .admonition-title, .rst-content .wy-alert-warning.seealso .admonition-title, .rst-content .admonition-todo .admonition-title, .rst-content .wy-alert-warning.admonition .admonition-title { + background: #B15E16; } +/* important */ +.wy-alert.wy-alert-success .wy-alert-title, .rst-content .wy-alert-success.note .wy-alert-title, .rst-content .wy-alert-success.attention .wy-alert-title, .rst-content .wy-alert-success.caution .wy-alert-title, .rst-content .wy-alert-success.danger .wy-alert-title, .rst-content .wy-alert-success.error .wy-alert-title, .rst-content .hint .wy-alert-title, .rst-content .important .wy-alert-title, .rst-content .tip .wy-alert-title, .rst-content .wy-alert-success.warning .wy-alert-title, .rst-content .wy-alert-success.seealso .wy-alert-title, .rst-content .wy-alert-success.admonition-todo .wy-alert-title, .rst-content .wy-alert-success.admonition .wy-alert-title, .wy-alert.wy-alert-success .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-success .admonition-title, .rst-content .wy-alert-success.note .admonition-title, .rst-content .wy-alert-success.attention .admonition-title, .rst-content .wy-alert-success.caution .admonition-title, .rst-content .wy-alert-success.danger .admonition-title, .rst-content .wy-alert-success.error .admonition-title, .rst-content .hint .admonition-title, .rst-content .important .admonition-title, .rst-content .tip .admonition-title, .rst-content .wy-alert-success.warning .admonition-title, .rst-content .wy-alert-success.seealso .admonition-title, .rst-content .wy-alert-success.admonition-todo .admonition-title, .rst-content .wy-alert-success.admonition .admonition-title { + background: #12826C; } +/* seealso, note, etc */ +.wy-alert.wy-alert-info .wy-alert-title, .rst-content .note .wy-alert-title, .rst-content .wy-alert-info.attention .wy-alert-title, .rst-content .wy-alert-info.caution .wy-alert-title, .rst-content .wy-alert-info.danger .wy-alert-title, .rst-content .wy-alert-info.error .wy-alert-title, .rst-content .wy-alert-info.hint .wy-alert-title, .rst-content .wy-alert-info.important .wy-alert-title, .rst-content .wy-alert-info.tip .wy-alert-title, .rst-content .wy-alert-info.warning .wy-alert-title, .rst-content .seealso .wy-alert-title, .rst-content .wy-alert-info.admonition-todo .wy-alert-title, .rst-content .wy-alert-info.admonition .wy-alert-title, .wy-alert.wy-alert-info .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-info .admonition-title, .rst-content .note .admonition-title, .rst-content .wy-alert-info.attention .admonition-title, .rst-content .wy-alert-info.caution .admonition-title, .rst-content .wy-alert-info.danger .admonition-title, .rst-content .wy-alert-info.error .admonition-title, .rst-content .wy-alert-info.hint .admonition-title, .rst-content .wy-alert-info.important .admonition-title, .rst-content .wy-alert-info.tip .admonition-title, .rst-content .wy-alert-info.warning .admonition-title, .rst-content .seealso .admonition-title, .rst-content .wy-alert-info.admonition-todo .admonition-title, .rst-content .wy-alert-info.admonition .admonition-title { + background: #277CB4; } +/* error, danger */ +.rst-content .danger .admonition-title, .rst-content .danger .wy-alert-title, .rst-content .error .admonition-title, .rst-content .error .wy-alert-title, .rst-content .wy-alert-danger.admonition-todo .admonition-title, .rst-content .wy-alert-danger.admonition-todo .wy-alert-title, .rst-content .wy-alert-danger.admonition .admonition-title, .rst-content .wy-alert-danger.admonition .wy-alert-title, .rst-content .wy-alert-danger.attention .admonition-title, .rst-content .wy-alert-danger.attention .wy-alert-title, .rst-content .wy-alert-danger.caution .admonition-title, .rst-content .wy-alert-danger.caution .wy-alert-title, .rst-content .wy-alert-danger.hint .admonition-title, .rst-content .wy-alert-danger.hint .wy-alert-title, .rst-content .wy-alert-danger.important .admonition-title, .rst-content .wy-alert-danger.important .wy-alert-title, .rst-content .wy-alert-danger.note .admonition-title, .rst-content .wy-alert-danger.note .wy-alert-title, .rst-content .wy-alert-danger.seealso .admonition-title, .rst-content .wy-alert-danger.seealso .wy-alert-title, .rst-content .wy-alert-danger.tip .admonition-title, .rst-content .wy-alert-danger.tip .wy-alert-title, .rst-content .wy-alert-danger.warning .admonition-title, .rst-content .wy-alert-danger.warning .wy-alert-title, .rst-content .wy-alert.wy-alert-danger .admonition-title, .wy-alert.wy-alert-danger .rst-content .admonition-title, .wy-alert.wy-alert-danger .wy-alert-title { + background: #e31704; +} + +/* Generic admonition titles */ +.wy-alert-title, .rst-content .admonition-title { + background: #277CB4; } diff --git a/_static/tabs.css b/_static/tabs.css new file mode 100644 index 0000000..957ba60 --- /dev/null +++ b/_static/tabs.css @@ -0,0 +1,89 @@ +.sphinx-tabs { + margin-bottom: 1rem; +} + +[role="tablist"] { + border-bottom: 1px solid #a0b3bf; +} + +.sphinx-tabs-tab { + position: relative; + font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; + color: #1D5C87; + line-height: 24px; + margin: 0; + font-size: 16px; + font-weight: 400; + background-color: rgba(255, 255, 255, 0); + border-radius: 5px 5px 0 0; + border: 0; + padding: 1rem 1.5rem; + margin-bottom: 0; +} + +.sphinx-tabs-tab[aria-selected="true"] { + font-weight: 700; + border: 1px solid #a0b3bf; + border-bottom: 1px solid white; + margin: -1px; + background-color: white; +} + +.sphinx-tabs-tab:focus { + z-index: 1; + outline-offset: 1px; +} + +.sphinx-tabs-panel { + position: relative; + padding: 1rem; + border: 1px solid #a0b3bf; + margin: 0px -1px -1px -1px; + border-radius: 0 0 5px 5px; + border-top: 0; + background: white; +} + +.sphinx-tabs-panel.code-tab { + padding: 0.4rem; +} + +.sphinx-tab img { + margin-bottom: 24 px; +} + +/* Dark theme preference styling */ + +@media (prefers-color-scheme: dark) { + body[data-theme="auto"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); + } + + body[data-theme="auto"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); + } + + body[data-theme="auto"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 1px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); + } +} + +/* Explicit dark theme styling */ + +body[data-theme="dark"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); +} + +body[data-theme="dark"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); +} + +body[data-theme="dark"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 2px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); +} diff --git a/_static/tabs.js b/_static/tabs.js new file mode 100644 index 0000000..48dc303 --- /dev/null +++ b/_static/tabs.js @@ -0,0 +1,145 @@ +try { + var session = window.sessionStorage || {}; +} catch (e) { + var session = {}; +} + +window.addEventListener("DOMContentLoaded", () => { + const allTabs = document.querySelectorAll('.sphinx-tabs-tab'); + const tabLists = document.querySelectorAll('[role="tablist"]'); + + allTabs.forEach(tab => { + tab.addEventListener("click", changeTabs); + }); + + tabLists.forEach(tabList => { + tabList.addEventListener("keydown", keyTabs); + }); + + // Restore group tab selection from session + const lastSelected = session.getItem('sphinx-tabs-last-selected'); + if (lastSelected != null) selectNamedTabs(lastSelected); +}); + +/** + * Key focus left and right between sibling elements using arrows + * @param {Node} e the element in focus when key was pressed + */ +function keyTabs(e) { + const tab = e.target; + let nextTab = null; + if (e.keyCode === 39 || e.keyCode === 37) { + tab.setAttribute("tabindex", -1); + // Move right + if (e.keyCode === 39) { + nextTab = tab.nextElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.firstElementChild; + } + // Move left + } else if (e.keyCode === 37) { + nextTab = tab.previousElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.lastElementChild; + } + } + } + + if (nextTab !== null) { + nextTab.setAttribute("tabindex", 0); + nextTab.focus(); + } +} + +/** + * Select or deselect clicked tab. If a group tab + * is selected, also select tab in other tabLists. + * @param {Node} e the element that was clicked + */ +function changeTabs(e) { + // Use this instead of the element that was clicked, in case it's a child + const notSelected = this.getAttribute("aria-selected") === "false"; + const positionBefore = this.parentNode.getBoundingClientRect().top; + const notClosable = !this.parentNode.classList.contains("closeable"); + + deselectTabList(this); + + if (notSelected || notClosable) { + selectTab(this); + const name = this.getAttribute("name"); + selectNamedTabs(name, this.id); + + if (this.classList.contains("group-tab")) { + // Persist during session + session.setItem('sphinx-tabs-last-selected', name); + } + } + + const positionAfter = this.parentNode.getBoundingClientRect().top; + const positionDelta = positionAfter - positionBefore; + // Scroll to offset content resizing + window.scrollTo(0, window.scrollY + positionDelta); +} + +/** + * Select tab and show associated panel. + * @param {Node} tab tab to select + */ +function selectTab(tab) { + tab.setAttribute("aria-selected", true); + + // Show the associated panel + document + .getElementById(tab.getAttribute("aria-controls")) + .removeAttribute("hidden"); +} + +/** + * Hide the panels associated with all tabs within the + * tablist containing this tab. + * @param {Node} tab a tab within the tablist to deselect + */ +function deselectTabList(tab) { + const parent = tab.parentNode; + const grandparent = parent.parentNode; + + Array.from(parent.children) + .forEach(t => t.setAttribute("aria-selected", false)); + + Array.from(grandparent.children) + .slice(1) // Skip tablist + .forEach(panel => panel.setAttribute("hidden", true)); +} + +/** + * Select grouped tabs with the same name, but no the tab + * with the given id. + * @param {Node} name name of grouped tab to be selected + * @param {Node} clickedId id of clicked tab + */ +function selectNamedTabs(name, clickedId=null) { + const groupedTabs = document.querySelectorAll(`.sphinx-tabs-tab[name="${name}"]`); + const tabLists = Array.from(groupedTabs).map(tab => tab.parentNode); + + tabLists + .forEach(tabList => { + // Don't want to change the tabList containing the clicked tab + const clickedTab = tabList.querySelector(`[id="${clickedId}"]`); + if (clickedTab === null ) { + // Select first tab with matching name + const tab = tabList.querySelector(`.sphinx-tabs-tab[name="${name}"]`); + deselectTabList(tab); + selectTab(tab); + } + }) +} + +if (typeof exports === 'undefined') { + exports = {}; +} + +exports.keyTabs = keyTabs; +exports.changeTabs = changeTabs; +exports.selectTab = selectTab; +exports.deselectTabList = deselectTabList; +exports.selectNamedTabs = selectNamedTabs; diff --git a/_static/term_role_formatting.css b/_static/term_role_formatting.css new file mode 100644 index 0000000..0b66095 --- /dev/null +++ b/_static/term_role_formatting.css @@ -0,0 +1,4 @@ +/* Make terms bold */ +a.reference span.std-term { + font-weight: bold; +} diff --git a/_static/togglebutton.css b/_static/togglebutton.css new file mode 100644 index 0000000..54a6787 --- /dev/null +++ b/_static/togglebutton.css @@ -0,0 +1,160 @@ +/** + * Admonition-based toggles + */ + +/* Visibility of the target */ +.admonition.toggle .admonition-title ~ * { + transition: opacity .3s, height .3s; +} + +/* Toggle buttons inside admonitions so we see the title */ +.admonition.toggle { + position: relative; +} + +/* Titles should cut off earlier to avoid overlapping w/ button */ +.admonition.toggle .admonition-title { + padding-right: 25%; + cursor: pointer; +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:hover { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 1%); +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:active { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 3%); +} + +/* Remove extra whitespace below the admonition title when hidden */ +.admonition.toggle-hidden { + padding-bottom: 0; +} + +.admonition.toggle-hidden .admonition-title { + margin-bottom: 0; +} + +/* hides all the content of a page until de-toggled */ +.admonition.toggle-hidden .admonition-title ~ * { + height: 0; + margin: 0; + opacity: 0; + visibility: hidden; +} + +/* General button style and position*/ +button.toggle-button { + /** + * Background and shape. By default there's no background + * but users can style as they wish + */ + background: none; + border: none; + outline: none; + + /* Positioning just inside the admonition title */ + position: absolute; + right: 0.5em; + padding: 0px; + border: none; + outline: none; +} + +/* Display the toggle hint on wide screens */ +@media (min-width: 768px) { + button.toggle-button.toggle-button-hidden:before { + content: attr(data-toggle-hint); /* This will be filled in by JS */ + font-size: .8em; + align-self: center; + } +} + +/* Icon behavior */ +.tb-icon { + transition: transform .2s ease-out; + height: 1.5em; + width: 1.5em; + stroke: currentColor; /* So that we inherit the color of other text */ +} + +/* The icon should point right when closed, down when open. */ +/* Open */ +.admonition.toggle button .tb-icon { + transform: rotate(90deg); +} + +/* Closed */ +.admonition.toggle button.toggle-button-hidden .tb-icon { + transform: rotate(0deg); +} + +/* With details toggles, we don't rotate the icon so it points right */ +details.toggle-details .tb-icon { + height: 1.4em; + width: 1.4em; + margin-top: 0.1em; /* To center the button vertically */ +} + + +/** + * Details-based toggles. + * In this case, we wrap elements with `.toggle` in a details block. + */ + +/* Details blocks */ +details.toggle-details { + margin: 1em 0; +} + + +details.toggle-details summary { + display: flex; + align-items: center; + cursor: pointer; + list-style: none; + border-radius: .2em; + border-left: 3px solid #1976d2; + background-color: rgb(204 204 204 / 10%); + padding: 0.2em 0.7em 0.3em 0.5em; /* Less padding on left because the SVG has left margin */ + font-size: 0.9em; +} + +details.toggle-details summary:hover { + background-color: rgb(204 204 204 / 20%); +} + +details.toggle-details summary:active { + background: rgb(204 204 204 / 28%); +} + +.toggle-details__summary-text { + margin-left: 0.2em; +} + +details.toggle-details[open] summary { + margin-bottom: .5em; +} + +details.toggle-details[open] summary .tb-icon { + transform: rotate(90deg); +} + +details.toggle-details[open] summary ~ * { + animation: toggle-fade-in .3s ease-out; +} + +@keyframes toggle-fade-in { + from {opacity: 0%;} + to {opacity: 100%;} +} + +/* Print rules - we hide all toggle button elements at print */ +@media print { + /* Always hide the summary so the button doesn't show up */ + details.toggle-details summary { + display: none; + } +} \ No newline at end of file diff --git a/_static/togglebutton.js b/_static/togglebutton.js new file mode 100644 index 0000000..215a7ee --- /dev/null +++ b/_static/togglebutton.js @@ -0,0 +1,187 @@ +/** + * Add Toggle Buttons to elements + */ + +let toggleChevron = ` + + + +`; + +var initToggleItems = () => { + var itemsToToggle = document.querySelectorAll(togglebuttonSelector); + console.log(`[togglebutton]: Adding toggle buttons to ${itemsToToggle.length} items`) + // Add the button to each admonition and hook up a callback to toggle visibility + itemsToToggle.forEach((item, index) => { + if (item.classList.contains("admonition")) { + // If it's an admonition block, then we'll add a button inside + // Generate unique IDs for this item + var toggleID = `toggle-${index}`; + var buttonID = `button-${toggleID}`; + + item.setAttribute('id', toggleID); + if (!item.classList.contains("toggle")){ + item.classList.add("toggle"); + } + // This is the button that will be added to each item to trigger the toggle + var collapseButton = ` + `; + + title = item.querySelector(".admonition-title") + title.insertAdjacentHTML("beforeend", collapseButton); + thisButton = document.getElementById(buttonID); + + // Add click handlers for the button + admonition title (if admonition) + admonitionTitle = document.querySelector(`#${toggleID} > .admonition-title`) + if (admonitionTitle) { + // If an admonition, then make the whole title block clickable + admonitionTitle.addEventListener('click', toggleClickHandler); + admonitionTitle.dataset.target = toggleID + admonitionTitle.dataset.button = buttonID + } else { + // If not an admonition then we'll listen for the button click + thisButton.addEventListener('click', toggleClickHandler); + } + + // Now hide the item for this toggle button unless explicitly noted to show + if (!item.classList.contains("toggle-shown")) { + toggleHidden(thisButton); + } + } else { + // If not an admonition, wrap the block in a
block + // Define the structure of the details block and insert it as a sibling + var detailsBlock = ` +
+ + ${toggleChevron} + ${toggleHintShow} + +
`; + item.insertAdjacentHTML("beforebegin", detailsBlock); + + // Now move the toggle-able content inside of the details block + details = item.previousElementSibling + details.appendChild(item) + item.classList.add("toggle-details__container") + + // Set up a click trigger to change the text as needed + details.addEventListener('click', (click) => { + let parent = click.target.parentElement; + if (parent.tagName.toLowerCase() == "details") { + summary = parent.querySelector("summary"); + details = parent; + } else { + summary = parent; + details = parent.parentElement; + } + // Update the inner text for the proper hint + if (details.open) { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintShow; + } else { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintHide; + } + + }); + + // If we have a toggle-shown class, open details block should be open + if (item.classList.contains("toggle-shown")) { + details.click(); + } + } + }) +}; + +// This should simply add / remove the collapsed class and change the button text +var toggleHidden = (button) => { + target = button.dataset['target'] + var itemToToggle = document.getElementById(target); + if (itemToToggle.classList.contains("toggle-hidden")) { + itemToToggle.classList.remove("toggle-hidden"); + button.classList.remove("toggle-button-hidden"); + } else { + itemToToggle.classList.add("toggle-hidden"); + button.classList.add("toggle-button-hidden"); + } +} + +var toggleClickHandler = (click) => { + // Be cause the admonition title is clickable and extends to the whole admonition + // We only look for a click event on this title to trigger the toggle. + + if (click.target.classList.contains("admonition-title")) { + button = click.target.querySelector(".toggle-button"); + } else if (click.target.classList.contains("tb-icon")) { + // We've clicked the icon and need to search up one parent for the button + button = click.target.parentElement; + } else if (click.target.tagName == "polyline") { + // We've clicked the SVG elements inside the button, need to up 2 layers + button = click.target.parentElement.parentElement; + } else if (click.target.classList.contains("toggle-button")) { + // We've clicked the button itself and so don't need to do anything + button = click.target; + } else { + console.log(`[togglebutton]: Couldn't find button for ${click.target}`) + } + target = document.getElementById(button.dataset['button']); + toggleHidden(target); +} + +// If we want to blanket-add toggle classes to certain cells +var addToggleToSelector = () => { + const selector = ""; + if (selector.length > 0) { + document.querySelectorAll(selector).forEach((item) => { + item.classList.add("toggle"); + }) + } +} + +// Helper function to run when the DOM is finished +const sphinxToggleRunWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} +sphinxToggleRunWhenDOMLoaded(addToggleToSelector) +sphinxToggleRunWhenDOMLoaded(initToggleItems) + +/** Toggle details blocks to be open when printing */ +if (toggleOpenOnPrint == "true") { + window.addEventListener("beforeprint", () => { + // Open the details + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.dataset["togglestatus"] = el.open; + el.open = true; + }); + + // Open the admonitions + document.querySelectorAll(".admonition.toggle.toggle-hidden").forEach((el) => { + console.log(el); + el.querySelector("button.toggle-button").click(); + el.dataset["toggle_after_print"] = "true"; + }); + }); + window.addEventListener("afterprint", () => { + // Re-close the details that were closed + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.open = el.dataset["togglestatus"] == "true"; + delete el.dataset["togglestatus"]; + }); + + // Re-close the admonition toggle buttons + document.querySelectorAll(".admonition.toggle").forEach((el) => { + if (el.dataset["toggle_after_print"] == "true") { + el.querySelector("button.toggle-button").click(); + delete el.dataset["toggle_after_print"]; + } + }); + }); +} diff --git a/branch/cff/_images/BYOC.png b/branch/cff/_images/BYOC.png new file mode 100644 index 0000000..94702a1 Binary files /dev/null and b/branch/cff/_images/BYOC.png differ diff --git a/branch/cff/_images/CR_workshop_setup.png b/branch/cff/_images/CR_workshop_setup.png new file mode 100644 index 0000000..47b4502 Binary files /dev/null and b/branch/cff/_images/CR_workshop_setup.png differ diff --git a/branch/cff/_images/community.png b/branch/cff/_images/community.png new file mode 100644 index 0000000..ddd9a62 Binary files /dev/null and b/branch/cff/_images/community.png differ diff --git a/branch/cff/_images/hackmd--controls.png b/branch/cff/_images/hackmd--controls.png new file mode 100644 index 0000000..46a74c7 Binary files /dev/null and b/branch/cff/_images/hackmd--controls.png differ diff --git a/branch/cff/_images/hackmd--full-demo.png b/branch/cff/_images/hackmd--full-demo.png new file mode 100644 index 0000000..0988b6f Binary files /dev/null and b/branch/cff/_images/hackmd--full-demo.png differ diff --git a/branch/cff/_images/hackmd--questions2.png b/branch/cff/_images/hackmd--questions2.png new file mode 100644 index 0000000..a609199 Binary files /dev/null and b/branch/cff/_images/hackmd--questions2.png differ diff --git a/branch/cff/_images/history-landscape-dark.png b/branch/cff/_images/history-landscape-dark.png new file mode 100644 index 0000000..a1aef3c Binary files /dev/null and b/branch/cff/_images/history-landscape-dark.png differ diff --git a/branch/cff/_images/history-portrait-dark.png b/branch/cff/_images/history-portrait-dark.png new file mode 100644 index 0000000..2fc1fa6 Binary files /dev/null and b/branch/cff/_images/history-portrait-dark.png differ diff --git a/branch/cff/_images/history-portrait-light.png b/branch/cff/_images/history-portrait-light.png new file mode 100644 index 0000000..5f4361c Binary files /dev/null and b/branch/cff/_images/history-portrait-light.png differ diff --git a/branch/cff/_images/history-portrait.png b/branch/cff/_images/history-portrait.png new file mode 100644 index 0000000..28e18b0 Binary files /dev/null and b/branch/cff/_images/history-portrait.png differ diff --git a/branch/cff/_images/history-rsh.png b/branch/cff/_images/history-rsh.png new file mode 100644 index 0000000..1bbb1cc Binary files /dev/null and b/branch/cff/_images/history-rsh.png differ diff --git a/branch/cff/_images/instructor.png b/branch/cff/_images/instructor.png new file mode 100644 index 0000000..718f2a8 Binary files /dev/null and b/branch/cff/_images/instructor.png differ diff --git a/branch/cff/_images/landscape.png b/branch/cff/_images/landscape.png new file mode 100644 index 0000000..eda9d42 Binary files /dev/null and b/branch/cff/_images/landscape.png differ diff --git a/branch/cff/_images/learner-large.png b/branch/cff/_images/learner-large.png new file mode 100644 index 0000000..3b6d2cd Binary files /dev/null and b/branch/cff/_images/learner-large.png differ diff --git a/branch/cff/_images/learner-normal.png b/branch/cff/_images/learner-normal.png new file mode 100644 index 0000000..590135e Binary files /dev/null and b/branch/cff/_images/learner-normal.png differ diff --git a/branch/cff/_images/learner-small.png b/branch/cff/_images/learner-small.png new file mode 100644 index 0000000..5d5f421 Binary files /dev/null and b/branch/cff/_images/learner-small.png differ diff --git a/branch/cff/_images/portrait.png b/branch/cff/_images/portrait.png new file mode 100644 index 0000000..415799f Binary files /dev/null and b/branch/cff/_images/portrait.png differ diff --git a/branch/cff/_images/steps.png b/branch/cff/_images/steps.png new file mode 100644 index 0000000..6c978b5 Binary files /dev/null and b/branch/cff/_images/steps.png differ diff --git a/branch/cff/_images/survey-impact1.png b/branch/cff/_images/survey-impact1.png new file mode 100644 index 0000000..7dd0ddc Binary files /dev/null and b/branch/cff/_images/survey-impact1.png differ diff --git a/branch/cff/_images/survey-impact2.png b/branch/cff/_images/survey-impact2.png new file mode 100644 index 0000000..8771bff Binary files /dev/null and b/branch/cff/_images/survey-impact2.png differ diff --git a/branch/cff/_images/welcome.png b/branch/cff/_images/welcome.png new file mode 100644 index 0000000..302082c Binary files /dev/null and b/branch/cff/_images/welcome.png differ diff --git a/branch/cff/_sources/co-teaching.md.txt b/branch/cff/_sources/co-teaching.md.txt new file mode 100644 index 0000000..c197f10 --- /dev/null +++ b/branch/cff/_sources/co-teaching.md.txt @@ -0,0 +1,110 @@ +(co-teaching)= + +# Co-teaching + +:::{objectives} +- Get to know the principle of co-teaching: How we do it and how you can too. +- Learn the team teaching concept and how to tailor it to your situation. +::: + +:::{instructor-note} +- Teaching: 15 min +- Exercises: 10 min +- Discussion: 5 min +::: + + +## Overview + +CodeRefinery lessons benefit from the application of the concepts of **co-teaching**. + +:::{admonition} Co-teaching +[Co-teaching](https://en.wikipedia.org/wiki/Co-teaching) can be defined as "the division of labor between educators to plan, organize, instruct and make assessments on the same group of students, generally in a common classroom, and often with a strong focus on those teaching as a team complementing one another's particular skills or other strengths". +::: + +Co-teaching can be used in various forms, some of which are present in our workshops: +- **Teaching + support**, e.g. one of the teachers leading instruction while the other watches over and maintains the collaborative document (HackMD/HedgeDoc/...). +- Another similar example is **remote learning groups** that watch the streamed CodeRefinery lessons guided by the local instructors. +- Having open-source material and planning jointly allows **multiple instances** of a lesson to be held by multiple teachers: + - *parallel teaching*, to different audiences at the same time, + - *alternative teaching*, to different audiences at the same or different time, with potential content adjustments (for example, different installation procedures). +- **Team teaching**, where the lesson is presented by multiple (in most cases, two) teachers who actively engage in conversation with each other. The team-teaching concept is explained in more detail in the [CodeRefinery manual](https://coderefinery.github.io/manuals/team-teaching/). + +In reality, different forms are very often mixed or fused together, even within a single lesson. + +Co-teaching is not an online-only concept. However, it is very practical in online teaching due to larger number of instructors and learners potentially available to join a teaching session. + + +## Co-teaching and team teaching benefits + +- It **saves preparation time**. Co-teachers can rely on each other's strengths while creating/ revising the material as well as in unexpected situations during the lesson. +- It **helps with onboarding new instructors**. One of the co-teachers can be learning at the same time, either the subtleties of the material taught (in this case literally being the "voice of the audience") or the teaching process itself. +- Team teaching **looks more interactive and engaging** to the audience in many cases, without forcing the learners to speak up if they can't or don't want to do so. +- It also **ensures responsive feedback and less workload** by having more active minds. + + +### Are there any downsides? + +Not every learner and not every instructor might like the team-teaching approach. +- It might seem **less structured**, unprepared, and chaotic, even with preparation. + - It might create situations where instructors accidentally talk over each other or "interrupt" and change the flow of the lesson. + - For some instructors it can be stressful to not know in advance what questions they get asked from the co-instructor. + - Sometimes when an unexpected question is asked that throws the other instructor off, it can add to the feeling of chaos and unpreparedness. +- It can be interactive and engaging but it can also end up awkward if the co-teachers don't have a good synergy. + - Can sound awkward: Main instructor talking all the time and at the end asking co-instructor whether everything is clear and co-instructor only saying "yes". + - Possibly more engaging: Co-instructor asking questions which help with the flow and a common understanding of the material. + + +## Team teaching specifics + +- For successful team teaching, additional **coordination** is needed, first of all to agree on the teaching model (see below) and the person in control (the **director**) for the lesson or its parts. +- It's useful to keep track of the **lecture plan**. The discussion is a good way to make lesson more interactive and adjust to the audience, but deviating too much will become disorienting (for example, if someone dropped their attention for a minute and now is trying to catch-up by reading lecture notes). +- Experienced solo teacher might have a habit to keep talking (lecturing), while the co-teacher might not want to "interrupt". Therefore, it is important for the leading presenter to anticipate and **allow for remarks/ questions**, and this can be different from one's previous teaching style at first. + + +## Team teaching models + +We propose two basic models, but of course there is a constant continuum. + + +### Guide and demo-giver + +One person serves the role of **guide**, explaining the big picture and context of the examples. + +Another, the **demo-giver**, +- shows the typing and does the examples, +- might take the role of a learner who is asking about what is going on, to actually explain the details, or to comment occasionally. + +Hands-on demos and exercises work especially well like this. + + +### Presenter and interviewer + +In this case, one is the **presenter** who is mostly explaining (including demos or examples), and trying to move the forward through the material. + +Another, the **interviewer**, +- serves as a learner or spotter, +- fills in gaps by asking relevant questions, +- tries to comment to the presenter when things are going off track. + +This can be seen as closer to classical teaching, but with a dedicated and prepared "voice of the audience". + + +### Exercise + +:::{exercise} Discuss the models of team teaching (10 min) +While in breakout rooms, discuss one of the basic team-teaching models presented here: +- Have you already tried this or similar model in your teaching? +- Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best? + +Write your comments in the collaborative document. +::: + + +## Summary + +:::{keypoints} +- Co-teaching focuses on complementing individual skills and strengths in teaching process. +- Co-teaching may save time, reduce teachers' workload and make lessons more interactive/ engaging. +- Team teaching requires some adjustments in lesson preparation and delivery. +::: diff --git a/branch/cff/_sources/coderefinery-intro.md.txt b/branch/cff/_sources/coderefinery-intro.md.txt new file mode 100644 index 0000000..50d108c --- /dev/null +++ b/branch/cff/_sources/coderefinery-intro.md.txt @@ -0,0 +1,116 @@ +# About the CodeRefinery project and CodeRefinery workshops in general + +:::{objectives} +- Discuss what CodeRefinery is and how we got here +- Understand about the challenges to define our target audience +::: + +CodeRefinery is a +[Nordic e-Infrastructure Collaboration (NeIC)](https://neic.no/) +project that has started in October 2016 and is currently +funded until February 2025. We are working on the continuation plans. + +The funding from 2022-2025 is designed to keep this project active +beyond 2025 by forming a support network and building a community of +instructors and contributors. + + +:::{discussion} History +The CodeRefinery project idea grew out of two [SeSE](http://sese.nu) courses given at KTH Stockholm in 2014 and 2016. +The project proposal itself was submitted to NeIC in 2015, accepted in 2015, and started in 2016. + +We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form. +::: + + +## Goals + +- Develop and maintain **training material on good enough software development practices** for researchers that write code/scripts/notebooks. +- Our material addresses all academic disciplines and tries to be as programming language-independent as possible. +- Provide a [code repository hosting service](https://coderefinery.org/repository/) that is open and free + for all researchers based in universities and research institutes from Nordic countries. +- Provide **training opportunities** in the Nordics using (Carpentries and) CodeRefinery training materials. +- Evolve the project towards a **community-driven project** with a network of instructors and contributors. + + +## Community + +```{figure} img/community.png +Image showing the key areas of the CodeRefinery community: Workshops, chat inlcuding help channel, online meetings and co-working, +other collaborative training, eg on High Performance Computing topics. +``` + +CodeRefinery is not just workshops, we are community and want you to be part of it! + +There are many different levels of involvement, from the occasional commenter in chat, +CodeRefinery ambassador (people who like the project and workshops and help us spreading the word) or lesson issue creators and lesson contributors to +local host, co-instructor or co-organizer. + +Best **first step** in any case is to join the [CodeRefinery Zulip chat](https://coderefinery.zulipchat.com) +or let us know about your interest at support@coderefinery.org. + + +## Target audience + +One common question we get is how do we relate to [the Carpentries](https://carpentries.org). +This section describes how we see it: + + +### Carpentries audience + +The Carpentries aims to teach computational **competence** to learners through an applied approach, +avoiding the theoretical and general in favor of the practical and specific. + +**Mostly, learners do not need to have any prior experience in programming.** +One major goal of a Carpentries workshop is to raise awareness on the tools researchers can learn/use to speed up their research. + +By showing learners how to solve specific problems with specific tools and providing hands-on practice, +learners develops confidence for future learning. + +:::{admonition} Novices +We often qualify Carpentries learners as **novices**: they do not know what they need to learn yet. +A typical example is the usage of version control: the Carpentries lesson +[Version Control with Git](https://swcarpentry.github.io/git-novice/) +aims to give a +very high level conceptual overview of Git but it does not explain how it can be used in research projects. +::: + + +### CodeRefinery audience + +In that sense, CodeRefinery workshops differ from Carpentries workshops as we assume +our audience already writes code and scripts and we aim at teaching them **best software practices**. + +Our learners usually do not have a good overview of **best software practices** but are aware of the need to learn them. +Very often, they know of the tools (Git, Jupyter, etc.) we are teaching +but have difficulties to make the best use of them in their software development workflow. + +Whenever we can, we direct learners that do not have sufficient coding experience to Carpentries workshops. + +:::{admonition} Competent practitioners +We often qualify CodeRefinery learners as **competent practitioners** because they already have an understanding of their needs. +::: + +:::{discussion} Challenges related to defining our target audience +We often get the feedback "I wish I would have known X earlier!" +*Competent practitioners* have run into issues with **not** caring (or not fully understanding) +about version control, documentation, modularity, reproducibility before, so they are easily motivated to learn more. + +For a *novice* these topics may seem unnecessary and "too much" and the workshop may feel too difficult to follow. +However, the materials are designed so that one can always revisit a topic, when needed. +The important part is that you know that "X" exists, and where to find more information, which is also beneficial for novices. +::: + +--- + +:::{keypoints} Keypoints: CodeRefinery +- Teaches intermediate-level software development tool lessons +- It is difficult to define "best practices", we try to teach **"good enough" practices** +- Training network for other lessons +- Publicly-funded discrete projects (3 projects actually) transitioning towards an open community project +- We have online material, teaching, and exercise sessions +- Our main target audience are competent practitioners, but also novices and experts can get something out of the workshops +- We want more people to work with us, and to work with more people +::: diff --git a/branch/cff/_sources/collaborative-notes.md.txt b/branch/cff/_sources/collaborative-notes.md.txt new file mode 100644 index 0000000..15f84b3 --- /dev/null +++ b/branch/cff/_sources/collaborative-notes.md.txt @@ -0,0 +1,333 @@ +(collaborative-notes)= + +# Collaborative notes + +:::{objectives} +- Be able to provide a highly interactive online workshop environment with collaborative documents +::: + +:::{instructor-note} +- Teaching: 10 min +- Exercise: 15 min +- Questions & Answers: 5 min +::: + +## Introduction + +The Collaborative document is how you interact with the participants. +The participants can ask questions and give feedback through the collaborative +document. During a CodeRefinery session there can be a large a volume of questions. +A dedicated person, a Collaborative document-manager, is needed to answer and edit the collaborative document. +Let us see how the collaborative document is used, then discuss the role of +the editor or collaborative document-manager. + +## Collaborative document mechanics and controls +Technologies that can be used as a collaborative document are [Hackmd](https://hackmd.io), [HedgeDoc](https://hedgedoc.org), +or [Google Docs](https://www.google.com/docs/about/) + +[Hackmd](https://hackmd.io) or [HedgeDoc](https://hedgedoc.org/) are real-time text editor online. We use it to: +* As a threaded chat, to **answer questions and provide other information** without + interrupting the main flow of the room. +* provide everyone with a **more equal opportunity to ask questions**. +* **create notes** which will be archived, for your later reference. + +You do not need to login/create an account to be able to edit the document. + +### Basic controls + +```{figure} img/hackmd--controls.png + +This may look slightly different on mobile devices and small windows. +``` + +- At the top (left or right), you can switch between **view**, + **edit**, and **split view and edit** modes. + +- You write in [markdown](https://commonmark.org/help/) here. Don't + worry about the syntax, just see what others do and try to be like + that! Someone will come and fix any problems there may be. + +- Please go back to view mode if you think you won't edit for a + while - it will still live update. + + +### Asking questions + +**Always ask questions and add new sections at the very bottom**. +You can also answer and comment on older questions, too. + +```{figure} img/hackmd--questions2.png + +Questions and answers in bullet points +``` + +Since we plan to publish the questions and answers later as part +of the workshop page, we recommend to not use any names. You can indicate +your own name to make it easier to discuss more during the workshop but +then always use this form: `[name=Myname]`. This makes it easier for +us to automatically remove all names before publishing the notes. + +Other hints: + +- Use `+1` to agree with a statement or question (we are more likely + to comment on it). + +- Please leave some blank lines at the bottom + +- NOTE: Please don't "select all", it highlights for everyone and adds a + risk of losing data (there are periodic backups, but not instant). + +- It can be quite demanding to follow the collaborative document closely. Keep an eye + on it, but consider how distracted you may get from the course. For + things beyond the scope of the course, we may come back and answer + later. + + +### Don't get overwhelmed + +There can be a flood of information on the collaborative document. Scan for what is +important, then if you would like come back later. But it is +important to keep checking it. + + +### Privacy + +- Assume the collaborative document is **public and published: you never + need to put your name there**. + +- The collaborative document will be **published on the website afterwards**. We will + remove all non-instructors names, but it's easier if you don't add + it there in the first place. + +- Please keep the link private during the workshop, since since + security is "editable by those who have the link". + +- You can use `[name=YOURNAME]`, to name yourself. We *will* remove + all names (but not the comments) before archiving the notes (use + this format to make it easy for us). + +## Exercise + +:::{exercise} Discuss how to collaborate and handle questions (15 min) +Write down your conclusions in the shared document. Items to discuss are: +- What is your experience with questions and discussions while teaching? +- How do you deal with them? +- What kind of technologies do you prefer: chat, shared document, or voices + and discussion raised during instruction? And why? +::: + +## Collaborative Document Manager + +We have one person who is a "Collaborative Document helper". This isn't the only +person that should edit and answer, but one person shouldn't have too +much else on their mind so can focus on it. They also make sure that +the collaborative document is updated with exercise, break, and other meta-information to +keep people on track. + +Below, (*) = important. + +### Before the workshop + +* Create a new collaborative document for the workshop +* make sure that **editing is enabled for anyone without login** +* Add workshop information, links to the workshop page and material +and an example question and answer to the top of the collaborative document(see below) + +### Most things to edit (everyone) + +Make it easy to post after the course and consistent to follow: + +* Tag all names with `[name=XXX]` (so they can be removed later), + remove other personal data or make it obvious. +* Add in information on exercises (new section for them, link, end + time, what to accomplish) +* Make a logical section structure (`#` for title, `##` for sections, + `###` for episodes, etc. - or what makes sense) + + + +### General Collaborative Document practices + +```{figure} img/hackmd--full-demo.png +:align: right + +A live demo of a Collaborative Document during a Q&A time. The two instructors are +discussing some of the import answers. Multiple learners have asked +questions, multiple answers, and some remaining to be answered +``` + + + +Keep it formatted well: + +- (*) Tag names you see with `[name=XXX]` so that we can remove it + later. +- Heading level `#` is only the page title +- Add a new `##` heading when a new *lesson* or similar thing is + started (introduction, icebreaker, break between lessons, etc) +- Add a new `###` heading when a new *episode*, *exercise*, *break* + (within exercise session) +- Ensure people are asking questions at the bottom, direct them there + if they aren't. +- (*) Ensure each question is a bullet point. Each answer or follow-up + should be a bullet point below. + - Should you use more deeply nested bullet points, or have only one + level below the initial question? It depends on the context, but + if a conversation goes on too long, try not to let it go too + deep. + + +Update with meta-talk, so that learners can follow along easily: + +- Add Icebreaker and introductory material of the day. Try to talk to + people as they joined to get them to open the collaborative document and answer. +- Anything important for following along should not be only said via + voice. It needs to be in the collaborative document, too. +- New lessons or episodes, with links to them. +- For exercises, link to exercise and add the duration, end time, + goals. If these are unclear, bring it up to the instructor by voice. +- Add a status display about breaks. + + +Screenshare it when necessary: + +- During breaks and other times, share the collaborative document(including the + notification about break, and when it ends). +- It is nice if the arrangement allows some of the latest questions to + be seen, so people are reminded to ask there. +- Someone else may do this, but should make sure it happens. + +Answer questions + +- If there is an question that should be answered by the instructor by + voice, bring it up (by voice) to the instructor immediately. +- How soon do you answer questions? Two points of view: + - Answer questions right away: can be really intense to follow. + - Wait some so that we don't overload learners: reduces the info + flow. But then do people need to check back more often. + - You need to find your own balance. Maybe a quick answer right + away, and more detailed later. Or delay answers during the most + important parts of the lecture. +- Avoid wall-of-text answers. If reading an answer takes too long, it + puts the person (and other people who even try to read it) behind + even more by taking up valuable mental energy. If an answer needs a + wall of text, consider these alternatives: + - Progressive bullet points getting more detailed (first ones + useful alone for basic cases) + - Don't be worried to say "don't worry about this now, let's talk + later." + - Figure out the root problem instead of answering every possible + interpretation + - Declare it advanced and that you will come back later. + +Ensure it can be posted quickly: + +- The collaborative document gets posted to the workshop webpage. For this, it needs some + minimal amount of formatting (it doesn't need to be perfect, just + not horrible). +- All names and private information needs to be stripped. This is why + you should rigorously tag all names with `[name=XXX]` so they can be + removed (see above). + - Learner names can be completely removed. CR staff names can be + `[name=CR]` or something similar. + - There may be other private URLs at the top or bottom. + +- If possible, send the PR adding the collaborative document to the workshop webpage + (though others can do this, too). + + + +### Collaborative document format example + +``` +# Workshop, day 1 + + +## Lesson name +https://coderefinery.github.io/lesson/ + +### Episode name +https://coderefinery.github.io/01-episode/ + +- This is a question + - Anwser + - More detailed answer +- question + - answer + +### Exercises: +https://link-to-exercise/.../.../#section +20 minutes, until xx:45 +Try to accomplish all of points 1-3. Parts 4-5 are optional. + +Breakout room status: +- room 2, need help with Linux permissions +- room 5, done + +### Break +:::danger +We are on a 10 minute break until xx:10 +::: + + +## Lesson 2 +https://coderefinery.github.io/lesson-2/ + +``` + +### Posting the collaborative document to the website + +The collaborative document should be posted sooner rather than later, and hopefully the +steps above will make it easy to do so quickly. You could wait a few +hours, to allow any remaining questions to be asked an answered. + +- Download as markdown +- Remove any private links at the top +- Adjust headings so that they are reasonable +- Look for private info and remove it + - Search document for `[name=???]` (change to `[name=staff]` or + `[name=learner]`) + - Any names not tagged with `[name=]` + - usernames in URLs + - private links + +### Feedback template + +`````` +## Feedback, day N + +:::info +### News for day N+1 +- . +- . +::: + +### Today was (multi-answer): +- too fast: +- just right: +- too slow: +- too easy: +- right level: +- too advanced: +- I would recommend this course to others: +- Exercises were good: +- I would recommend today to others: +- I wouldn't recommend today: + +### One good thing about today: +- ... +- ... + +### One thing to be improved for next time: +- ... +- ... + +### Any other comments: +- ... +- ... +`````` +:::{keypoints} +- Having a collaborative document improves communication and interaction. +- Answering questions requires a dedicated person - A Collaborative Document Manager. +- The collaborative document should be posted on the web site as soon as possible. +::: diff --git a/branch/cff/_sources/computational-thinking.md.txt b/branch/cff/_sources/computational-thinking.md.txt new file mode 100644 index 0000000..943d9c8 --- /dev/null +++ b/branch/cff/_sources/computational-thinking.md.txt @@ -0,0 +1,25 @@ +(computational-thinking)= + +# Computational thinking + + +:::{objectives} +- Explain what is computational thinking +- Get to know how the theory of computational thinking can be used in teaching +- Short exercise +::: + +:::{instructor-note} +- Teaching: 20 min +- Exercises: 10 min +::: + + +Materials available as [slides](https://github.com/coderefinery/train-the-trainer/blob/main/content/computational_thinking.pdf). + + +:::{keypoints} +- Computational Thinking consists of 4 main parts: decomposition, pattern recognition, abstraction and algorithmic design. +- How can this be a useful framework for solving problems? +- How can this be used practically? +::: diff --git a/branch/cff/_sources/cool-gems.md.txt b/branch/cff/_sources/cool-gems.md.txt new file mode 100644 index 0000000..a4a6f5c --- /dev/null +++ b/branch/cff/_sources/cool-gems.md.txt @@ -0,0 +1,16 @@ +(cool-gems)= + +# Sharing teaching gems + +:::{objectives} +- Our goal is to share our teaching tricks and tools and demonstrate them in + very short presentations/discussions. +::: + +:::{instructor-note} +- Demonstrations: 35 min +::: + +Here we encourage participants to take the screen share for 3 minutes and +demonstrate either some tool or trick they found useful for their teaching or +something from a course you liked. diff --git a/branch/cff/_sources/feedback-and-impact.md.txt b/branch/cff/_sources/feedback-and-impact.md.txt new file mode 100644 index 0000000..698de4a --- /dev/null +++ b/branch/cff/_sources/feedback-and-impact.md.txt @@ -0,0 +1,200 @@ +# How we collect feedback and measure impact + +:::{objectives} +- Discuss how one can collect feedback from learners ("what can we improve?"). +- Discuss how we convert feedback into actionable items. +- Discuss how we measure the impact of teaching ("did we achieve our goals?"). +- Discuss the "why". +- Get to know the reasons and sources of inspiration behind major lesson and workshop updates. +::: + +:::{instructor-note} +- Discussion: 20 min +- Exercises: 10 min +::: + + +## Asking questions before the workshop + +- Motivation: Know your audience. +- Until 2021 we had a pre-workshop survey: + - Data, questions, and notebook: + - Zenodo/DOI: +- After 2021 we incorporated some of the questions into the registration form. + - Easier registration experience for participants. + - After 5 years of running workshops, we had a good idea of what to expect. + + +## Collecting feedback as we teach + +- Each day we ask for feedback in the collaborative notes. + - One good thing about today. + - One thing to improve for next time. + - Any other comments? +- During the workshop we sometimes check in and ask about the pace, example: + ``` + How is the speed so far? (add an "o") + - Too fast: oooooo + - Too slow: ooo + - Just right: ooooooooooooooooooo + ``` +- We publish all questions, answers, and feedback. Example: +- How we follow up: + - Some problems we can fix already before the next workshop day. + - We convert feedback/problems into GitHub issues and track these close to the lesson material. + + +## Trying to measure impact with longer-term surveys + +- Motivation: Understand the long-term impact of our workshops. Have something to show to funders. +- 2024 post-workshop survey: + - Blog post: + - Questions, notebook, and figures: + - Zenodo/DOI: +- 2021 version: + - Data, questions, notebook, and figures: + - Zenodo/DOI: +- How we use the results: + - When reporting to funders. + - When planning future workshops and bigger picture changes. + + +## Lessons learned + +- Think about how to measure impact/success from the beginning. +- **Make the feedback and survey results public**. +- Make the results persistent and citable. +- Have a mechanism to follow-up on feedback. +- Anonymization is more than just removing or dissociating names. +- Take time designing your survey and collect feedback on the survey itself. + + +## Take time designing your survey + +We are not experts in survey design but we reached out to RISE Research +Institutes of Sweden to get feedback on our survey questions. They provided us +with a lot of valuable feedback and suggestions for improvements. +Below are few examples. + + +### Example 1 + +First version of our survey question about impact: +- "Do our workshops help to save time in future?" Please quantify in hours saved: ... + +Feedback: +- Difficult to answer. +- Since when? Until all eternity? + +```{figure} feedback-and-impact/survey-impact1.png +:width: 80% +:class: with-border +:alt: Screenshot of earlier version of the survey question about impact. + +Earlier version of the survey question about impact. +``` + +Feedback: +- The question "Do our workshops help to save time in future?" is unspecified, + unnecessary, and leading. +- "No time saving" does not match the wording "save time" in the question. + +```{figure} feedback-and-impact/survey-impact2.png +:width: 80% +:class: with-border +:alt: Screenshot of later version of the survey question about impact. + +Later version of the survey question about impact. +``` + +- The wording "have you saved" now matches "No time saved". + + +### Example 2 + +- Earlier version: + ``` + Would you judge your code to be better reusable/reproducible/modular/documented + as a result of attending the workshop? + + - More reusable + - More reproducible + - More modular + - Better documented + - None of the above + ``` +- Feedback: The question is not neutrally formulated and risks leading to + over-reporting of yes answers. Consider balancing so that the questions are + formulated more neutrally. +- Reformulated to: + ``` + After attending the workshop, would you judge your code to be + more reusable or not more reusable? + + - My code is more reusable + - My code is not more reusable + - Not sure + ``` + + +### Example 3 + +- Early version: + ``` + What else has changed in how you write code since attending the workshop? + + [free-form text field] + ``` +- Feedback: Leading and assumes that something has changed. +- Reformulated to: + ``` + Has anything else changed in how you write code for your research after + attending the workshop? + + [free-form text field] + ``` + + +### Example 4 + +- Earlier version: + ``` + Has it become easier for you to collaborate on software development with your + colleagues and collaborators? + + - Yes + - Not sure + - No + ``` +- Feedback: + - Leading question. + - Avoid "Yes" and "No" response options because respondents tend to answer + "Yes" if that option is available, leading to a risk of measurement error + (acquiescence bias). + - Do not place "Not sure" in the middle of the scale because it captures + participants who actually don't know and should therefore be placed at the + bottom instead of in the middle of the scale. +- Reformulated to: + ``` + After attending the workshop, has it become easier or not for you to + collaborate on software development with your colleagues and collaborators? + + - Collaboration is easier + - Collaboration is not easier + - Not sure + ``` + + +## Exercise: Group discussion (10 min) + +:::{exercise} Group discussion using the collaborative notes +- What tricks/techniques have you tried in your teaching or seen in someone + else's teaching that you think have been particularly effective in collecting + feedback from learners? +- Can you give tips or share your experiences about how to convert feedback + into actionable items? +- How do you measure the impact of your teaching? Any tips or experiences about + what you have tried or seen other courses do? +- Anybody knows of good resources on survey design? Please link them in + the collaborative notes. +::: diff --git a/branch/cff/_sources/guide.md.txt b/branch/cff/_sources/guide.md.txt new file mode 100644 index 0000000..88e078a --- /dev/null +++ b/branch/cff/_sources/guide.md.txt @@ -0,0 +1,53 @@ +# Instructor guide + + +## Target audience + +- Everyone teaching online workshops about computational topics or interested in teaching. +- Previous and future instructors and helpers of CodeRefinery workshops. + + +## Timing + +**Session 1** +- 15 min: Intro +- 45 min: Lesson design and development +- 15 min: Break +- 45 min: Lesson template +- 15 min: Break +- 30 min: How we collect feedback and measure impact +- 10 min: Outro and feedback + +**Session 2** +- 15 min: Intro +- 10 min: About the CodeRefinery project and CodeRefinery workshops in general +- 30 min: Collaborative notes and interaction +- 15 min: Break +- 35 min: Workshop overview, roles, onboarding/installation, helpers +- 20 min: Sound +- 15 min: Break +- 30 min: Screenshare +- 10 min: Outro and feedback + +**Session 3** +- 15 min: Intro +- 30 min: Computational thinking +- 15 min: Break +- 30 min: Teaching philosohies +- 30 min: Co-teaching +- 15 min: Break +- 35 min: Sharing teaching tips, tricks, tools etc +- 10 min: Outro and feedback + +**Session 4** +- 15 min: Intro +- 10 min: Why we stream +- 20 min: Behind the stream +- 15 min: Video editing (part 1) +- 15 min: Break +- 25 min: Video editing (part 2, exercise) +- 20 min: OBS introduction +- 15 min: Break +- 30 min: OBS setup +- 15 min: What's next? + diff --git a/branch/cff/_sources/index.md.txt b/branch/cff/_sources/index.md.txt new file mode 100644 index 0000000..6adb709 --- /dev/null +++ b/branch/cff/_sources/index.md.txt @@ -0,0 +1,122 @@ +# Train the trainer workshop + +::::{admonition} August/September 2024 CodeRefinery train the trainer workshop + +Do you teach the use of computers and computational tools? Are you curious about scaling your training and learn about tested and proven practices from CodeRefinery workshops and other trainers? Join us for the CodeRefinery train the trainer workshop: four self-contained sessions on tools and techniques for computational training offer a great chance to enhance your teaching skills and learn about new tools and practices. What you will learn is also used a lot outside CodeRefinery, whenever good beginner friendly training is needed. + +**Learning objectives:** +- Learn about tools and techniques and practice to create engaging online teaching experiences (screenshare, audio, etc.). +- Become mentally ready to be an instructor in a collaborative interactive online workshop (not only large workshops but in general). +- Learn how to design and develop lesson material collaboratively. + +**Target audience:** +- Everyone teaching online workshops about computational topics or interested in teaching. +- Previous and future instructors and helpers of CodeRefinery workshops. + +**Prerequisites:** +An interest in teaching. + +**Workshop structure:** +We aim for a mix of modular presentations and work in small groups. The latter will be done in breakoutrooms - +be prepared to switch on your camera and have a fruitful exchange with fellow participants! + +**Organizers and instructors:** + +The workshop is organized by [partner organizations of the CodeRefinery project](https://coderefinery.org/about/partners/). + +Facilitators and instructors: + +- Radovan Bast +- Richard Darst +- Bjørn Lindi +- Dhanya Pushpadas +- Jarno Rantaharju +- Stephan Smuts +- Stepas Toliautas +- Samantha Wittke + + +**Content and timing:** + +The workshop consists of four sessions every Tuesday between August +13th and September 3rd 2024, +{localtime}`09:00 13 August 2024 +02:00 (HH:mm)` to +{localtime}`12:00 13 August 2024 +02:00 (HH:mm z/zzz)`: + +- Session 1: About lesson design, deployment and iterative improvement (Aug 13) +- Session 2: Tools and techniques adopted in CodeRefinery workshops (Aug 20) +- Session 3: About teaching & cool things we all would like to share (Aug 27) +- Session 4: Workshop streaming practices and post-workshop tasks (Sep 3) + +You can join all sessions, or the just the ones that interest you. More details on each session will be shared later. + +The workshop is **free of charge for everyone**, please register below to get the Zoom link and other useful information for the workshop. + +The workshop is over and registration is closed now. + +If you have any questions, please write to . +:::: + +```{admonition} +You can find materials of previous similar trainings using the links below: + +- First version of the course in 2019 and then in 2020: + +- Reworked material for our summer workshop 2022 and +for the CarpentryCon 2022 workshop: + +``` + +```{toctree} +:maxdepth: 1 +:caption: Session 1 + +lesson-development +lessons-with-git +feedback-and-impact +``` + +```{toctree} +:maxdepth: 1 +:caption: Session 2 + +coderefinery-intro +collaborative-notes +overview +sound +screenshare +``` + +```{toctree} +:maxdepth: 1 +:caption: Session 3 + +computational-thinking +teaching-philosophies +co-teaching +cool-gems +``` + +```{toctree} +:maxdepth: 1 +:caption: Session 4 + +session-4-intro +why-we-stream +streaming +video-editing +obs +obs-config +streaming-whats-next +``` + +```{toctree} +:maxdepth: 1 +:caption: Resources + +notes-archive +guide +All lessons +CodeRefinery +Reusing +``` diff --git a/branch/cff/_sources/lesson-development.md.txt b/branch/cff/_sources/lesson-development.md.txt new file mode 100644 index 0000000..76e79bf --- /dev/null +++ b/branch/cff/_sources/lesson-development.md.txt @@ -0,0 +1,204 @@ +(lesson-design)= + +# Lesson design and development + +:::{objectives} +- We share our design processes for teaching material and presentations. +- Learn how to design lessons "backwards", starting from learning objectives + and learner personas. +- Learn good practices for improving existing material based on feedback. +::: + +:::{instructor-note} +- Discussion: 20 min +- Exercises: 35 min +::: + + +## Exercise: How do you design your teaching material? + +:::{exercise} We collect notes using a shared document (5 min) +- When you start preparing a new lesson or training material, where do you start? +- What tricks help you with "writer's block" or the empty page problem? +- Maybe you haven't designed training material yet. But how do you start when creating a new presentation? +- If your design process has changed over time, please describe what you used to do and what you do now instead. +- What do you know now about preparing lessons/training/presentations that you wish you knew earlier? +::: + + +## Creating new teaching material + + +### Typical problems + +- Someone creates a lesson, but they think about what is interesting to them, + not what is important for the learners. +- "I want to show a number of things which I think are cool about + tool X - how do I press these into 90 minutes?" +- Write down material you want to cover and then sprinkle in some exercises. +- Thinking about how I work, not how the learners work. +- Trying to bring learners to their level/setup, not trying to meet the learners + where they are. +- Not really knowing the learning objectives or the learner personas. + + +### Better approach + +Good questions to ask and discuss with a group of colleagues **from diverse backgrounds**: +- What is the expected educational level of my audience? +- Have they been already exposed to the technologies I am planning to teach? +- What tools do they already use? +- What are the main issues they are currently experiencing? +- What do they need to remember/understand/apply/analyze/evaluate/create + ([Bloom's taxonomy](https://en.wikipedia.org/wiki/Bloom%27s_taxonomy))? +- Define learner personas. +- It may be an advantage to share an imperfect lesson with others early to + collect feedback and suggestions before the lesson “solidifies” too much. + Draft it and collect feedback. The result will probably be better than + working in isolation towards a "perfect" lesson. + + +### The process of designing a lesson "backwards" + +As described in ["A lesson design process" in the book Teaching Tech +Together](https://teachtogether.tech/en/index.html#s:process): + +1. Understand your learners. +1. Brainstorm rough ideas. +1. Create an summative assessment to know your overall goal. + > [Think of the things your learners will be able to do at the end of the lesson] +1. Create formative assessments to go from the starting point to this. + > [Think of some engaging and active exercises] +1. Order the formative assessments (exercises) into a reasonable order. +1. Write just enough material to get from one assessment (exercise) to + another. +1. Describe the course so the learners know if it is relevant to them. + + +## Improving existing lessons + +:::{discussion} All CodeRefinery lessons are on GitHub +- Overview: +- All are shared under CC-BY license and we encourage [reuse and modification](https://coderefinery.org/lessons/reusing/). +- Sources are all on GitHub: +- Web pages are generated from Markdown using [Sphinx](https://www.sphinx-doc.org/) + (more about that in the episode {ref}`lessons-with-git`). +- We track ideas and problems in GitHub issues. +::: + +Collect feedback during the workshop: +- Collect feedback from learners and instructors ([Example from a past + workshop](https://coderefinery.github.io/2024-03-12-workshop/questions/)). +- Convert feedback about lessons and suggestions for improvements into issues + so that these don't get lost and stay close to the lesson material. + +Collect feedback before you start a big rewrite: +- First open an issue and describe your idea and collect feedback before you + start with an extensive rewrite. +- For things still under construction, open a draft pull/merge request to collect + feedback and to signal to others what you are working on. + +Small picture changes vs. big picture changes: +- Lesson changes should be accompanied with instructor guide changes (it’s like + a documentation for the lesson material). +- Instructor guide is essential for new instructors. +- Before making larger changes, talk with somebody and discuss these changes. + + +## Use case: our lessons + +As an example to demonstrate the process of designing and improving lessons, we +will have a look at one of our own lessons: [Introduction to version control +with Git](https://coderefinery.github.io/git-intro/). + +- Initial 2014-2016 version + - and + - Amazingly they are still findable! + - Format: Slides and live coding. + - Exercises were separate, during afternoon sessions. +- Some time in 2014-2015 attended Carpentries instructor training. +- 2016: CodeRefinery started. +- 2017: Started a new repository based on the Carpentries lesson template (at the time using Jekyll). + - Exercises become part of the lesson. + - We start in the **command line** and only later move to GitHub. +- 2019: A lot more thought about learning objectives and personas. + - Also license change to CC-BY. +- 2022: Convert lesson from Jekyll to Sphinx. + - Using the tools that we teach/advocate. + - We can have tabs and better code highlighting/emphasis. + - Easier local preview (Python environment instead of Ruby environment which we were not used to in our daily work). +- 2024: Big redesign. We move the lesson closer to where learners are. + - Start from GitHub instead of on the command line. + - Start from an existing repository instead of with an empty one. + - Offer several tracks to participate in the lesson (GitHub, VS Code, and command line) and learners can choose which one they want to follow. + - Blog post: [We have completely changed our Git lessons. Hopefully to the better.](https://coderefinery.org/blog/2024/04/19/git-lesson-rewrite/) +- Next steps? + - Making the lesson citable following + [our blog post](https://coderefinery.org/blog/2024/07/30/lesson-cffs/). + - Improvements based on what we learn from this workshop. + +The overarching trend was to make the lesson simpler and more accessible - to +meet the learners where they are instead of pulling them to the tool choices of +the instructors. Looking back, we learned a lot and the learning process is +not over yet. + + +## Exercise: Discussion about learning objectives and exercise design + +:::{exercise} We work in groups but use the shared document as result (20 min) +1. As a group **pick a lesson topic**. It can be one of the topics listed here but + you can also choose something else that your group is interested in, or a topic + that you have taught before or would like to teach. Some suggestions: + - Git: Creating a repository and porting your project to Git and GitHub + - Git: Basic commands + - Git: Branching and merging + - Git: Recovering from typical mistakes + - Code documentation + - Jupyter Notebooks + - Collaboration using Git and GitHub/GitLab + - Using GitHub without the command line + - Project organization + - Automated testing + - Data transfer + - Data management and versioning + - Code quality and good practices + - Modular code development + - How to release and publish your code + - How to document and track code dependencies + - Recording environments in containers + - Profiling memory and CPU usage + - Strategies for parallelization + - Conda environments + - Data processing using workflow managers + - Regular expressions + - Making papers in LaTeX + - Making figures in your favorite programming language + - Linux shell basics + - Something non-technical, such as painting a room + - Introduction to high-performance computing + - A lesson you always wanted to teach + - ... +1. Try to define 2-3 learning objectives for the lesson and write them down. + You can think of these as "three simple enough messages that someone will + remember the next day" - **they need to be pretty simple**. +1. Can you come up with one or two engaging exercises that could be used to + demonstrate one of those objectives? + **They should be simple** enough people can actually do them. Creating simple exercises is not easy. + Some standard exercise types: + - Multiple choice (easy to get feedback via a classroom tool - try to design each wrong answer so that it identifies a specific misconception). + - Code yourself (traditional programming) + - Code yourself + multiple choice to see what the answer is (allows you to get feedback) + - Inverted coding (given code, have to debug) + - Parsons problems (working solution but lines in random order, learner must only put in proper order) + - Fill in the blank + - Discussions, self directed learning exercises +::: + + +## Great resources + +- [Teaching Tech Together](http://teachtogether.tech/) +- [Our summary of Teaching Tech Together](https://coderefinery.github.io/manuals/teaching-tech-together/) +- [Ten quick tips for creating an effective lesson](https://doi.org/10.1371/journal.pcbi.1006915) +- [Carpentries Curriculum Development Handbook](https://cdh.carpentries.org/) +- [Our manual on lesson design](https://coderefinery.github.io/manuals/lesson-design/) diff --git a/branch/cff/_sources/lessons-with-git.md.txt b/branch/cff/_sources/lessons-with-git.md.txt new file mode 100644 index 0000000..f91a0e9 --- /dev/null +++ b/branch/cff/_sources/lessons-with-git.md.txt @@ -0,0 +1,217 @@ +(lessons-with-git)= + +# Lessons with version control + +:::{objectives} +- Understand why version control is useful even for teaching material +- Understand how version control managed lessons can be modified. +- Understand how the CodeRefinery lesson template is used to create new lessons +::: + +:::{instructor-note} +- Discussion: 25 min +- Exercises or demos: 20 min +::: + + +## Why version control? + +- If you are in CodeRefinery TTT, you probably know what version + control is and why it is important. +- The benefits of version control also extend to lessons: + - Change history + - Others can submit contributions + - Others can make derived versions and sync up later + - Same workflow as everything else + - Write it like documentation: probably more reading after than + watching it as a presentation. +- Disadvantages + - "What you see is what you get" editing is hard + - Requires knowing version control + +:::{discussion} Accepting the smallest contribution + +Question: if someone wants to make a tiny fix to your material, can they? +::: + +## Tour of lesson templates options + +There are different ways to make lessons with git. Some dedicated to +teaching: + +- CodeRefinery + - Example: This lesson itself + - Based on the Sphinx documentation generator + - [sphinx-lesson](https://github.com/coderefinery/sphinx-lesson) is + *very* minimal extra functionality +- Carpentries + - Example: + - Based on R and Rmarkdown + +Our philosophy is that anything works: it doesn't have to be just +designed for lessons + +- Jupyter Book + - Example: https://jupyterbook.org/ + - Note: is based on sphinx, many extensions here are used in CR lessons +- Various ways to make slides out of Markdown +- Cicero: GitHub-hosted Markdown to slides easily + - [Demo: Asking for Help with + Supercomputers](https://cicero.xyz/v3/remark/0.14.0/github.com/bast/help-with-supercomputers/main/talk.md/#1) + [The source](https://github.com/bast/help-with-supercomputers/blob/main/talk.md) +- Whatever your existing documentation is. + +**We like the CodeRefinery format, but think that you should use +whatever fits your needs the most.** + + +## [Sphinx](https://www.sphinx-doc.org) + +- We build all our lesson material with Sphinx +- Generate HTML/PDF/LaTeX from RST and Markdown. +- Many Python projects use Sphinx for documentation but **Sphinx is not limited to Python**. +- [Read the docs](https://readthedocs.org) hosts public Sphinx documentation for free! +- Also hostable anywhere else, like Github pages, like our lesson material +- For code a selling point for Sphinx is that also API documentation + is possible. + +Sphinx is a doc generator, not HTML generator. It can: + +- Markdown, Jupyter, and ReST (and more...) inputs. Executable inputs. + - jupyter-book is Sphinx, so anything it can do we can do. This was one of the + inspirations for using Sphinx +- Good support for inline code. Much more than static code display, if + you want to look at extensions. +- Generate different output formats (html, single-page html, pdf, epub, etc.) +- Strong cross-referencing within and between projects + + +## [CodeRefinery lesson template](https://github.com/coderefinery/sphinx-lesson-template) + +It is "just a normal Sphinx project" - with extensions: +- [Sphinx lesson extension](https://github.com/coderefinery/sphinx-lesson) + - adds is various directives (boxes) tuned to lesson purposes + - provides a sample organization and template repo you can use so that lessons look consistent +- Sphinx gives us other nice features for free + - Tabs: they are very important for us and allow us to customize in-place instead of copying everything and fragmenting lessons + - Emphasize lines: they make it easier to spot what has changed in longer code snippets + - Various input formats + - Markdown (via the MyST-parser), ReStructured text, Jupyter + Notebooks. + - Many other features designed for presenting and interacting with code +- It's fine if you use some other static site generator or git-based lesson method. + +:::{demo} Instructors go through the building and contributing process + +Depending on the course, instructors will demo what is roughly +exercise 4 below. Or a course might go straight to exercises. + +- Instructors decide what change they would want to make +- Instructors clone the repository +- **Instructors make the change** +- **Instructors set up the build environment** +- **Instructors build and preview** +- Instructors command and send upstream +::: + + +## Exercises + +Some exercises have prerequisites (Git or Github accounts). Most +instances of this course will have you do **1 and 2** below. + +:::{exercise} Lesson-VCS-1: Present and discuss your own lesson formats + +We don't want to push everyone towards one format, but as long as you +use Git, it's easy to share and reuse. + +- Discuss what formats you do use +- Within your team, show examples of the lessons formats you use + now. Discuss what is good and to-be-improved about them. +- Look at how they source is managed and how easy it might be to edit. +::: + + +:::{exercise} Lesson-VCS-2: Tour a CodeRefinery or Carpentries lesson on Github +- Look at either a CodeRefinery or Carpentries lesson + - CodeRefinery Git-Intro: [Lesson](https://coderefinery.github.io/git-intro/), [Github repo](https://github.com/coderefinery/git-intro) + - Carpentries Linux shell: [Lesson](https://swcarpentry.github.io/shell-novice/), [Github repo](https://github.com/swcarpentry/shell-novice/) +- Can you find + - Where is the content of the lessons? + - What recent change propsals (pull requests) have been made? + - What are the open issues? + - How you would contribute something? + - How would you use this yourself? +::: + + +:::{exercise} Lesson-VCS-3: Modify a CodeRefinery example lesson on Github +In this, you will make a change to a lesson on Github, using only the +Github interface. (Github account required, and we assume some +knowledge of Github. Ask for help in your team if it is new to you!) + +- Navigate to the example lesson we have set up: + [repo](https://github.com/coderefinery/sphinx-lesson-scratch-space), [web](https://coderefinery.github.io/sphinx-lesson-scratch-space/) +- Go to some page and follow the link to go to the respective page on + Github. (Alternatively, you can find the page from the Github repo directly). +- Follow the Github flow to make a change, and open a Pull Request + with the change proposal: + - Click on the pencil icon + - Make a change + - Follow the flow to make a commit and change. You'll fork the + repository to make your own copy, add a message, and open a pull + request. + +We will look at these together and accept some changes. +::: + + +:::{exercise} Lesson-VCS-4: Clone and build a CodeRefinery lesson locally +In this exercise, you will use Git to clone one a CodeRefinery lesson +and try to preview it locally. It assumes installation and knowledge +of Git. + +- Use this sample repository: + [git-intro](https://github.com/coderefinery/git-intro) (or whatever + else you would like) +- Clone the repository to your own computer +- Create a virtual environment using the ``requirements.txt`` + contained within the repository. +- Build the lesson. + - Most people will probably run: `sphinx-build content/ _build/` + - If you have `make` installed you can `make html` + - Look in the `_build` directory for the built HTML files. + +Overall, this is pretty easy and straightforward, if you have a Python +environment set up. The [CodeRefinery documentation +lesson](https://coderefinery.github.io/documentation/sphinx/) teaches +this for every operating system. + +This same tool can be used to build documentation for other software +projects and is pretty standard. +::: + + +:::{exercise} Lesson-VCS-5: (advanced) Create your own lesson using the CodeRefinery format +In this lesson, you'll copy the CodeRefinery template and do basic +modifications for your own lesson. + +- Clone the lesson template: + https://github.com/coderefinery/sphinx-lesson-template +- Attempt to build it as it is (see the previous exercise) +- How can you do tabs? +- How can you highlight lines in code boxes? +- How can you change color, logo and fonts? +- What directives are available? + +::: + + +## Summary + +:::{keypoints} +- Version control takes teaching materials to the next level: + shareable and easy to contribute +- There are different formats that use version control, but we like + Sphinx with a sphinx-lesson extension. +::: diff --git a/branch/cff/_sources/notes-archive.md.txt b/branch/cff/_sources/notes-archive.md.txt new file mode 100644 index 0000000..178256f --- /dev/null +++ b/branch/cff/_sources/notes-archive.md.txt @@ -0,0 +1,1605 @@ +# Collaborative notes archives from workshops + +## August/September 2024 + +### Day1: Session 1 (13.08.24) - About lesson design, deployment and iterative improvement + +#### :calendar: Schedule + +| Time (CEST) | Title | EEST (UTC+3) | BST (UTC+1) | +|---------------|--------------------------------------------|---------------|---------------| +| 8.45 - 9.00 | Connecting time | 9.45 - 10.00 | 7.45 - 8.00 | +| 9.00 - 9.15 | Intro and Icebreaker | 10.00 - 10.15 | 8.00 - 8.15 | +| 9.15 - 10.00 | Lesson design and development | 10.15 - 11.00 | 8.15 - 9.00 | +| 10.00 - 10.15 | Break | 11.00 - 11.15 | 9.00 - 9.15 | +| 10.15 - 11.00 | Lessons with version control | 11.15 - 12.00 | 9.15 - 10.00 | +| 11.00 - 11.15 | Break | 12.00 - 12.15 | 10.00 - 10.15 | +| 11.15 - 12.00 | How we collect feedback and measure impact | 12.15 - 13.00 | 10.15 - 11.00 | + +#### :icecream: Icebreaker + +##### Check-in + +Which emoji best describes your current state of mind? [Emoji cheat sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) +- :Decaffed ... and going strong ... +- :coffee: 🤔 +- :100: (ironically!) :coffee: intake happening +- :smile: +- :tired_face: +- :coffee: :party: +- :coffee: :happy: +- 😪 +- just got zoom installed / before my coffee +- :smil- +- :sweat_smile: (+) +- :yawning_face: +- :is it morning already? +- :smile: +- :yawning_face: +- :nerded_face: +- 🥵 +- :smile: +- :sleeping: +- :sleepy: :coffee: :smiley_cat: +- 🥳 +- :coffee: +- :coffee: + +##### Introduction in breakoutrooms. + +- Name / Affiliation / Location + +##### About teaching + +What is the hardest thing about teaching for you? +- Knowing how "it's going", whether learners are happy or not (especially when teaching online) :+1: +- The preparation the night before. It is always much more that I would hope, no matter how prepared I want it to be :+1: :+1: +- Managing groups with vastly different academic backgrounds +- Teaching wide spectrum of skill level at the same time. :+1: :+1: :+1: :+1: +- Time management! (Knowing how much can fit in a sessions) :+1: :+1: +- General preparation time, how to fit it into the regular work schedule, and estimate how much time is needed for prep. +- How to reduce too much text into just the right amount +- Preparation of the session material and estimating the right amount of time for each section +- Getting learners to take the first step: sign up for and attend a workshop, when they don't think programming is a skill they can learn +- Getting learners to take the _second_ step: translating what they've learned in a workshop into something they can apply +- preparation and time management +- Engaging with the students which was much easier for me when I used to coach +- Finding the right depth for an unknown audience for "my topic" +- education background of participants and their learning objectives + +What is the best thing about teaching for you? +- Seeing when learner gets interested/curious about something and takes inspiration from the course. :+1: +- Seeing it works and someone can do something new. +- Motivated students grasping new stuff +- Students picking up and running with the matertial and skills I give them and using it for their own work. :+1: +- The "ah-ha!" moment when a student gets it! :+1::100: :+1: +- Learning from students who know about some topic more than you do. :+1: +- Being able to help people reach their goals, by showing them something new. +- Teaching is optimism acted out in the hope of making a difference both ways I suppose. +- The feeling of accomplishment when you see learning grow and implement the learnings :book: +- mutual learning and impact on learners :+1: +- Results and feedbacks / Mutual interests and interesting discussions +- mutual learning and I can also learn lots of things and new ideas from participants + + +#### :question: Questions + +##### General / Practicalities + +- Will the material be made available? + - Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/ + - Can I share them with a colleague + - Yes please :) + - Can I resuse them in my own teaching? + - Yes please :) +- Will these sessions be recorded? + - No, but the materials (see above) should include everything needed for self-learning. +- Can I get a certificate for this workshop? + - You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended. +- How often will we be talking in breakout rooms? I'm not in a place where I can talk, so if we're going to talk a lot I'll need to move offices + - We'll have about one breakoutroom session per episode +- +##### Episode 1: Lesson design and development + +Materials: https://coderefinery.github.io/train-the-trainer/lesson-development/ +**Discussion:** + +- When you start preparing a new lesson or training material, where do you start? + - I look at existing materials on the same topic, but chose/refine topics based on the perceived needs/interests of the presumed audience + - Outline of structure and Material collection for a new lesson :+1: + - What material I have already? (what other material is already out there?) + - Start by looking for related resources (documents, videos, courses, etc) to have a base data and better understanding of what have been done around the topic + - Know your audience + - Review existing material + - Think about learning objectives (to keep focus on essential things) + - Think of three things simple enough that they will be remembered the next day. Design around that. + - I write down the thoughts that I have and then go back and structure it. + +- What tricks help you with “writer’s block” or the empty page problem? + - Write anything down that comes to mind, sometimes draw something, looking out the window :) + - Do a mind map - what concepts do I want to get across? + - Starting small, for example a list of headings and then building around it. :+1: + - What does one know about the target audience and why should they be spending longer than 1 minute listening to what they will eventually get to hear? + - Get some inspiration from another source. + - Start with the three things above + - Start with the plan and the overview design + - Some kind of outline / main message(s) + - Start with three things. Three supporting points for each of these. +- Maybe you haven’t designed training material yet. But how do you start when creating a new presentation? + - Think about the learning objectives and try to break them down into steps + - Title, Objectives, target audience and Plan + - Some kind of outline / main message(s). Get as many images as I can, instead of words + - Draft an outline and use chatgpt to fill in details + - Example of how the teaching content is applied in a real-world context +- If your design process has changed over time, please describe what you used to do and what you do now instead. + - I look more at existing materials and try to get more information about the audience. Unfortunately getting information about the audience before the event is hard + - I used to start from the begginning and get from there but that often meant a very polished start and a rushed end. Now I try an overview first, then fil out sparsed details at every section + - Updating the data and tweak the presentation + - If I am teaching a small group (or one to one) talk to them before hand - find out what they know already, what they want to learn. +- What do you know now about preparing lessons/training/presentations that you wish you knew earlier? + - less is more. It's better to have 2-3 main messages rather than trying to show everything in one go :+1: :+1: :+1: :+1: + - how much practice time the learners need to master what's taught + - Don't worry about something going wrong. It often makes the lesson (and thus the material) more presistent in memory. :+1: + - Try and remove everything except what you want the person to learn + - That's a very tough part for me in the sense that I never know how much of an underlying "black box" is still ok.... + - Designing intermediate materials is hard, and requires putting some "gatekeeping" making sure that learners are directed to appropriate courses + - When I see a cool graphic, concept, slide, etc., download it and save it in my 'new-materials' folder to use later on! + - I have come to the conclusion that perhaps a more "agile" approach to developing materials (try to do design/teaching iterations quickly) might be the best way to go, but there are risks with this approach too + +**Questions** + +- From zoom chat: Can you expand on what a learner persona is? + - A defined example person described in terms of the materials you are preparing, making up a story about the background and interest of t + - Answer from chat: A learner persona is a blackbox which has a very simple algorithm inside: GIGO. + - Answer from chat: I think it's the same as ICP (Ideal customer persona) where you describe the learner as a customer + - Answer from chat: I'm a big fan of "How Learning Works" by Ambrose et al https://bookshop.org/p/books/how-learning-works-eight-research-based-principles-for-smart-teaching-michele-dipietro/18640868?ean=9781119861690 + - See also book: [Teaching tech together](http://teachtogether.tech/) +> CodeRefinery lessons: https://coderefinery.org/lessons/ +- From chat: Do you have an example of an instructor guide? + - One example from our [reproducible research lesson](https://coderefinery.github.io/reproducible-research/guide/) + - Another from git intro: https://coderefinery.github.io/git-intro/guide/ +- From zoom chat: Do you have a "measure" of how better are the new lesson compared to the old ones? Does it make sense to talk about measurements here? + - So far we only have daily feedback that we collect at the end of the day and we can compare that to earlier daily feedbacks. More about that in the last episode of today. But measuring this is indeed not easy and it also takes time to capture the effect during longer-term surveys. Some of the changes were more leap-of-faith than based on data. + - I guess that sometimes one can use "compelling arguments" instead of data to justify a decision +- Software Carpentry does teach using the command line, and gives a session on the command line before. What do you think about this approach? Are you stating that a 3-hour lesson about CLI is not sufficient to make people comfortable enough to use that for version control? + - Yes, good question. For CR we consider it a more advanced step: we do think people should learn command line, but it's for a different course. We accept some people might not know it or want to know it so adapt to that. + - In general, we've found the "you need X, but have to learn A, B, and C first" approach should be avoided if possible: people are busy, try to reach people where they are. + +:::danger +[Exercise](https://coderefinery.github.io/train-the-trainer/lesson-development/#exercise-discussion-about-learning-objectives-and-exercise-design) in breakoutrooms +::: + +- Room 1 + - Research data management + - Objectives + - Research life cycle + - FAIR principles (Findable, Accessible, Interoperable, Reusable) + - Exercise + - develop a data management plan (DMP) that outlines how their research data will be handled throughout its lifecycle. + +- Room 2: What is the difference between eating breakfast and sitting through a lecture? (Tip: Start by listing the similarities ...) +- Room2 : Making papers in LaTeX + - What is LaTex and how is it different from editors like Word + - Basic Structures + - How to find and use a template + - Including figure & table + - How to use references and labels + - Exercise: to create a new LaTeX document & edit it + - Excercise: common error messages: can you find the error in this code? + - Exce +- Room 3 + - GPU Programming (1 hour intro) + - Learning objectives: + - What is GPU programming. + - When is it usable, beneficial to use GPU programming? + - What are technologies to do GPU programming? + - [What are and how to manage typical issues] + +- Room 4 + - Git / Figures / Project management / data cleaning + - Chose data cleaning + - Three learning objectives: + 1. What do we mean by "clean"? How to identify it? + 2. Identify some common problems in a dataset + 3. Identifying and handling missing values/fields + - Exercise + 1. Discuss problems, find the most common ones + - In small groups + - What problems have you run into with datasets you've worked with? + - What problems can you imagine, or have you heard about from colleagues/news/social media? + - Report back, instructor collects all problems into a list + 2. Have a dataset to clean; a clean and a messy example + - (identifying) Using a visualisation or overviewing tool? + +- Room 5 + - Jupyter Notebooks + - Learning Objectives + - Can setup an enviroment you can reuse / can share with others / a project. + - The order you run the commands in needs to match the order of the code in the Notebook - otherwise you end up in a pickle. + - Why use a Jupyter Notebook? What are the advantages? Easy to use environment. + - Exercise + - Print variable assignments from different cells - show that the order you run the code is important. + - hand out a domain specific notebook that does some calculations and visualization to run and modify, to show that you can share easily + - show !pip install to add dependencies/features +- Room 6 + - Using GitHub without the command line + - Learning Outcomes: + - Be able to discuss changes before merging changes into the main repository. + - Publish a personal repository page ( I think its called intro repository) + - Share their script/notebook/code/small data on GitHub + - Homepage using GitHub pages or the README that becomes the "index page" of the GitHub user account page + - Learner personas: + - Check the Personas of the learners + - Somebody who has seen/heard of GitHub but hasn't used it yet + - Someone using it for their own work but struggling with collaboration + - Exercises: + - Upload/share an example dataset or script + - Review another collaborators pull request. + - Take part in the discussion on a pull request. +- Room 7 + Linux shell basics: why do we want to teach them? + (this took most of the time for the discussion) + - Learning objectives: + 1. Filesystem: Directory (CLI) - Folder (GUI) analogy + 1. Basic commands (which commands are basic? make a survey of shell histories and get the most common ones) + 1. Basic constructs (e.g., for loops, pipes, while loops... which ones are basic? See above) + +> Note from chat: Zoom timer: https://support.zoom.com/hc/en/article?id=zm_kb&sysparm_article=KB0068677 + +##### Episode 2: Lessons with version control + +Materials: https://coderefinery.github.io/train-the-trainer/lessons-with-git/ + +Poll options: I want to hear about: +- A: Why use version control for teaching materials +- B: Different template options +- C: How CodeRefinery does it; CodeRefinerys lesson template + +Poll vote (multi-select): add a `o` to your answer + - A: ooo + - B: oooooo + - C: oooooooo :ghost: + +Question to audience: if someone wants to make a tiny fix to your material, how hard is it? +- If my material is only in pdf format which is not online, then it is hard. +- I hope it is easy - my material is in GitHub. Nobody has ever done that though! +- Slides: hard to find, easy to edit; Git repos somewhat easy, unless they have to be built locally or with an action; HackMD easiest to edit. + - if you use something like google slides they are not that difficult to find + - known permanent address. Google docs et al fail on that/same for many pads. +- For this material today - very easy! e.g. https://github.com/coderefinery/train-the-trainer/pull/128 +- Template with an edit button in the HTML pointing to the source-code in the repo. + +**Questions/Discussion topics** +> Upcoming CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/ +> Please share with your networks, and let us know if you would like to co-teach a lesson (to support@coderefinery.org or in our [Zulip chat](https://coderefinery.zulipchat.com/)) + +- Changes to the material are sometimes not just tiny fixes. For example, one wants to present a slightly different selection of topics, but maybe some topics are "coupled" (perhaps naturally or perhaps just because of how they are presented), or change the general "theme" (e.g., life sciences vs theoretical physics) while keeping the actual topics the same. How could a lesson be developed to avoid having to do a huge rewrite? + - You can try to modularize your material and keep non topic specific parts non themed. E.g. where you explain the functionality, don't make reference to the example (not simple), so the example can be changed depending on the audience. +- What are the pros/cons of renaming a course / changing a repo name in GitHub? + - It should be relatively unproblematic since GitHub will forward to the new name. + - How long does Github keep the "old" name linked? Is there a max time it's blocked, or changed as soon as a new one appears with the name? + - in my experience it forwards "forever" until I create a new repo with the old name which will break the forward +- what should be in the readme for the git repo? (canonical address? contact points? license!) + - https://coderefinery.github.io/mini-workshop/2/documentation/#often-a-readme-is-enough-checklist + - I miss the url to the (main) repo in the readme + - Do you mean the link to the rendered (lesson) page? + - Link to rendered page: We often have this in the "about" section of the readme (see up right: https://github.com/coderefinery/train-the-trainer) + - this gets lost in a fork, doesn't it? so 20 folks forking and or reuploading the repo somewhere means the url gets lost? + - True, but they might want to have their own version rendered? + - yes, I have had issues finding and contributing to the "master" repo so all benefit. Else it gets cluttered. Both is valid + - Good point though, the link to rendered page should probably also be included in the readme for completeness; ah and the link to the repository too, yes + - so realistically we need a content folder and some more next to the readme as a best practice. sounds good! +- Is myst (markdown renderer) enabled by default in sphinx now? + - to my knowledge no. we add the "myst_parser" extension to conf.py. + +> Cicero: https://cicero.readthedocs.io/ +> Sphinx documentation: https://www.sphinx-doc.org/en/master/ +> Carpentries workbench for creating Carpentries lessons: https://carpentries.github.io/workbench/ +> This is the testing lesson Richard showed: https://coderefinery.github.io/testing/ +> And the corresponding repository: https://github.com/coderefinery/testing +> You can lean back and watch, exercise coming in a bit :) +> Richard will now edit our train the trainer material repository: https://github.com/coderefinery/train-the-trainer +> The Sphinx extension for CodeRefinery lessons: https://github.com/coderefinery/sphinx-lesson +> Empty lesson template to build your own lesson: https://github.com/coderefinery/sphinx-lesson-template + +**More questions** +- Does the coderefinery.org page built on sphinx? + - It's built also from markdown but it uses https://www.getzola.org/ (which is more optimized to render websites, but we could do teaching also with Zola or create the project page using Sphinx) + +- Is there a way to build and preview CR lessons without the command line? + - The GitHub workflow we use creates HTML from all branches. This means that one can push a branch to GitHub, preview it there, and then open a pull request. One thing that would be nice but we don't have yet is if a bot automatically posts the link to the preview to a pull request. + +- For VCS-2, for the Carpentries Linux shell example, Lesson, Github repo, to me it seemed as though the Sandpaper setup they have makes a very nice interface, complicates the relationship between source and output. E.g on the soucre page https://github.com/swcarpentry/shell-novice/blob/main/index.md I could only see to 'Prerequisits' and not 'Download files' on the page https://swcarpentry.github.io/shell-novice/. Perhaps I have missed something? + - I am sorry I don't know the new Sandpaper setup well enough to answer this question. + +- Do we have the instructions to build the lessons available somewhere to try out later? + - https://github.com/coderefinery/sphinx-lesson + +:::danger +Exercise VCS-1 (and VCS-2 (if time)) (https://coderefinery.github.io/train-the-trainer/lessons-with-git/#exercises) in breakoutrooms until xx:05 + +then short summary in main room and then break. + +Use the notes below. Collect a list of lesson formats and discuss what you like about each of them. +::: + +- PDF slides by a presentation program +- pdf slides with beamer in latex under source control. +- Markdown slides via Github +- CodeRefinery template +- Carpentries template +- Google Slides +- git-book +- [Jupyter Book](https://jupyterbook.org/) - allows creating a structured reference website using RST/Markdown, including Jupyter Notebooks to show result of running code +- [mdbook](https://rust-lang.github.io/mdBook/) - create simple/minimal website using Markdown +- [Binder](https://mybinder.org) - allows learners to run their own live version of a github repository with Jupyter Notebooks, with only a web browser +- Jupyter notebooks and jupyterhub platform +- Jupyter + Nbviewer and custom css (read only) + Binder link (hands on) +- RMarkdown +- Quarto Slides +- [Reveal.js](https://revealjs.com/) - write slides in HTML (also supports markdown) + - Example: https://bl-presentations.erambler.co.uk/2024-02-21-idcc24/ +- [Remark.js](https://remarkjs.com/) - write slides in markdown + - Example: https://bl-presentations.erambler.co.uk/2024-02-19-idcc-pids-workshop/ + + +Room discussions: +- Room 1 + - (https://smc-aau-cph.github.io/SPIS/README.html) + - CodeRefinery template + - Shared notes & blogs + +- Room 2 + - demo the exercise + +- Room 3 + - Mix of JupyterLab, Terminal within that, and traditional slides + - Jupyter + RISE (benefit: slides that are editable and executable live) + - Challenges + - present code in an interactive way + - handle lots of images/ figures without too much additional overhead when setting up the material + +- Room 4 + - Material and tools depend on instructors + - Some slide building tools + - https://revealjs.com/ + - https://remarkjs.com/ + - https://github.com/rust-lang/mdBook + - Using flat git repos without fancy styling to make it easier to edit but still version controlled + +- Room 5 + - Using R as a GIS: https://github.com/nickbearman/intro-r-spatial-analysis + - Workbook: RMarkdown, Slides: Quarto + - No continuous intergration + - Having a jupyter nbinder link to test the notebook + - repo lives on codeberg in this example + +- Room 7 + - Ex 1: + - Sphinx, similar to CR + - Sometimes pdfs generated with beamer package (or from pptx and odt), but blows up repository size if in version control + - Ex 2: + - Content + - CR: Content commonly found int the content folder + - SC: Mostly under episodes + - Question that came up: + - is CR/Sphinx approach mostly for technical topics? What about language. + - I guess by our nature it's focused there. But probably could be used for others (I guess it it's much easier to use git in a technical audience.) + + +##### Episode 3: How we collect feedback and measure impact + +Materials: https://coderefinery.github.io/train-the-trainer/feedback-and-impact/ + +**Questions to audience** + +- What tricks/techniques have you tried in your teaching or seen in someone else's teaching that you think have been particularly effective in collecting feedback from learners? + - preparing a survey and emailing it to participants as soon as the event ends (usually get <50% of answers but it's a representative enough sample) + - do engage with the audience, give them the time to get the courage to speak up + - Be the audience yourself + - yes! some problems/issues I don't notice as instructor, only as listener + - Have time (e.g. 5 min) in the session to fill out the feedback form + - If the course/workshop has several days/sections do a couple questions every change, then a full one afterwards + - "Traffic light" feedback (e.g. for pacing or progress on exercises): give each learner two different coloured post-it notes for in-person, or use emoji for online, to indicate a current status +- Can you give tips or share your experiences about how to convert feedback into changes or actionable items? + - ask questions about things you know you don't know + - “Don’t let the noise of others’ opinions drown out your own inner voice.” — Steve Jobs +- When people ask questions / get stuck with a specific step. Is there a typo I can change there and then in the workbook? + - Being able to fix small things on the fly helps sometimes, otherwise open issues if working on github + - If multiple people have the same question, then this is an indication that I should look at this in more detail +- How do you measure the impact of your teaching? Any tips or experiences about what you have tried or seen other courses do? + - "How likely are you to recommend this workshop to others? (0/5)" + - Check the 'Garbage Out' bin, what you find there will be what went across. The rest will be history... +- Anybody knows of good resources on survey design? Please link them here. + - "Our job is to figure out what they're going to want before they do... Our task is to read things that are not yet on the page." - Steve Jobs + +**Questions/Discussion points** + +- Feedback is necessary to design good lessons. Improvement can only be done iteratively. So the faster the iteration (design/teach), the better. But on the other hand, I cannot constantly bomb our community with training event emails. So I would like to try proposing a course many times a year, but I don't want to spam everybody many times a year. + - :+1: + - With CR we also have a calendar that can be imported to different calendar applications, where we add all workshops: https://github.com/coderefinery/calendar/ +- Does an even split of too fast / too slow mean speed is about right?! + - I take it to mean "it's roughly where it should be". Would be better to accomdate the sides better though... (we do try to design for a broad audience: some easy stuff, some advanced stuff, so people can make their own path) + - It could also indicate that the prerequisites/scope are not well defined :+1: + - Based on long term surveys we also know though that even though the workshop might have been to fast, people appreciate having "heard things before and know where to find them later" + - perhaps the even split between too fast/too slow is ok only if the majority of votes goes for "just right" :+1: +- One of the most important disciplines in journalism is to challenge your working premises. (Bill Keller) This applies equally to learning as well. + - Participants can be encouraged to write some posts on LinkedIn. If it is helpful some blurbs can be created for pre and post-workshop to generate more traction for Code Refinery and future participation. + - Ask participants if they use Dev.to, hashnode etc to blog their work or use twitter etc to have a memory of their work. +- Do you have any suggestions for prerequisites? I try to make them clear, but occasionally people attend who clearly do not meet them. :+1: + - I guess it depends how much it matters for the workshop itself. If you have group exercises etc, it probably matters? , lecture style maybe not so much?; important is that the participants themselves know that prerequisites exist and if they meet them + - Sometimese people that do not meet the prerequisites join to get to "know what they don't know", find out where to find information on topics they might get interested in future etc + - Other suggestions? Viewpoints? :) + - Thank you - things for me to think about there :-) + - With CR's latest ideas, we try to make the prerequisites clear, but there is no capicity limit: it's OK if people drop by and are less than prepared: it's livestream, anyone can come. We try to have something for these people, too: learn what you are missing, why you might want to study more in the future. + - Any thoughts on applying this to a more practical focused course, with a total capacity limit (i.e. not like CodeRefinery). +- Everytime you do a course on CodeRefinery, think of it as trying to bake a new cake with an old recipe with no idea about the individual taste preferences of the one you bake the cake for. Then, you will not experience too many surprises. Fine-tuning the recipe for one cohort still remains the 'old recipe' as far as the next 'new cohort' will be concerned. C'est la vie. + - nice analogy! +- Question from chat: For examples 2 & 4, would you also consider using something like a Likert scale? E.g. Rate how well you agree with the statement "My code is more reusable as a result of attending a CodeRefinery workshop" (from 1 Strongly disagree to 5 Strongly agree) + - Thanks! I am new to Likert scale and will read up on it. In my experience numbered answers can be useful for reporting. But I also like questions where we ask for what actually to change. +- Comment from chat: Richard, your point crowns the point of having CodeRefinery, With Radovan's and Samantha's acquiescence assured, I would like to suggest you wear a crown going forward, especially for the CodeRefinery session. Do we have a deal ? + - I don't quite understand this + - I *think* it's a tongue-in-cheek-comment (joke) but I am not sure..... +- What is the ideal way to allow people to interact while course is going on in the main online session, i.e. without a breakout room? Taking a pause or discussion in the background? + - I've had some success with WhatsApp groups for a course - particually ones that run over 4 (or 2) sessions. + - A quick survey/quiz + - Question to the audience that we take time to answer but it helps to show the answers +--- + +### Wrapup + +- Thank you for active participation :) + - We'll continue answering questions after the workshop and make the cleaned up (no names etc) available from the materials +- Next session **Tuesday August 20, 9 CEST: Tools and techniques adopted in CodeRefinery workshops** + - we will talk about on-boarding, install help, roles, screensharing, sound, collaborative notes +- All workshop materials will stay available (after the full workshop also on Zenodo :tools:) +- CodeRefinery community: https://coderefinery.zulipchat.com/ +- If you want to co-teach with us in the upcoming (or next) CodeRefinery workshop (https://coderefinery.github.io/2024-09-10-workshop/); or just want to learn more about this opportunity: Send your name and e-mail address to support@coderefinery.org; we will contact you! + +### Feedback about todays session + +What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session: +- Lesson design approach +- I liked the backwards lesson design, gives a name to a practice I've already been doing :+1: :+1: +- Lessons from code refinery on lesson design. Learning about Sphinx. +- Collaborative notes and anonymized archive of notes. +- it's nice to have a community to discuss these kinds of problems +- Hearing the variety of tools people use for slides (PDF, Quarto, Beamer etc.) +- Good intro of the tools, the jargon and the pedagogical philosophy of teaching tech. +- The absolute openess in having everything publicly available - materials ofc but also questions, discussions, feedback, ... +- Thinking about all content being available publicly and as a git repo +- Thanks for explaining the HedgeDoc interface, with view and edit options + - Is there anyway to come back to this document later (e.g. tomorrow) and see what has changed since now? So I can see if any other questions have been asked/answered? + - There is a "revision" point under "Menu" up right, which shows you different versions of this document +- Modesty: the gentle art of enhancing your charm by pretending not to be aware of it. - Oliver Herford +- + + + +What one thing would you improve about this session? +- Perhaps some more interactivity but can be hard to plan and time + - We'll see what we can do. +- _Maybe_ mix the breakout groups up for each breakout session (although there are advantages to consistency too) :+1: + - yes, pros and cons! For me, having consistency worked well this time. + - Likely we will have different participants next week, and a bit of mixing will happen naturally. +- The pace of the presentations could be a little tighter (the pace is good for a discussion though) +- Richard's voice was only 80% audible + - Sorry to hear that. It seemed fine on my end. Will check better for next session. +- Hands on simulation and collaborative notes +- I found it difficult to follow the presentation and the collaborative notes at the same time + - We will highlight the collaborative notes more in the next session. Our strategy usually is to say to focus on the "teaching part" and use the notes only when needed. Since you can go back and also check the notes later. + - My problem is that I want to follow both since I don't want to miss out on anything. As such, I have both windows (zoom and the notes) open side-by-side. Since there is near-constant real-time typing in the editor, and as such visible movement on screen, I get constantly distracted. This makes following the event quite exhausting. +- Heads up to participants on using the break out rooms on voice interaction and screen sharing. + - Do you mean that we should have mentioned it more clearly in the pre workshop email? +- I found it hard to follow with so many things going on at once... + - A collaborative document being changed at the same time as... + - Someone speaking and explaining content at the same time as... + - Chat in a different application at the same time as... + - Content changing in a termin application. + - Thank you for the feedback. We will remove the Zoom chat out for the next session and explain the use of the collaborative notes more. +- Make more use of defining and then making sure the learning objectives are met + - True we did not talk about them much, will pick that up better for next session. +- UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. - Dennis Ritchie. You need to do a lot to prove that to be wrong, simply put. +- Allocate some time for learners to type in the answers so that we don't have to listen and type at the same time. + +Any other comments? +- It's great to hear other people's experience + - Good to hear :) +- Looking to meet you onsite if there are any events and get more emails from you :) + - We will keep you informed :) +- Thanks for putting this together, I got a lot of inspiration for my own courses + - Good to hear :) +- I didn't know where to ask questions. It would work best *for me* to do it in zoom chat as that's the application that I'm watching in.. + - Sorry for that, just to figure out why: Did you join a bit late? + - No. Perhaps I just missed that or it was too quick for me or something? + - Ok, sorry. Will try to make this more clear in next session. + - Perhaps also because there were so many things going on and jumping around. For me, the zoom chat is the constant (and obvious) place to ask questions while watching a shared screen, trying to find the right place in a moving collaborative document is difficult. It tears my attention into too many pieces. :+1: +- Had a lot of content that assumed extant knowledge that I didn’t have. This wasn’t in the pre-requisites. + - Do you have examples? + - Yes! The code refinery templates and even just the way of doing that. I was expecting more on "when designing a lesson you should think about these steps" rather than this is how we do it and this is our tool for doing it. I guess I should have read the pre-workshop content better? + - Ok, thank you for your feedback. You are right that we actually had some content that for sure would have been easier to follow for people with background knowledge about a certain topic. + - "If you are in CodeRefinery TTT, you probably know what version control is and why it is important." - extant knowledge, why not just add a sentence or two? + - Please can you update in preparation for the next workshops so that I can decide whether or not they will be right for me? + - Yes, we will think more thoroughly about this and send the info in the next email going out Wed/Thu + - Thank you! +- Lots of the content was relevant to code refinery but not the wider topic (e.g. it was how to design a code refinery lesson and not how to design a lesson as stated in the session title) + - We thought of the content of showing one way of doing things, ie "what we have learned", if you have suggestions on how we could make that more clear on the event page, please let us know :) + - "in a code refinery lesson" in the lesson/workshop description? +- When you have pre-written “thank you for your active participation” it feels fake! + - He, that is true, did not think about that. Thank you for the feedback. I would not have added it if Radovan and Richard would not have provided good feedback from circling the rooms. +- I found it vague and disorganised and difficult to follow. It felt like the instructors were presenting the content for the first time and didn't know what to do next. + - Thank you for your feedback. This is not the first time we have this training, but it is the first time in this constellation/way. The way of teaching may also sometimes make it seem new to instructors. +- I really liked the active exchange with other participants, but I also would have enjoyed a bit more technical content in the presentations. In a sense it felt less like a 'training' and more like a get-together :+1:. + - Thank you for your feedback. We thought the name "workshop" would combine the training and exchange nature of this event. But maybe it didn't do so enough? Do you have suggestions on how to clarify it on the event page? + - Well, the 'train the trainer' title created the anticipation of being trained ;) don't get me wrong, I liked the exchange, but I felt that the training aspect fell a little short. imho the workshop would benefit from a little more (instructional) content that is presented in a more structured way by the instructors (as opposed to 'crowd-sourced knowledge' that is collated in a loose collection of questions, notes and links) + - Other than that, you could add another section on the main page, sth like 'Workshop structure: we aim for a mix of modular presentations and work in small groups. The latter will be done in breakout rooms - be prepared to switch on your camera and have a fruitful exchange with fellow participants!' + - Thank you for the suggestions, will add something like this :tools: + - > Added : https://github.com/coderefinery/train-the-trainer/commit/03308595436e636b3bb37ed9d1f0dee39eeccd0f +- My understanding (so far) of what (unlike the competition) CodeRefinery DOES NOT seek to exemplify - +https://images.ctfassets.net/rxqefefl3t5b/2k45BFtw4sBMlBfjr1OZ90/5c6ecd3628a43b0cdc79815f665e224a/Screenshot_2023-05-02_at_09.35.23.png?fl=progressive&q=80 +- My understanding of what (unlike the competition) today's session of CodeRefinery DID exemplify - Definition of 'Workshop' from the Oxford dictionary of the English language "a period of discussion and practical work on a particular subject, in which a group of people share their knowledge and experience" +- In my experience, even for the most seasoned Programmer coding, by its very nature, is nothing trivial, this being a simple straightforward fact just like there is no such thing as an egg which is a cube. I mean there is a reason why not just about everybody is a poet either. But, other minds have pointed this out without having to first explain why the universe is what it is in a way that could be understood without effort ... https://i.pinimg.com/originals/7b/7e/c4/7b7ec4b91d2cf9d8e1b064678d205467.jpg +- The inclusive environment feels very welcoming. Keep up the good work! + +**Thank you all for your feedback! Highly appreciated!** + +--- + +### Day 2 : Session 2 (20.08.24)- Tools and techniques adopted in CodeRefinery workshops + +#### :calendar: Schedule + +| Time (CEST) | Title | EEST (UTC+3) | BST (UTC+1) | +|---------------|---------------------------------------|---------------|---------------| +| 8.45 - 9.00 | Connecting time | 9.45 - 10.00 | 7.45 - 8.00 | +| 9.00 - 9.15 | Intro and Icebreaker | 10.00 - 10.15 | 8.00 - 8.15 | +| 9.15 - 9.25 | About CodeRefinery workshops | 10.15 - 10.25 | 8.15 - 8.25 | +| 9.25 - 9.55 | Collaborative notes and interaction | 10.25 - 10.55 | 8.25 - 8.55 | +| 9.55 - 10.10 | Break | 10.55 - 11.10 | 8.55 - 9.10 | +| 10.10 - 10.45 | Workshop overview, roles, onboarding | 11.10 - 11.45 | 9.10 - 9.45 | +| 10.45 - 11.05 | Sound | 11.45 - 12.05 | 9.45 - 10.05 | +| 11.05 - 11.20 | Break | 12.05 - 12.20 | 10.05 - 10.20 | +| 11.20 - 11.50 | How to prepare a quality screen-share | 12.20 - 12.50 | 10.20 - 10.50 | +| 11.50 - 12.00 | Outro and feedback | 12.50 - 13.00 | 10.50 - 11.00 | + + +#### :icecream: Icebreaker + +##### Check-in + +Which emoji best describes your current state of mind? [Emoji cheat sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) +- :-) +- https://media.istockphoto.com/id/148421550/vector/bored-emoticon.jpg?s=612x612&w=0&k=20&c=uo5KBTqdJZbBQb_Xldhzuovx5t08fHfGR7dw7TCk90I= +- :saluting_face: +- :sleepy: +- :coffee: +- :umbrella: +- :cocktail: :coffee: +- :seedling: +- :tired_face: +- :sun_with_face: +- 🥴 (:woozy_face: not converted?) +- :coffee: +- :sunflower: :book: +- :satisfied: +- :coffee: +- :coffee: +- 🥱:tired_face: +- :bread: - I am baking bread today so I have been kneading dough while listening! + +##### Introduction in breakoutrooms + +Name / Affiliation / Location + +##### Teaching + +- Do you teach and organize teaching alone or with others? What would you prefer and why? + - Coming together is a beginning; keeping together is progress; working together is success. – Edward Everett Hale + - These days always with others. Alone is easier to prepare but almost always is harder during it. + - Teaching with very diverse partners, it can be challenging to find a common language with people very different than you. + - I teach alone, in the future there will be more collaboration with multiple team members. Both approaches have their pros and cons. + - Both has its own distinct advantages + - Most of my teaching is on my own, as a freelancer its more expensive to work with colleagues than to deliever a course on my own. + - Teaching together, learns from each other, feedbacks to improve + - Not formally taught yet, only given presentations actually . + - collective teaching would benefit the teachers with collaborative curriculumn and experiences sharing. + + +- If applicable, have you seen any challenges when teaching together and how to overcome them? + - It actually requires preparation, + - Is it about teaching or about inspiring ? Discover the answer and get inspired ... + - It's like being in a band: you might be great at improvising and your band-partners might be great at improvising too, but a bit of rehearsing makes even the impro gig much better + - Need to plan before session, difficult if people don't 'plan' in the same way, e.g. with the same time frame. + - Heterogeneity in learners make it impossible to get the same result from everyone. + - In fact, the same applies to teachers :D + - Teaching together requires to have similar opinions on how to teach. I share vews only with ~40% of my colleagues I think. +- No Teaching experience but it is good to give the outline of the lessons beforehand and learning goals. + + +--- + +#### :question: Questions + +##### General / Practicalities + +- What is this document for? + - Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts) +- Will the material be made available? + - Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/ + - Can I share them with a colleague + - Yes please :) + - Can I resuse them in my own teaching? + - Yes please :) +- Will these sessions be recorded? + - No, but the materials (see above) should include everything needed for self-learning. +- Can I get a certificate for this workshop? + - You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended. +- How often will we be talking in breakout rooms? + - We'll have about one breakoutroom session per episode + - BR 1 : The Zoom chat does not work for the breakout room so we should take note of that. No webcam/mic = expect silence. + - Thanks for notifying! This was not intended. Turned the chat back on. + + + + +--- + +#### Episode 1: CodeRefinery + +Materials: https://coderefinery.github.io/train-the-trainer/coderefinery-intro/ + +- (questions continue here) +- Is there the plan to build capacity / be paid to deliever courses? + - We've discussed it but right now we don't have many people who could accept money to do this (and maybe shouldn't, because of their jobs). But, we would encourage others to use our materials as "independents" to deliver paid courses + - One idea we have had is that paid courses could be delivered through the DRA (link below), who we know. Basically, DRA could find instructors and handle the money transfers (If someone wanted a paid course, we could help find someone to do it through DRA or independently) + - :smile: +- Have you come across DRA, https://digital-research.academy/, Heidi Seibold, Joyce Kao who are doing similar work? I can connect you if you like. + - Yes we have been discussing about possible future collaborations and are already sending possible clients their way (we, as a project cannot take money) :+1: + - Excellent! :-D :smile: +- . + +#### Episode 2: Collaborative Notes + +Materials: https://coderefinery.github.io/train-the-trainer/collaborative-notes/ + +- So anyone can type anonymously? + - Yes, as long as you do not log in, you are Guest XXX + - And at least in our hedgedoc case you cannot log in so you will always be anonymous. You can do [name=xxx], to add your name to a comment + +- Test of +1 + - +1 :+1: :+1: + - :-1: a test + +- You are hosting your own version of HedgeDoc, and Hackmd.io is a similar (free) option. What are the limitations of the free hackmd.io? Should each center install their own HedgeDoc instance? + - It **seems** the free version of HackMD has gotten worse lately. It works still well enough with a few people editing at the same time. + +- Have there every been problems with the anonymity and CoC? + - We haven't had any issues so far. + - With a different anonymous tool in a bachelor course, we had issues with anonymous participants (participants were posting slurs and unsafe links). The course organiser decided to stop allowing anonymous tools. + +- Why not google documents? + - Google documents are actually setting a hard limit for simultaneous writing, no more than 100 concucurrent editors. I am unsure if microsoft onedrive word documents would allow more users writing at the same time. + +- What's the most people you have every had on HackMD / Hedgedoc? + - I believe about 200 active participants? + +- What are your thoughts on using the build-in Zoom Q&A? + - We haven't tried this, in part because the way we do streaming now (you'll see in session 4), participants aren't in Zoom so don't have access to that. The doc-format works pretty well though, when we keep it in this limited "write at end" format. + +- How do you see what has changed? e.g. if leave the session at the end, can I come back tomorrow and see X has been added? e.g. a diff for this maybe? + - In the menu up right there is revision, it does show the document and changes at different time step :+1: Thanks! + - We recommend people only write at the bottom (and since we answer things live), so as a first level approximation you find where you were and read below that. Think of it more like chat than a full document. (Yes, we do revise questions at the end) + +- How about flinga boards or similar tools? + - My take is that the simplicity of a simple text document wins over free-form in-person-workshop-like tools. + - There's miro, can be a bit confusing though + +- How does this work with small groups, e.g. 10-15 people? + - Good question: it can be hard if people aren't rigorous about it, people start only using chat/voice. So there seems to be some lower bound in size but we haven't tested this much + - And if the instructors never screenshare it to show what goes on it, then seems to be less used. + - And if there aren't other people to read/answer it during the session (perhaps less likely in a small course), it seems to be less used. + + +:::info +Breakoutrooms until xx:55 + +Exercise/discussion: https://coderefinery.github.io/train-the-trainer/collaborative-notes/#exercise +::: + +- Breakout room 1: + * Use of etherpad for collaborative discussion. + * Use of slido for polling and quizzing. + * Presemo as a slido alternative (https://www.aalto.fi/en/services/presemo-a-fully-web-based-classroom-participation-system) + * Use of text based approach for questions rather than live can be helpful if there is a language barrier issue. + - A good teaching session which had many questions coming spontaneously to the teacher is a non-entity of sorts. If the overall flow of feedback / questions increases it could indicate that the session will not prove to be a helpful experience. A signal that generates noise is, well, noise, if calling a spade a spade signals anything. Note that the 'overall' bit and the 'to the teacher' aspect are important. Both the best and the worst teaching session have two things in common: a teacher, and the fact that NO Materials of any kind are used, ie speech is the only channel of communication via a common language. The only difference is that it is not the same teacher, at least not in the same session at the same time. + + Another less mentioned, but perhaps more relevant indicator of a great session is the simple fact that at the end of the session EVERYONE feels empowered, NOT tired. This is not an easy to quantify thing, but screams out the quality of the experience loud. More often then not, such sessions differ little from each other, apart from in terms of the theme / topic and the participant mix. It ends up being the 'keep your cake and eat it too,' of sorts, not quite the far less amusing post-bombardment devastation scenario in the wake of a take it or leave it go at anything. + + - profanity in collaborative documents where people can add content anonymously could be a problem (happens very rarely, fortunately and somewhat surprisingly) + +- Breakout Room 2: + - Good experiences with Zoom polls + - Handling questions in hybrid setups: all participants (on-site and online) ask questions in written form + - Collaborative notes can be challenging when conducting a course alone (without teaching assistants) :+1: + - Providing a method to ask questions anonymously can make asking easier for shy participants + - Questions can give valuable feedback on how the course is going + - Online collaborative whiteboarding platforms such as Miro + - Large monitors are useful for this not to have to drag a "periscope" around + + + + +- Room 4 + - good experience with whatsapp chat for questions. since most learners have the app already and one thing less to install and set up + - reply to question is a way to handle multiple questions at the same time but it works well for smaller groups + - experience with collaborative docs in in-person workshops: voice questions might "win" over the document + - "seeding" questions may help to not have an empty document + - it can help somebody to start and create a structure which helps others to see and follow + - we discussed the Carpentries sticky notes system (red sticky note: signal tech issues and use for feedback, green sticky note: signal that exercise worked and for positive feedback) + - Nice summary of sticky notes system: https://teachtogether.tech/en/#s:classroom-sticky-notes :+1: + - What is the success rate of in-person workshops after COVID? Discussion: Teachers prefer in person and learners prefer remote or recorded to spool back and relearn. + + +- Room 5 + + - Good experience with Collaborative tools as HackMD and HedgeDoc while teaching with no bad feedback + - When used with smaller groups works best as one-way, like sharing links with students and so on + - Needs to be done as a team, quite difficult if teaching alone + - Most useful when online/hybrid + - Anonymisity is important for transparent feedback and no biasis in classrooms + - Not very collaborative but useful to share history or jupyter notebooks live https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush + - Used Flinga before that seems like Figma and also onsite teaching using sticky notes + - There's miro.com but can be a bit confusing, more for brainstorming than for teaching + - Using quizzes apps like Kahoot is beneficial while teaching to have more engaging students + - + +- Room 6 + - teaching teenagers (in presence) but using shared pad becomes quickly very chaotic, so only usable for short moments when answering very precise questions + - Yeah, I can imagine. For CR we try to keep it in this very limited format (all questions bullet points, only add to the end) and I think that helps. + - using shared notepad for small workshop (5-10 people) to explore common thematic (mainly technical) to keep a shared notes and condense aftwerward (and publish on wiki to archive) + - Difference between teaching in person and online. Some people prefer in-person and sometimes you have no option but to organise it online. + - There are sometimes cultural differences and learners feel shy to ask / question the knowledge of the Teacher, so shared notes are a good way to safely ask questions. + + +Questions continue: + +- Have we demonstrated how we do polls in HedgeDoc? Add your vote by adding an `o` + - yes: oooo *(in session 1)* + - no: + - :smile: + - not sure: o + + +#### Episode 3: One workshop, many perspectives + +Materials: https://coderefinery.github.io/train-the-trainer/overview/ +Next CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/ + + +:::info +#### Exercise until xx:39 +https://coderefinery.github.io/train-the-trainer/overview/#discussion +::: +- Room 1 + - Send pre-workshop email with pre-requisite instructions on what should be set-up beforehand. + - But, also mention that if help is needed for set-up, we will be ready before the session officially starts. + - Discussion on whether we push to work in a pre-ready environment (e.g. Binder, Colab) or in their own environment. + - Lots of help needed both before and after. + - Installations: as much as we can provide ready made environments for the learners, maybe installations will be something that the learners will face sooner or later. Maybe one should teach more about installations? + - My only cherished role in a teaching-learning session is the that of one who is living the moment as if there were no tomorrow. What cuts all ways really is that “By failing to prepare, you are preparing to fail.” ― Benjamin Franklin. A helpful motto: “When one teaches, two learn.” — Robert Heinlein. The best experience cannot be given, it can only be allowed to flow its way, so get out of its way. + + +- Room 2 + - Frequently, a single person fills all the roles for a single or multi-day workshop + - Collaboration with different centers/ universities can be challenging + - Preparing participants: it's essential for the instructor to go through the demos and be sure that they will work (no unpleasant surprises live). This can be extended to advance-prep for participants. + - Best experience is to hear (live or in feedback notes) some positive things directed at you :) + - Fully prepared environments (eg self-hosted JupyterHub) can make preparation for participants easy + + +- Room 3 + - Some students have problems with setuping the environment. Maybe having a step by step instructions could help. But some students don't want to "start" the course before hand. + - Preparing the environemnt before hand ensures everyone is onboard from day 1. The same thing happend in CSC training sessions and another session Peng attended. + + - Had experience in attending as teacher and student in previous workshops + +- Room 4 + - knowing the background of the audience is helpful + - Try and ask in advance of the background of the audience. Do a poll at the start of the workshop. In person one can do it interactive. + - among co-instructors: discuss topics and flow + - if more people are involved, it can help changing roles from time to time to see different perspectives + - preparation is key + - Circulate instructions beforehand + - Do a poll before session: Have you installed (QGIS) successfully? + - Push hard to do this in the welcome email + - communicate clearly to the participants + - +- Room 5 + - We've all taken most roles + - How to prepare in advance? + - Meet and discuss once or twice + - Make a pre-survey to check for interest and background + - Going through the materials + - Checking the toolkit (zoom) + - Agree on the reponsibilities and back-up plans (bit of scenarios planning) + - How to prepare trainings in advance? + - Collect resources and prepare the workshop plan + - Having the material readily available online ans sharing it + - Making a pre-survey + - What was the best workshop experience for you as learner, helper or instructor? What made it great? + - learner + - Engaging and practical workshop with more exercices and follow-up theoretical part explanations + - helper + - When the instructor is well prepared and as helper ther's only typos to fix and interesting questions to answer + - Assist the instructor, coordinate the collaborative notes, and make sure that the time is respected + - instructor + - I have a colleague whom I've ran the same workshop a few times already, goes quite smoothly now and we've made a few changes. Hard to reach that point with new colleagues but getting there + - Students/participants were engaging with the material and many good feedback collected even some of them asked for the next workshop + + +- Room 6 + - What has made a great experience for you as a learner/helper/instructor? + - Common ground between learners & teachers + - + - Motivation + - Teaching is much more enjoyable when the learners want to be there + - I spend a lot of time at the start of a workshop making sure learners feel that the content is possible for them to understand and master + + +Poll: I have joined a CodeRefinery workshop before: (add an `o` for your answer) +- yes (within last 2 years): ooooooo +- yes (longer time ago): oo +- no: oooooooo +- + + +(questions would continue below:) +- What is the motivation / advantages of streaming workshop versus using zoom? + - We'll cover this more in week 4, but roughly: zoom became unmanageable and essentially quiet once things got big. Streaming allowed "one to many" communication with no limit, and collab notes allowed better interaction anyway. By separating the rooms, it was more pleasant to teach. Videos could be released immediately since there was no risk of privacy of participants. There could still be in-person/online small groups who have "watching parties." +- What are the blue red and green font colors here, does it symbolify anything or just a convention HedgeDoc uses? + - Visual separation of formatting, mostly. (It helps to quickly realize you've missed/ mistyped a control Markdown symbol etc.) + - Yeah, it's bascically "code highlighting" for markdown. No special meaning but quite convenient for us. +- Is this next workshop only for team leads or also open for helpers and coordinators? + - You mean the next session of this workshop or the upcoming "CodeRefinery workshop"(this one: https://coderefinery.github.io/2024-09-10-workshop/)? + - The upcoming workshop coordinators are alredy working, but can be joined if you are interested + - As helper roles we currently only have "collaborative notes helper", which is all about helping to answer questions in the collaborative notes + - We do have some co-teaching slots open :) + - If interested: join the discussion in our chat: https://coderefinery.zulipchat.com/#narrow/stream/316508-coderefinery-tools-workshop/topic/Fall.202024.20CodeRefinery.20workshop + +- Can a person have multiple roles in a workshop as a helper and a teacher? + - Yes, many teachers also contribute to the rest of the workshop by answering questions in collaborative notes. :+1: + - Some teachers also host a local classroom in week one and do their teaching in week two of the workshop + - Roles that do not go well together are broadcaster/director/host and instructor (goes well until there is a problem; co-teaching solves that partly) + + +#### Episode 4: Sound +https://coderefinery.github.io/train-the-trainer/sound/ + +- To me, Richard is a bit quieter than the other two :+1: :+1: :+1: + - to elaborate: I think that the audio coming from him is missing some mids + - Do you have any links about this kind of evaluation and adjustment? + +- Do you suggest / recommend a specific headset(s) with mounted microphone? + - in our experience headsets with a microphone will almost always be better than a separate microphone sitting on the desk or in the monitor + - + +- Speakers have different tones of voice and speaking styles, is there a recommendation or experience from CR workshops for how this is adjusted and catered to environemnts for listeners? + - Yeah, people's voices are different and we haven't gone as far as voice training or improving. + +- How to change the volume for speakers? Tried Zoom settings and system settings and didn't help. + - From linux I can use different pulsemixers `pavucontrol`, `pulsemixer` to set the gain to above 100%. I'm not sure the equivalent on other OSs but + +--- + +:::info + +Exercise until xx:10 +https://coderefinery.github.io/train-the-trainer/sound/#exercises +::: + +- room 1 + + - Practically, no typical headset is designed or can capture the technical purity of human voice within its natural environment. But one needs to understand the polar pattern of the (specific) microphone or how much of the signal will be picked up by the microphone from different directions, a sine qua non when it comes to mitigating unwanted sound sources to bleed into the signal. + +For best results, keep the right direction & distance to your (directional) mic. Usually, that’s between 15-30 cm to get get a natural sound. A microphone records everything it can, also silence, so check the headphone output BEFORE adjusting the gain, in some specific cases aim for a dry sound, ie the influence of the room or how audible the room is on the recording ! Finally, adjust the mix between dry and room sound, or change the frequency response in tandem using a compressor to reduce the dynamic range of a signal for a more consistent listening experience = the quietest parts of your signal will appear louder by reducing the loudest parts. + +It is all about one thing and one thing only - love your voice, let people fall in love with the acoustic quality of your charm. So remember: GIGO, it matters! + +- Room 3 + - Had different headsets and we could see the difference (bluetooth low quality) + - How to change the volume? + - It's surprisingly hard to get more control than the basic slider you see in the apps! You need to look. + +- room 4 + - headset is probably better listening experience but they can be uncomfortable to wear during long meeting days :+1: + - Yeah. Luckily only instructors + - Therefore breaks are non-negotiable + - loud keyboard can be an issue + - if one has a silent room that does not echo, it can be ok to teach without headset + - on Linux I am using `pulsemixer` to adjust levels and `pavucontrol` to change outputs/sources + - mic modes on mac + - check default microphone for zoom. + + - room 5 + - Most tricks help tuning yourself but hard to do it as a group. Perhaps doing a short recording. + - Yeah. Some independent recording/playing aronud, but also asking for advice. I would do small group/one-on-one things. + - Background noises cancellation tools or wise choice of quiet environments + - Audio check with colleagues or through the app with the audience saying numbers for example + - Zoom or Teams have sound checks but work different in the app than the browser. They also work different across Operating systems + - Some sound issues might be related to network speed or stability, also to RAM available. Worthwhile to try and control those as well + - Make it welcoming for the audience to give you feedback on the audio and other settings, give reminders + + +#### Episode 5: How to prepare a quality screen-share + +Materials: https://coderefinery.github.io/train-the-trainer/screenshare/ + +- If your Zoom does not support "share portion of screen", sharing a tab and resizing it to portrait for yourself is a possible workaround (this at least works when joining the call from Chromium browser) + - Another workaround is to use an editor/IDE that displays multiple panels in one window and can show a web page, code files and terminal session +10 +- Is 'share a portion of your screen' where you draw a box in Zoom to share a section? + - yes :+1: + + +- When using zsh, one can run something like this in a terminal + ``` + tail -n $NLASTCOMMANDS -f ~/.zsh_history | sed 's/^.............../LAST COMMAND:/g' + ``` + (I place this in a window under the main terminal, I use i3) + +- I am a bit confused on what platform you are putting this code? + - Radovan is using Linux with (I think) the "i3 window manager". It can be quite involved and there is lots of personal customization here. +- When teaching with a custom prompt, is it worth starting with the default (that your learners will see) and explicitly mentioning "I change these things to make it clearer when teaching" + - One should always comment on what may be different. Thing is "default" may look different for many people :+1: + - "I am _not_ going to teach you how to customise your prompt, but here's an online tutorial, be prepared to lose several days of your life..." :laughing: + + +- Now I can't see the last line in the terminal + - Yep, that's a problem. It can be good to keep a buffer on the bottom of the screen. + - If you move your mouse outside the Zoom window, the controls should go away. But still a good note. + - My mouse was on another screen. + - Ok, thanks. + - I think one can also make the zoom bars not auto-hide (then it won't display under), but that is annoying also since it wastes space. + + +- Does anybody still use shellshare? Does it work? + - We in CR haven't used it much but we have seen it. + +- Does the stacking of the screens work on windows? + - Don't know unfortunately + + + +:::info +Exercises (done together) +https://coderefinery.github.io/train-the-trainer/screenshare/#exercises + +Write your cool tips and ideas below. +Stay after xx:00, to +::: + +- To be safe, I have created on my computer an account that I use only for teaching, so I do not need to do any manual set up +- share history or jupyter notebooks live (5-10 secs refresh rate) into a git repo. Share the link with the learners so they can catch up https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush + +--- + +### Wrapup + +- Next session Tuesday August 27 9 CEST: About teaching & cool things we all would like to share +- All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development) +- CodeRefinery community: https://coderefinery.zulipchat.com/ +- Cool gems session: If you want to share something, please edit your registration and fill it in there (link to modify in registration confirmation); or e-mail to support@coderefinery.org +- If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14:00 (Europe/Stockholm time) + + +### Feedback about todays session + +What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session: +- Sound and screen share optimization as well as relevant tools and good practices for online instruction. “While you may be unable to control your users’ mindset, you can anticipate it, and make sure that your user experience caters to it.” - Jonathan Cherki +- Nice opportunity to (re)think about my online teaching setup :+1: :+1: :+1: +- Other ways to display command history :+1: +- Did not know that bluetooth gear had so much latency! :+1: +- A good reminder about headsets with microphones +- Nice and friendly teaching. Thank you! +- Screen share with command history and terminal customisation +- Really useful tips on sound and screen sharing :+1: +- Nice experience share +- very useful and practical tips! +- Easy to follow along and filled with useful tips on sound, video etc. +- + +What one thing would you improve about this session? +- Just digging to find something: I have read some of the things you have talked about here already in some blog posts, so perhaps these sessions are not as shokingly full of new content as I imagined (but actually sharing experiences is something I can't do by reading a blog post) + - Perhaps: could you link some blog posts or other sources for what you have discussed so far? If it makes sense. Not sure. +- Talking about interface optimization approaches, which applies to sound as much as to visuals or any other aspect either for that matter, it might offer a perspective to bear in mind the concept of introducing asymptotic complexity increment. The latter would mean the goal is measuring how fast the effort of engaging, on one or more of the three parallel levels of interaction, must change to reach higher levels of partial certainty on the correctness of the implementation of the method in question, in this case the pedagogical paradigm. For the former, lower is better I guess, or in this case, in the intended sense, slower is faster. Let us consider an abstract example: People liked using the search engine Google (a Google session to put it in a fancy way) in the early days because it was as simple as it could get, a literally featureless entry point with no bells and whistles. That was the level of its visible complexity, or rather Google set a bar as low as it one could have, and then any higher point of VISIBLE complexity that was to be introduced, such a move would only be on the path of an asymptotic curve curving towards the set bar, never reaching it, as far as the entry point is concerned. We still see the same level of complexity when we fire up google and we never feel distracted to start with, except for the rather forgivable nuisance of the GDPR conformity pop-up notice which appears only AFTER the first move has been made, and thankfully it works plain and simple from there on (unless one starts feeling lucky, pun intended). Now, think about Youtube ... the user experience complexity is a totally different matter, the same company today (unfortunately) yet one now has a steadily worsening engagement experience. Good learning sessions tend to be more of the Google search engine experience and a far cry from the current Youtube trend I would opine. Or, to sum it up and keep it sweet and simple, it helps to identify the limits of human-human and human-technology interaction, within the framework of any applicable technology-technology interaction and joy is the result of respecting those limits. Wishful thinking ? +- Bring the cat back! + - I wish it came, but it's been resting all morning! I don't bother it or stage apperances... +- Maybe having a digest/ summary of previous iterations of this session might be interesting. I feel a lot of experiences have been exchanged and a lot of techniques/ tools have been mentioned. Spending some time in compiling this into a selected list and adding it as content to the course itself might be worthwhile. + - Good idea! We will write a blog post about this workshop and will include a summary of all discussions there :) +- Possibly have some command line examples from Windows rather than (just) *nix? I will look at the screenshots after the session. :+1: :+1: + - Also, a thought if you do do breakout sessions with this work, do one for Unix, one for Windows, one for Mac as an option. +- I could not follow the part Radovan showed codes (Radovan is using Linux with (I think) the "i3 window manager".) +- .. + +Any other comments? +- Looking forward to the topics of following sessions. +- Looking forward to the next sessions! +- Thank you! +- Relax, nothing else matters, live a life and have fun ! If you obey all the rules you may end up missing all the fun. 'The best way to predict your future is to create it.' - Abraham Lincoln :+1: + + +### Day 3 : sessiion 3 (27.08.24) - "About teaching and cool things we all would like to share" + +#### :calendar: Schedule + +| Time (CEST) | Title | EEST (UTC+3) | BST (UTC+1) | +|---------------|---------------------------------------|---------------|---------------| +| 8.45 - 9.00 | Connecting time | 9.45 - 10.00 | 7.45 - 8.00 | +| 9.00 - 9.15 | Intro and Icebreaker | 10.00 - 10.15 | 8.00 - 8.15 | +| 9.15 - 9.45 | Computational thinking | 10.15 - 10.45| 8.15 - 8.45 | +| 9.45 - 10.00 | Break | 10.25 - 11.00 | 8.25 - 9.00 | +| 10.00 - 10.30| Teaching philosophies | 11.00 - 11.30 | 9.00 - 9.30 | +| 10.30 - 11.00 | Co-teaching | 11.30 - 12.00 | 9.30 - 10.00 | +| 11.00 - 11.15 | Break | 12.00 - 12.15 | 10.00 - 10.15 | +| 11.15 - 11.50 | Sharing teaching gems (voluntary) | 12.15 - 12.50 | 10.15 - 10.50 | +| 11.50 - 12.00 | Outro and feedback | 12.50 - 13.00 | 10.50 - 11.00 | + + +#### :icecream: Icebreaker + +##### Check-in + +Which emoji best describes your current state of mind? [Emoji cheat sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) +- ... +- :sleeping: +- :coffee:+2 +- :robot: +- Still little sleeppy :) +- 🥴 (:woozy_face: still not converted 🤷‍♂️) +- Our planet could be a cube. It has six sides to it. It must be a cube. A cube it is, this Blue Planet ... just wondering ... +- 🦾 +- :sweat_smile: +- computer says no :-) some network trouble +- running late, and participating from a :train2: + + +##### Introduction in breakoutrooms + +Name / Affiliation / Location + +##### Best classroom experiences + +As a learner or teacher; what was the best workshop/lesson/seminar you have attended? What made the experience great? + +- Room 1 + - First summer HPC streamed workshop (as a teacher). Somehow the first felt the best + - CSC HPC summer workshop + - story telling teaching approach +- Room 2 + - NVIDIA DLI Course on Deep Learning + - very enthusiastic instructor + - intuitive and very accessible way of showing technical details and fostering deeper understanding + - a lot of hands-on material and smaller coding exercises + - Anything as long as its interactive and somehow enjoyable from both teacher and learner sides +- Room 4: + - EPCC MPI Distributed training workshop. + - Lots of hand on coding / experience gained. + - Very interactive instructor who also discussed ideas for more personalised cases of distributed computing. + - Coderefinery RSE course + - relevance of topic to my current work. + - Dynamic / friendly / positive teaching style. + - Modular Code Development; very instructive + - Some CSC courses / LinkedIn learning courses + - up to date materials and topics. + - Good way to merge theory with practicalities without making learner feel bored (Example: Jonathan Reichental) + - Challenging information to learn more and research about the topic + - Trainers are the experts in the field + + +:::success + +##### Episode on teaching gems + +If you want to share or demo something about tools and techniques you have found helpful in your teaching, please add your name/initials and rough topic below for smooth transition. + +> Note: It does not have to be your tool or your idea, this episode is meant to share experiences and discover new things. You also do not need any slides or materials, a story will do fine :) +> Length of the stories will be depending on interest, but be prepared to fit it into 3 min (shortest possible). + +- RD: teaching clock +- RB: [Containerized teaching setup](https://github.com/bast/teaching-setup) + - Isolated home dir is a good idea! +- AVM: [Screenkey for showing keyboard shortcuts](https://www.thregr.org/wavexx/software/screenkey) + +::: + +--- + +### :question: Questions + +#### General / Practicalities + +- What is this document for? + - Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts) +- Will the material be made available? + - Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/ + - Can I share them with a colleague + - Yes please :) + - Can I resuse them in my own teaching? + - Yes please :) +- Will these sessions be recorded? + - No, but the materials (see above) should include everything needed for self-learning. +- Can I get a certificate for this workshop? + - You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended. +- How often will we be talking in breakout rooms? + - We'll have about one breakoutroom session per episode + + +--- + +#### Episode 1 : Computational thinking + +Materials: https://coderefinery.github.io/train-the-trainer/computational-thinking/ (Link to slides in the middle of material) + +##### Questions to audience + +How might breaking down a complex problem into smaller parts change your approach to problem-solving in your current projects? + +- Avoids cognitive overload +- I used to give an example about this in workshops of cutting long tree into pieces from top to avoid that it falls and destroy a house bloc. +- Easier to start on something small +- Each individual part is familiar and can take existing solutions. +- Only focus on the new things +- One can lose oversight of where is supposed to be getting to due to problems with summation of biases introduced during the solving of the parts. +- . + +Can you think of a research project where identifying patterns in your data led to new insights or breakthroughs? +- Multi-targeted drug design where you need to identify both chemical and biological pathways/patterns +- Distilling complex physics problems into simpler 1D statistics is very often done. +- I used to do bioinformatics, pretty much everything in biology is about patterns in strings of charachters (DNA, proteins). Finding those patterns and using them is the way to go +- Pattern recognition DOES NOT lead to new insight, it is new insight which allows for the recognition of a 'pattern', the latter being an allocation of possible bias. +- +- .. + +What challenges do you face when trying to simplify complex concepts in your field, and how do you decide which details to focus on? + +- Absence of a terminology / jargon to describe a new idea. :+1: +- Similar to above, when teaching often students know what they want to achive, but don't have the termonology to express it, so working through what they want is helpful, after teaching them some termonology. +- Whatever is most useful to the learner first? +- I work with researchers in different fields. I don't always fully understand their domain knowledge but I can take the basiscs or generalities and get code that works for them +- A very practical problem is trying to resist going for a coffee in the midst of taking a shot at a complex concept, in the hope that the true details are to be found in the coffee. +- not all information is easy to find or a lot of conflicting information or even sometimes imformation explosion + + +How do you determine the priority of tasks when designing algorithms for your academic projects, and what criteria do you use to ensure that the most critical tasks are addressed first? + +- Working chronologically when going through a problem - start at the beginning. +- What gives the more insight with the least effort can be a nice start +- Talk to colleagues and Subject matter experts to understand various perspective to decide and prioritize. +- Logic will get you from A to B. Imagination will take you everywhere. - Albert Einstein. +- .. + +##### Questions from the audience + +- About the 4 core concepts, is this based on the model of how human brain works and perceives vision / abstract ideas? + - I don't know if it's based on how the brain works, but it's related to creating a framework for solving programming programs that has been extrapolated to solve any other problem as well. + +- Devil's advocate question: cooking (by recipe) actually employs all four principles outlined here and has done so since before the advent of computers. Why then is this concept presented as "computational"? + - Random aside, this is an interesting connection to our "cooking metaphor to HPC" +- Devil's answer to the Devil's advocate: Great question, cooking, as far as the act happens in the Devil's kitchen, does not employ numerical algorithms. The Devil introduced the computer precisely to make man lose apetite for that what is cooked in the Devil's kitchen to be served to all. Only then can the Devil eat the cake and keep it too ... + - Well, an algorithm without numbers is still an algorithm, i.e. a set of rules :) + +- Are there other names for this technique? I may have missed something crucial, but it strikes me as 'logical thinking' in a way. + - Yes, you could also just see it as problem solving. Most people know how to do it and if you've worked with programming, you've probably applied it. It can be the case that it's very obvious to some, but not to others. + +- Any chance we can ge a link to the slides? + - They are in the course material: https://coderefinery.github.io/train-the-trainer/computational-thinking/ :thumbs_up: + + +##### Exercise questions to discuss + +1. Conceptually would the strategies provided by computational thinking help you in completing tasks more efficiently? +- Room 1: + - divide and conquer technique + - We discussed what happens if you *don't* use these, since they are so natural +- Room 2: + - in some cases yes, if the task is not too small + - not sure if more efficiently but it does help at least getting strted + - Computational thinking is an extension of what others have called solutionism: the belief that any given problem can be solved by the application of computation. Whatever the practical or social problem we face, there is an app for it. - James Bridle +- Room 3: + - Helps in starting the task. + - For many it is the normal way to do problem solving. Also in Agile & Scrum methodlogies. +- Room 4: + - Yes, it helped me during my scientific research to manage multiple projects and research publications simultaneously. + - + + +2. Do you think that the effectiveness of computational thinking depends on the person’s personality type? +- Room 1: + - yes, we agree it's quite different. But good vision and motivation this can be effective +- Room 2: + - yes, laying out all the steps necessary to achieve an overall goal can be very daunting; some people are not good at/ comfortable with following fine-grained instructions + - once the problem is broken down, different personalities might choose different ways to tackle the parts + - The degree to which something, that is a result of what one means by 'Computational Thinking,' is successful in producing a desired result, that is success, cannot be a function of personality. +- Room 3: + - Yes. Different people have different ways to communicate. + - Online tools vs pen and paper +- Room 4: + - We are all agree that it depends on the personality type but it could be learned and trained + +3. Would this type of thinking be an option for you to integrate into your current workflow? +- Room 1: + - Yes; we didn't know the name explicitly; but we use it + - It's quite important for +- Room 2: + - I'm already doing it implicitly :smile: :+1: :+1: + - Writing a program is like writing a song, its all about the tune, lyrics are merely the necessary nuisance a coder needs to put up with. The latter can, if so written, result in a lot of noise. +- Room 3: + - Easy if you are working alone. But different team may have their own ways of working (inertia). One way would be then to gradually show the rest of the team its effectiveness. + - https://teamtopologies.com/key-concepts + +- Room 4: + - We are using it in our daily life so it's already an option for us, only the terminologies are a bit new. + + +#### Episode 2 : Teaching philosophies + +Materials: https://coderefinery.github.io/train-the-trainer/teaching-philosophies/ + +Questions to discuss: +- Share your approach to teaching and your teaching philosophy with your group. +- Please share your tricks and solutions in the live document for others. + +Additional ice-breaker questions: +- What is your motivation for taking this training? +- How structured or informal are your own teaching needs? +- What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching? +- What other skills need to be taught, but academic teaching isn’t the right setting? + +#### Breakout Room exercise + +- Room1 + + - Motivation + - For best practices in teaching, learning from each other, collaboration + - Learning applied tech is like an apprecentiship: there is theory, but real learning happens by co-working with others. + - Worse is better: teach what can be used more quickly and it can be improved later + - + - I think there are two bits of teaching - teach the basics and terminology so people know what they want to know, and then teaching how to find out how to do things like Richard said - how to find answers yourself. + - Using Jupyter notebooks - good for learning a technique, but not for learning the basics. + - Possibly command line usage has a branding problem - "programming other programs"? + - the skills we learn in CR training are expected to stay , it is not exam oriented + +- Room 2 + - State objectives clearly and repeat them a few times + - Try to keep it informal, interactive, flexible + - Helps when having practical tasks in mind for the materials taught + - Leave some reasoning to the learner, not always giving full answers + - How to deal with frustration though: try some personal approaches, more clues... + - The mediocre teacher tells. The good teacher explains. The superior teacher demonstrates. The great teacher inspires. — William Arthur Ward + - Teaching kids to count is fine, but teaching them what counts is best. –Bob Talbert + +- Room 4 + - Question 1: What is your motivation for taking this training? + - Currently do instruction, wanting to improve as an instructor and helper when conducting software carpentries. + - Planning to start some side hustles providing online courses and why not joining the CR in the near future + - Question 2: How structured or informal are your own teaching needs? + - More recently, follow software carpentries, but look into what aspects can be tailored to keep to different time slots. + - I used to be more informal in the past, repetetive practice sessions. Would like to be more structured given the teaching tools. + - I've done life-coaching and some teaching but I feel i'm both of them + - Question 3: What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching? + - Smaller size, and more targetted. + - Collaborative tools and targeted audience working with small groups + - Academic probably focuses on an audience with a more focused/narrow background, while this style encompasses a wider audience. + - Academic teaching keeps theory and practical lab sessions very separate, whereas carpentries combine both. + - Question 4: What other skills need to be taught, but academic teaching isn’t the right setting? + - Public speaking, collaborative meeting skills + - Industrial cases and related work skills + + +#### Episode 3: Co-teaching + +Materials: https://coderefinery.github.io/train-the-trainer/co-teaching/ + +- In general: Co-teaching is a beast with at least two personalities each of which + * demand higher preparation requirements + * face remarkable complexity in terms of coteacher coordination + * in the virtual component face shortcomings related to the technical equipment and the failure of the human factor +* Co-teaching requires the framework of co-operative learning. Team teaching does not by default translate into parallel learning, and vice versa. + +- Re: CodeRefinery in-person beginnings -- I agree with the "didn't work so well in-person", I'm not sure if it's that we weren't as ready for it, or that the different characteristics made it not work so much + +- How do the downsides compare to a single instructor monologuing? + - That's a great question! The main difference is that a single instructor can teach himself to be good (i.e. not just boring monologuing) **alone**, while for teams of 2+ to work well, **everyone** needs to be baseline-competent. So the effort to avoid downsides gets reduced if (and only if) all team members share it. + + +:::info + +Exercise/Discussion: https://coderefinery.github.io/train-the-trainer/co-teaching/#exercise + +Questions: +- Have you already tried this or similar model in your teaching? +- Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best? +- Have you tried or seen a different model for two instructors to present? Please share with us how it works. +::: + +- room 1 + - We have tendend to do presenter/interviewer more + - challenges are co-teaching with different personalities +- room 2 + - Main challenge: finding enough personell :smile: + - It's not always possible/feasible to have colleagues co-teaching + - A combination of both, but presenter and interviewer could be difficult to plan an to follow + - Guide and demo-giver with technical / non-technical roles could be nice + - How to plan the guide and demo-giver + - First guide, then demo + - Demo, then guide describes + - Alternative model: main presenter + 'technical expert' + - main presenter introduces concepts from a birdseye view and passes on to the technical expert for additional details, experiences and answers to questions from the audience + - We frequently do a classical division: on person in presenting, one or more are answering questions in the chat; there is rarely any interaction between them however + +* As has been pointed out by Paolo Freire, in general, ‘education is suffering from narration sickness’ ... ‘The outstanding characteristic of this narrative education, then, is the sonority of words, not their transforming power’. Perhaps one approach could be to rephrase the question after having the answer: It is not apriori about the model implemented, it is about whether that what was implemented was judged aposteriori to have succeeded in becoming, or at least could pretend to have done so, the intended context matched model implementation it probably was computed to be. + +- room 4 + - the co-teaching approach does not seem to be widely practiced + - it can be interesting to see "mistakes" which are less likely to happen in solo-teaching? + - co-teaching can be nicer for audience but maybe more stress/anxiety for instructors to prepare? more stress in terms of not knowing all the questions in advance. less stress worrying about forgetting something. + + + +#### Teaching gems + +(scroll up to find the green box "Episode on teaching gems") + +What's your favorite way of teaching? Any nice tools you use? + +Has anyone found a nice online tool to draw? +- I love this tool suite https://excalideck.com/ + - For drawing https://excalidraw.com/ +- I have seen Miro ... +- I think the Code Refineries use something for their graphics that looks a bit 'cartoony' - but I cannot remember what it is called! + - Drawn on remarkable and then coloured and tidied up in Inkscape. :+1: +- I am a big fan of remarkable. I think sharing option is fairly good. Unfortunately bit expensive tool. + - true, for me it was worth it already for the pdf annotation for research papers, cannot read on computer screen +- https://webwhiteboard.com/ +- https://www.youtube.com/watch?v=4-l8MY5kYGc +- Figma and Kahoot are useful as well + +Screenkey: [Screenkey for showing keyboard shortcuts](https://www.thregr.org/wavexx/software/screenkey) +- Is there a Windows version people can recommend? + - I found this list of alternative for windows users like me: https://alternativeto.net/software/screenkey/ :+1: +- I sometimes use the on-screen keyboard already provided by the OS :+1: + +### Wrapup + +- Next session Tuesday September 3rd 9 CEST: About teaching & cool things we all would like to share +- All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development) +- CodeRefinery community: https://coderefinery.zulipchat.com/ +- If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14 CEST + +- Preparations for next week will be sent out by e-mail + +### Feedback about todays session + +What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session: +- The co-teaching lesson and experiences from others +- Discussions were quite good, had a nice group +- Breakout rooms and collaborative tools +- Computational thinking and co-teaching are interesting ideas! I have seen it before, but never knew or even recognized it was a method. +- Thanks for group discussions working with my chat only interaction! :smile: +- .. + +What one thing would you improve about this session? +- Minor point - it would be useful to have the teaching gmes box at the bottom of the document rather than the top - tricky to scroll between! In the end I opened two windows which was easier. + - Thanks, yes agree. Also had that problem, but did not want to move it in between. +- The meaning of teaching "philosophy" wasn't very clear, felt more like teaching "styles" + - Thank you, we will take that into consideration +- Some prepared slides to present for an intro about the topics + - You mean in addition to the materials? To use in the beginning of each session? +- The [*instructor views*](https://coderefinery.github.io/train-the-trainer/teaching-philosophies/#instructor-views) segment could be named as additional material, if it was not meant to be discussed within the course. + - Thank you, we will take that into consideration + +Any other comments? +- Keeping it short and sweet: If at first you don't succeed in teaching, try to explain it like you're talking to a room full of cats. Caveat: In a room full of computational thinkers maybe if you tell students that the brain is a computational device that is forbidden, they might get excited and start using it. + +### Day4: Session 4 (3.09.24) - Streaming and video editing + +#### :calendar: Schedule + Time (CEST) | Title | EEST (UTC+3) | BST (UTC+1) | +|---------------|---------------------------------------|---------------|---------------| +| 8.45 - 9.00 | Connecting time | 9.45 - 10.00 | 7.45 - 8.00 | +| 9.00 - 9.15 | Intro and Icebreaker | 10.00 - 10.15 | 8.00 - 8.15 | +| 9.15 - 10.00 | Why we stream & Behind the scenes | 10.15 - 11.00| 8.15 - 9.00 | +| 10.00 - 10.15 | Break | 11.00 - 11.15 | 9.00 - 9.15 | +| 10.15 - 10.35 | Video Editing | 11.15 - 11.35 | 9.15 - 9.35 | +| 10.35 - 10.55 | Exercise: Video Editing | 11.35 - 11.55 | 9.35 - 9.55 | +| 10.55 - 11.10 | Break | 11.55 - 12.10 | 9.55 - 10.10 | +| 11.10 - 11.30 | Open Broadcaster Software(OBS) introduction | 12.10 - 12.30 | 10.10 - 10.30 | +| 11:30 - 11:50 | OBS setup & what next | 12.30 - 12.50 | 10.30 - 10.50 | +| 11.50 - 12.00 | Outro and feedback | 12.50 - 13.00 | 10.50 - 11.00 | + +#### :icecream: Icebreaker + +##### Check-in + +Which emoji best describes your current state of mind? [Emoji cheat sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) +- :coffee: + +- :runner: +- :tired_face: Tired! +- :nerd_face:![](https://) +- ![](https://notes.coderefinery.org/uploads/58bfdc31-ac86-4172-aef4-b7b4bd762533.png) +- :cloud: :tea: + +##### Introduction in breakoutrooms + +- Name / Affiliation / Location + +What's the most number of people you have taught to? +- 20 at a time, with 1 asleep, 2 fidgiting with some silly device and the rest were... well... staring at their good luck... straight ahead it was of course, right before them. +- ~35 +- ~80 in a lecture in a previous (lecturer) role, 26 in a training course setting +- ~30 +- ~50 in training spaces and more than 100 for public audience talk +- 35 (software carpentry) +- CodeRefinery answer: The biggest ones are maybe 200-300 people. "small" for a stream is ~100 people. + +What's the most number of people you have taught with? +- 5 or so +- 2 or 3 in total +- 3, as in three, none of them smiling. I wish I could figure out why... it was such fun really... +- 7 +- 2 or 3 +- 3 (helpers, not really co-teaching) +- CodeRefinery answer: our biggest workshops are something like 10-20 people helping out in many different roles. + +How can you divide teaching into separate independent tasks? +- By content blocks, having roles like main and assistant... +- Having responsibility for different sections of the course. +- Wow, now thats what we call a question... bravo... indeed, how does one separate sleeping and snoring into separate independent tasks... +- Course, exercices, resources, tools and forms. +- Different people teach different topics +- CodeRefinery answer: the big logical blocks are instructors, in-person and breakout room helpers, and Notes-questions answers. + +What’s the most interesting or useful thing you’ve learned from an online workshop, and how have you applied it/planning to apply in your life or work +- Having breaks every hour or so +- New approach to screensharing, using the 'portrait' approach +- Manage breathing: reduce stress and use silence to let the audience grasp what you're saying +- Well, the most interesting or useful thing I’ve learned from online workshops is how not to conduct a workshop, or at least some elements of the same, and I have applied this understanding by engaging in the global effort to discover more about how not to conduct a workshop, or at least some elements of the same, with the motto: That's one small step for a man, one giant leap for mankind.. + +#### :question: Questions + +#### [Why we stream](https://coderefinery.github.io/train-the-trainer/why-we-stream/) + +- If during streaming there is no interaction between the teacher and the audience, why don't we just record the lectures and stream them? So one can do a better job, perhaps? + - Streaming it making it a "thing" that's a group experience. It feels good to be a part of it, so we hope that encourages people to actually attend. All the mass Q&A is fun, and the audience helps to make it easier to present. Still, this is a good question. + - I really appriciate it being "a thing". If it was just recorded, I would say I would watch it tomorrow, and then I never would. + - But then you can just fake it, and still have all the breakout rooms and collaborative document and so on. I appreciate the value of having a proper "event". + - I think I follow you, but if you pre-recorded the talking bits, then the presentors couldn't change what they do based on the feedback in the shared document. + - true, but I assumed that the teachers were too busy to actually do that. The more (less )division of labor between the teachers and the helpers (or collaborative document editors), the more (less) sense it makes to pre-record - IMHO +- What interaction options do 'streamers' use, e.g. on Twitch/YouTube (not Code Refinary)? + - I'm besides chat and things that happen in chat, I'm not sure. The Notes-doc is definitely unique to us. +- Streaming is a kind of exercise for the movie star type. If you cannot be one, act like one, pretend, fool the listener into thinking you are one, take their brains and emotions under control. And if they don't leave the session with tears of love for learning running down their chubby cheeks you know who to kick for doing a job just that bit worse than it should have been necessary. +- Have you kept track of streming stats? like how many people logged in and stayed troughout, how many interacted? + - Yes please, it would be good to see the stats + - Here is stats [repo](https://github.com/coderefinery/workshop-stats) + - Thanks, I get a 404 error, is it private? + - No, I don't think so. https://github.com/coderefinery/workshop-stats + - Still get 404. Does it work for anyone else? + - Yeah I think it's private. We need to fix this... +- How big is small (10-15), medium (~30-40)? + - I would say below 50 is small. +- Have you considered scaling to more events instead of to a larger audience? I mean, this seems the opposite of scaling, but this kind of content would be more useful the more often is it taught ("I need to learn GIT/Python/* in December!") + - We would, but right now we simply don't have enough time and people to do more small events. But yes, "scheduling conflict" is a big problem - the best we can do right now is written material+videos to follow up on (and hope it's interesting enough) + - [Python for Scientific Computing 5-7/November/2024](https://www.aalto.fi/en/events/python-for-scientific-computing-5-7november2024) + - This was just an example. I mean, if I am a PHD student that needs to start working on a topic on Month X which happens to be inconveniently placed in the year, I will not benefit as much from having a workshop at Month X+3 + - The materials are open and the videos are publically available on YouTube channel + - What's the ratio of people watching videos afterwards vs people attending the event? That ratio can give an idea of the popularity of the two possible approaches. + - The more you scale up the less interactive the course / workshop will need to be. It then becomes a question of priorities, and if teaching is a lower priority then learning than I guess there really should be no prizes for guessing which approach should reign the airwaves. +- I guess outside Europe / Africa, time zones could be a problem? + - yes, that is true + - +- Sorry, I might have missed this: have you been rehearsing and/or doing dry runs? + - With instructors I like to try to do a dry run. I often don't do a live broadcast dry run these days since I'm confidente enough, but when you are just starting, it's a good idea. +- Do you always use Zoom for the 'presenter end' or have you tried other things? Teams? Jitsi? etc.? + - we use mostly zoom + - It was first pioneered using Jitsi. You can probably use others, too. + +- A comment: for deRSE24 we have been using the [GWDG streaming service](https://docs.gwdg.de/doku.php?id=en:services:mobile_working:live_streaming:start) and OBS, it worked quite well (with a 20s delay or so) + - Cool! Yes, there is plenty of livestreaming options. Twitch+our OBS config gives us 2-3s of latency (which is low enough for live Notes interaction). You might be able to tune this if needed. + +#### Behind the stream + +- Does OBS take a lot of RAM or CPU? what are the specs on your machine? + - Richard have a relatively powerful computer with 8 AMD CPUs. + - 4 CPUs are relatively enough for a good OBS setup, most important is a stable internet connection (ideally wired). + - An extra monitor is recommended for the setup + - See the hardware notesrecommendation [here](https://coderefinery.github.io/train-the-trainer/obs/#hardware-requirements) +- Do you do a screenshare from Zoom -> OBS or OBS -> Zoom? + - Instructors share to Zoom, OBS captures Zoom, OBS sends to the world. + - When I am using OBS sfor a single-person presentation recording, I go the other way: OBS captures my desktop/camera, OBS generates the preview window, and then Zoom captures and broadcasts the preview window. + + +#### [Video editing](https://coderefinery.github.io/train-the-trainer/video-editing/) + +##### Poll +- Have you tried video editing? Add an`o` as answer below + - yes: ooooo + - no : + - Video editing makes all the difference. I have never known a way to avoid this sacred of steps, so to speak. In short, no recording can ever be production ready by default in the books of the wiser among the streamers. In fact, during the editing one can considerably refine and improve the learning experience in great ways. But then one would need to invest both time and effort. + +- If `yes` Which are the tools you use? + - Windows Movie Maker / ClipChamp + - (raw stream from Zoom) + - I think it was shotcut - I did only basic trimming + - Kdenlive + - Clipchamp, OpenShot, Sony Vegas + - also ffmpeg from command line to cut beginning and end + +##### Questions +- What is Whisper? + - Open-source model from OpenAI that converts speech to text transcripts. + - this one? https://openai.com/index/whisper/ + - curious if anyone has tried it with languages other than english + - I heard that one of my spanish colleague try it with another software. I don't remember the tool. But with AI bloom there are many licensed tools that can do it with fifferent language + +- What do you use to crop the videos? + - I see now, ffmpeg + +- how to merge multiple parts in one? I asked because you edited only the icebreaker part? + - you can manage it in input part, see ffmpeg-editlist readme. + +- Do you generate custom thumbnails for the video? + - no, because of the time, but its good to have. If we had a volunteer to manage that, then we should! + +- Does anyone recommend any other (GUI) tools that work well? ffmpeg is very new to me! + - if you want a basic trimming and editing , you can use Quicktime player/imovies on mac + - Clipchamp as the Microsoft video editor + - Thanks :smile: + +- How do subtitles get uploaded to YouTube? + - You upload the video and subtitles as part of upload. + - :+1: + +- How does codewhisperer compare against youtube's automatically generated subtitles? + - by experience, whisper was better couple of years ago. We haven't compared it recently + - I guess and advantage is that you can edit whisper subtitles in case something is odd or whatever, probs cannot do that in YouTube + + +#### [Open Broadcaster Software (OBS) introduction](https://coderefinery.github.io/train-the-trainer/obs/) & [setup](https://coderefinery.github.io/train-the-trainer/obs-config/) + +- Are the profiles public? + - Yes, you can see it [here](https://coderefinery.github.io/train-the-trainer/obs-config/#coderefinery-obs-configs) +- Does it work in Linux+Wayland? + - I think everything we do with OBS would. + +### Wrapup +- All workshop materials will stay available (and be put on Zenodo right after the workshop) +- Upcoming Workshops + - [CodeRefinery workshop September 10-12, 17-19, 2024](https://coderefinery.github.io/2024-09-10-workshop/) + - [Build Systems Course and Hackathon](https://www.kth.se/form/build-systems-course-and-hackathon-part-i) + - [Python for Scientific Computing](https://www.aalto.fi/en/events/python-for-scientific-computing-5-7november2024) + +- CodeRefinery community: https://coderefinery.zulipchat.com/ +- If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org +- A summary email will be sent out to all participants + +### Feedback about todays session + +What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session: + +- ffmpeg seems great, will give a try for fun! +- great to see everything in practice! +- Very insightful to see what happens behind the scenes. + +What one thing would you improve about this session? + +- Some more interactivity would've been nice but since most the group preferred demo instead of exercise perhaps it's only a personal opinion +- It would have been good to share the OBS profiles repo beforehand in the setup email - so I could have had it to hand. (https://github.com/coderefinery/obs-config) + - +1 good idea, we should do this next time +- Perhaps a simpler starter OBS setup? + - Good idea... I should have, but basically ran out of time to prepare. + +Any other comments? + +- Cool to see the switch from RSE to trainer to AV guy, impressive! + + + diff --git a/branch/cff/_sources/obs-config.md.txt b/branch/cff/_sources/obs-config.md.txt new file mode 100644 index 0000000..df5e530 --- /dev/null +++ b/branch/cff/_sources/obs-config.md.txt @@ -0,0 +1,93 @@ +(obs-config)= + +# Open Broadcaster Software (OBS) setup + +:::{objectives} +- See how to configure OBS using the pre-made CodeRefinery scene + collections +- Modify the collections to suit your needs. +::: + +:::{instructor-note} +- Teaching: ?? min +- Hands-on: ?? min +- Q&A: ?? min +::: + +:::{See also} +* The previous episode {doc}`obs` +* [OBS theory in CodeRefinery manuals](https://coderefinery.github.io/manuals/obs/) +::: + + +In this lesson, we'll see how to configure OBS from scratch for your +purposes. We'll do this by deleting the instructor's configuration +and trying to recreate it + +This section is short, since it has never been done before: we'll just +give it a short and update the lesson later. + + +## CodeRefinery OBS configs + +- CodeRefinery configs are shared in a repository: + +- These can be imported to pre-configure some things +- There are two types of configs: + - Profiles + - Servers, resolutions, audio, video, etc. + - Scene collections + - The graphical layouts. + + +## Installing the OBS config + +- Clone the git repository. +- Import the profile and scene collections under their respective + menus. + + +## Initial setup + +- Click through each menu and change anything that is needed +- Set the streaming server + +:::{demo} The instructor will go through the setup. + +- Reset configuration: `mv .config/obs-studio/ + .config/obs-studio-old/` +- Import `profiles/TeachingStreamingv3/` +- Import `scenes/TeachingStreamingZoomv3.json` +::: + + + +## Set up the remote control + +- Create a Python environment and install it: `pip install https://github.com/coderefinery/obs-cr/archive/refs/heads/master.zip` + +- Run it: `python obs_cr/control.py localhost:4445 TOKEN + --broadcaster` +- There are more options but let's not cover them yet... and leave + this for a hands-on session. + + +## Setup before each course + +- Re-confirm audio +- Re-confirm each scene +- Test everything +- rkdarst has a [rather long + checklist](https://docs.google.com/spreadsheets/d/1g8Bc_76OPcv1vYWtB54wz6HsXQcb3B1GtQFga4Oanw4/edit?gid=0#gid=0), + but each individual step is short. + + +## Q&A + +We'll answer audience questions. + + +:::{keypoints} +- Most of our configuration has been OBS may seem complicated, but it's a graphical application and most + pieces make sense once you know how it works. +::: diff --git a/branch/cff/_sources/obs.md.txt b/branch/cff/_sources/obs.md.txt new file mode 100644 index 0000000..8db24f4 --- /dev/null +++ b/branch/cff/_sources/obs.md.txt @@ -0,0 +1,74 @@ +(obs)= + +# Open Broadcaster Software (OBS) introduction + +:::{objectives} +- Understand that OBS is a video mixer. +- Understand the basic controls and features of OBS. +::: + +:::{instructor-note} +- Teaching: 15 min +- Q&A 5 min +::: + +:::{See also} +* [OBS theory in CodeRefinery manuals](https://coderefinery.github.io/manuals/obs/) +* The next episode {doc}`obs-config` +::: + +In this episode, you'll get more familiar with the OBS portion of the +streaming setup. You'll see how it's used, but not yet how to +configure it from scratch. You'll learn how to be a "director". + + +## What is OBS? + +- Formally "OBS Studio" +- Most commonly known as a livestreaming application. +- Open source, free. +- Cross-platform, easy to use screencasting and streaming application. +- Real-time video mixer. + + +## OBS user interface + +- We'll click through each view. +- What does each view do? +- Let's click through the buttons. +- Let's see the important config options. + + +## OBS during a course + +- What management is needed. +- The control panel. +- Audio. +- Adjusting windows and so on. + + +## Hardware requirements + +- Reasonably powerful broadcast computer + - CodeRefinerys streaming computer is 8 CPU AMD, 64GB memory + - That is way overkill: a powerful laptop can probably do this. +- Large second monitor for laying out the windows you capture +- Stable internet connection (wired preferable) + - CodeRefinery's broadcast is the slowest purchasable: 100 Mbit down / + 25Mbit up + + +## Q&A + +We'll answer audience questions. + + +## See also + +- The next episode {doc}`obs-config` which is about configuring OBS. + + +:::{keypoints} +- OBS may seem complicated, but it's a graphical application and most + pieces make sense once you know how it works. +::: diff --git a/branch/cff/_sources/overview.md.txt b/branch/cff/_sources/overview.md.txt new file mode 100644 index 0000000..aaa3395 --- /dev/null +++ b/branch/cff/_sources/overview.md.txt @@ -0,0 +1,185 @@ +(workshop-overview)= + +# A workshop seen from different perspectives + +:::{objectives} +- Understand the general structure of CodeRefinery workshops and why it is the way it is +- Get to know the different roles of a workshop and which ones are the most essential ones +- Understand the importance of installation instructions and how they contribute to learners success +- Understand the importance of onboarding and a welcoming community for volunteers in a workshop +::: + +:::{instructor-note} +- Teaching: 20 min +- Exercises: 15 min +- Roles journeys can be shortened to looking only at instructor role. +::: + +:::{note} +This episode focuses on the large scale streamed workshop setup. Some of the features can also be applied to smaller scale workshops though. +::: + +## Discussion + +:::{discussion} +In breakoutrooms: choose one or two questions to talk about your own experiences; summary in collaborative notes: +- What kind of roles have you been in yourself regarding workshops? +- How were you prepared for your role? +- What are the things you would like to know before a workshop? +- How are you preparing your participants for your trainings? +- What was the best workshop experience for you as learner, helper or instructor? What made it great? +::: + +## One workshop - many parts + +```{figure} img/CR_workshop_setup.png +Image showing the different phases of a CodeRefinery workshop described below. Also showing that while there is only two people teaching, many people work behind the scenes. +``` + +### Before the workshop + +- During winter/summer: "Someone" takes the coordinator role for the next workshop +- Coordinator fills other roles: + - Coordinator: collects necessary lesson updates, supports other coordinators + - Registration coordinator: Sets up web page, starts and manages registration + - Instructor coordinator: Finds instructors and onboards them + - Advertising coordinator: Prepares advertizement texts and finds people to distribute them + - Team coordinator: Gathers local organizers/teams + - Bring your own code session coordinator: If available, offer BYOC session after main workshop +- Instructor: Onboarding with (instructor-) coordinator and previous instructor of lesson; update of lesson materials (urgent issues and personal touches) +- Local organizer/Team lead: Group [onboarding](https://coderefinery.github.io/manuals/team-leaders/) ~ week/or two before workshop +- Learner: Gets [installation instructions](https://coderefinery.github.io/installation/), invited to installation help session, workshop info from event page and summary via e-mail +- Collaborative notes manager sets up the notes document + +:::{note} +#### [Onboarding manuals](https://coderefinery.github.io/manuals/team-leaders/) +- **Outline of what will happen during the workshop** +- Discussion of different strategies to handle the exercise sessions +- Lowering the barrier to ask for support by meeting some organizers +- Q&A +::: + +:::{note} +#### [Installation instructions](https://coderefinery.github.io/installation/) +- Instructions for all operating systems +- Goal: Learners leave the workshop and are ready to apply the learned tools and techniques to their own work +- Support session for installation challenges +::: + + + +### During the workshop + +```{figure} img/BYOC.png +Image showing the different ways learners can do the exercises. No matter which way they choose, they always watch the stream and interact with instructors and organizers via collaborative notes. Individual learners do the exercises alone, people in online or local classrooms in addition get to discuss with their peers. +``` + +- Everyone watches stream +- Co-instructors + - Present content + - Answer questions in collaborative notes +- Collaborative notes manager + - Keeps the collaborative notes clean + - Helps answering questions + - Adds sections + - Archives the document after each day +- Learners do exercises individually or in team +- Local organizer / Team lead + - Guides learners through exercises + - Facilitates discussion +- (Registration-) coordinator sends out e-mails to participants after each day (summary + preparation) +- Director/Broadcaster manages the streaming (see session 4) + +### After the workshop + +- Coordinator collects lessons learned based on experience and feedback and turns them into issues +- Coordinator organizes debriefing week after the workshop, where anyone can join to give feedback +- "Someone" sends out post-workshop survey half a year after workshop +- Coordinator organizes "Bring your own code" sessions +- Broadcaster prepares and shares recording (see session 4) + +:::{note} +#### Bring your own code sessions + +We want to support learners to apply what they have learned in the workshop to their own work by offering one/two sessions where they can drop in, and discuss challenges with CodeRefinery instructors and helpers. + +```{figure} img/welcome.png +Image showing a classroom learning about git leading to a discussion between student and teacher to start a welcoming environment for asking for help. +``` +::: + +## This sounds like a lot of people and time investment! + +- Many roles can be combined or adjusted as needed +- Some roles can be taken on by multiple people + +So how many people are needed for this kind of workshop? +- Recommended minimum: 2-3 people +- Optimum: ~ 4-5 people +The more people you involve, the more time goes into coordination work. + +## How did we get to this setup? + +- **Collaborative** in-person workshops since 2016 around the Nordics +- Moved online in 2020 +- Started with "traditional zoom" workshops, breakoutrooms, volunteer helpers +- Thought about scaling and ease of joining -> current setup (More about this in session 4) +- Continuous development + +We also still do smaller scale local workshops, if instructors are available. +**You can offer your own CodeRefinery workshop** by inviting other CodeRefinery instructors. +You can also reuse single lessons and integrate them into your own teaching. + +## Workshop roles and their journeys + +### Individual learner journey + +- Registration +- Installation +- (if appicable: Invited to local meetup) +- Workshop + - Watch stream + - Q&A in notes + - Exercises alone or in team + - Daily feedback +- Debrief/ Feedback session +- Post workshop survey + +### Instructor journey + +- Indicate interest in CodeRefinery chat +- Onboarding +- Lesson material updates +- Teaching +- (if wished: supports answering questions in notes) +- Debrief + +### Team lead / Local host journey + +- Registration +- (if applicable: run own registration) +- Onboarding +- Workshop + - Watch stream + - Facilitate exercises/discussions + - Daily feedback +- Debrief / feedback / survey + +### Other roles + +Director and broadcaster roles will be discussed in Session 4. +For more in-depth descriptions and other roles (host, instructor, registration coordinator, etc), see also our [CodeRefinery manuals](https://coderefinery.github.io/manuals/roles-overview/). + +## Different roles as stepping stones for community involvement + +```{figure} img/steps.png +Image showing a person jumping from step to step following learner, helper, expert helper, co-instructor, co-organizer. +``` +There is no "one way" to get involved. Do what feels right. +Interested in teaching with us? Let us know and we can discuss what is a suitable path **for you**! + +:::{keypoints} +- CodeRefinery workshops are a collaborative effort with many different roles +- Onboarding the different roles is one key aspect of our workshops +- Everyone has their own path +::: diff --git a/branch/cff/_sources/screenshare.md.txt b/branch/cff/_sources/screenshare.md.txt new file mode 100644 index 0000000..cdf552a --- /dev/null +++ b/branch/cff/_sources/screenshare.md.txt @@ -0,0 +1,370 @@ +(screenshare)= + +# How to prepare a quality screen-share + +:::{objectives} +- Discuss the importance of a well planned screen-share. +- Learn how to prepare and how to test your screen-share setup. +- Know about typical pitfalls and habits to avoid. +::: + +:::{instructor-note} +- Discussion: 15 min +- Exercises: 15 min +::: + + +## Share portrait layout instead of sharing entire screen when teaching online + +- Many learners will have a smaller screen than you. +- You should plan for learners with **only one small screen**. +- A learner will **need to focus on both your screen share and their + work**. +- Share a **portrait**/**vertical half of your screen** (840 × 1080 is our standard and your + maximum). +- Zoom provides a "Share a part of screen" that is good for this. + - Our latest streaming setup (day 4) can take the portrait part for + you so you can share landscape. + - Zoom + Linux + Wayland display manager doesn't have "Share a + portion of the screen" + - You can share a single window portrait. + - Or you can start your desktop session in "X11" or "Xorg" legacy + mode. + - Or possibly other workarounds (does anyone know other solutions?) + +:::{figure} screenshare/landscape.png +:width: 80% + +A FullHD 1920x1080 screen shared. Learners have to make this really small if +they want to have something else open. +::: + +:::{figure} screenshare/portrait.png +:width: 45% + +Portrait layout. Allows learners to have something else open in the other half. +::: + +Motivation for portrait layout: +- This makes it easier for you to look at some other notes or to coordinate + with other instructors at the same time + without distracting with too much information. +- This makes it possible for participants to have something else open in the + other screen half: terminal or browser or notebook. + + +### Instructor perspective + +:::{figure} screenshare/instructor.png +:width: 75% + +**I1**: +This is how it can look for the instructor. Zoom is sharing a portion of the left +side, the right side is free for following notes, chat, etc. +::: + + +### Learner perspective + +Here are three examples of how it can look for the learner. + +:::{figure} screenshare/learner-large.png +:width: 75% + +**L1**: +Learner with a large screen, Zoom in dual-monitor mode so that the instructor +pictures are not shown. Screen-share is on the left side, collaborative notes +at bottom left, terminal and web browser on the right. +::: + +:::{figure} screenshare/learner-normal.png +:width: 75% + +**L2**: +A learner with a single large screen (Zoom in "single monitor mode"). +Instructor screen share at right, learner stuff at left. +::: + +:::{figure} screenshare/learner-small.png +:width: 75% + +**L3**: +A learner with a particularly small screen. Instructor screen-share at left, +your windows at right. +::: + + +## Share the history of your commands + +Even if you type slowly it is almost impossible to follow every command. We +all get distracted or want to read up on something or while following a command +fails on the learner laptop while instructor gets no error. + +**Add pauses** and **share the commands that you have typed** so that one can catch up. + +Below are some examples (some more successful than others) of sharing history +of commands. + +:::{figure} screenshare/history-portrait.png +:width: 50% + +**H1**: +A vertical screen layout shared. Note the extra shell history at the top. The +web browser is at the bottom, because the Zoom toolbar can cover the bottom +bit. +::: + +:::{figure} screenshare/history-rsh.png +:width: 75% + +**H2**: +This isn't a screen-share from CodeRefinery, but may be instructive. Note the +horizontal layout and shell history at the bottom right. +::: + +:::{figure} screenshare/history-landscape-dark.png +:width: 75% + +**H3**: +Similar to above, but dark. Includes contents on the right. +::: + +:::{figure} screenshare/history-portrait-light.png +:width: 50% + +**H4**: +Jupyter + terminal, including the ``fish`` shell and the terminal history. +::: + +:::{figure} screenshare/history-portrait-dark.png +:width: 50% + +**H5**: +Lesson + terminal, ``tmux`` plus terminal history and dark background. +::: + +:::{figure} screenshare/portrait.png +:width: 50% + +**H6**: +HPC Kickstart course. Note the colors contrast of the windows and colors of +the prompt and text. The history is smaller and doesn't take up primary +working space. The working directory is in the window title bar. +::: + +:::{figure} https://raw.githubusercontent.com/bast/history-window/main/demo.gif +:width: 80% + +**H7**: +Show command history "picture-in-picture", in the same terminal window. +::: + + +## How to configure history sharing + +You need to find a way to show the recent commands you have entered, so that +learners can see the recent commands. Below are many solutions. Try them out +and see what works for you. + +- [prompt-log](): + It adds a interesting idea that the command you enter is in color and also + provides terminal history before the command returns. + +- **Simple**: The simple way is `PROMPT_COMMAND="history -a"` and then + `tail -f -n0 ~/.bash_history`, but this doesn't capture ssh, + sub-shells, and only shows the command after it is completed. + +- **Better yet still simple**: Many Software Carpentry instructors use + [this script](https://github.com/rgaiacs/swc-shell-split-window), + which sets the prompt, splits the terminal window using tmux and displays command history + in the upper panel. Requirement: [tmux](https://github.com/tmux/tmux/wiki) + +- **Better (bash)**: This prints the output before the command is run, + instead of after. Tail with `tail -f ~/demos.out`. + ``` + BASH_LOG=~/demos.out + bash_log_commands () { + # https://superuser.com/questions/175799 + [ -n "$COMP_LINE" ] && return # do nothing if completing + [[ "$PROMPT_COMMAND" =~ "$BASH_COMMAND" ]] && return # don't cause a preexec for $PROMPT_COMMAND + local this_command=`HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"`; + echo "$this_command" >> "$BASH_LOG" + } + trap 'bash_log_commands' DEBUG + ``` + +- **Better (zsh)**: This works like above, with zsh. Tail with `tail -f + ~/demos.out`. + ``` + preexec() { echo $1 >> ~/demos.out } + ``` + +- **Better (fish)**: This works like above, but for fish. Tail with + `tail -f ~/demos.out`. + ``` + function cmd_log --on-event fish_preexec ; echo "$argv" >> ~/demos.out ; end + ``` + +- **Better (tmuxp)**: This will save some typing. + [TmuxP](https://tmuxp.git-pull.com/) is a Python program (`pip install + tmuxp`) that gives you programmable `tmux` sessions. One configuration that + works (in this case for `fish` shell): + ```yaml + session_name: demo + windows: + - window_name: demo + layout: main-horizontal + options: + main-pane-height: 7 + panes: + - shell_command: + - touch /tmp/demo.history + - tail -f /tmp/demo.history + - shell_command: + - function cmd_log --on-event fish_preexec ; echo "$argv" >> /tmp/demo.history ; end + ``` + +- **Windows PowerShell**: In [Windows Terminal](https://docs.microsoft.com/en-us/windows/terminal/), + a split can be made by pressing `CTRL+SHIFT+=`. Then, in one of the splits, the following + PowerShell command will start tracking the shell history: + ``` + Get-Content (Get-PSReadlineOption).HistorySavePath -Wait + ``` + Unfortunately, this only shows commands after they have been executed. + +- [Tavatar: shell history mirroring teaching tool](https://github.com/Sabryr/Tavatar) can copy recent history to a remote server. + +- [history-window](https://github.com/bast/history-window): Show command + history "picture-in-picture" when teaching command line. Requires Bash. + + +## Font, colors, and prompt + +### Terminal color schemes + +- Dark text on light background, *not* dark theme. Research and our + experience says that dark-text-on-light is better in some cases and + similar in others. +- You might want to make the background light grey, to avoid + over-saturating people's eyes and provide some contrast to the pure + white web browser. (this was an accessibility recommendation when + looking for ideal color schemes) +- Do you have any yellows or reds in your prompt or program outputs? + Adjust colors if possible. + + +### Font size + +- Font should be large (a separate history terminal can have a smaller + font). +- Be prepared to resize the terminal and font as needed. Find out + the keyboard shortcuts to do this since you will need it. + + +### Prompt + +At the beginning of the workshop your goal is to have a shell +**as easy to follow as possible** and **as close to what learners will +see on their screens**: +- Your prompt should be minimal: few distractions, and not take up many + columns of text. +- [prompt-log]() does + this for you. +- The minimum to do is is `export PS1='\$ '`. +- Blank line between entries: `export PS1='\n\$ '`. +- Have a space after the `$` or `%` or whatever prompt character you + use. +- Strongly consider the Bash shell. This is what most new people will + use, and Bash will be less confusing to them. +- Eliminate menu bars and any other decoration that uses valuable + screen space. +- Add colors only if it simplifies the reading of the prompt. + +Later in the workshop or in more advanced lessons: +- Using other shells and being more adventurous is OK - learners will + know what is essential to the terminal and what is extra for your + environment. + +Try to find a good balance between: +- Showing a simple setup and showing a more realistic setup. +- Showing a consistent setup among all instructors and showing a + variety of setups. + + +## Habits we need to un-learn + +- **Do not clear the terminal**. Un-learn CTRL-L or `clear` if possible. + More people will wonder what + just got lost than are helped by seeing a blank screen. Push + ``ENTER`` a few times instead to add some white space. +- **Do not rapidly switch between windows** or navigate quickly between multiple + terminals, browser tabs, etc. This is useful during your own work when nobody + is watching, but it is very hard to follow for learners. +- Avoid using **aliases** or **shortcuts** that are not part of the + standard setup. Learners probably don't have them, and they will fail + if they try to follow your typing. Consider even to rename corresponding + files (`.bashrc`, `.gitconfig`, `.ssh/config`, `.ssh/authorized_keys`, `.conda/*`). +- Be careful about using **tab completion** or **reverse history search** if these + haven't been introduced yet. + + +## Desktop environment and browser + +- Try to remove window title bars if they take up lots of space + without adding value to the learner. +- Can you easily resize your windows for adjusting during teaching? +- Does your web browser have a way to reduce its menu bars and other + decoration size? + - Firefox-based browsers: go to `about:config` and set + `layout.css.devPixelsPerPx` to a value slightly smaller than one, + like `0.75`. Be careful you don't set it too small or large since + it might be hard to recover! When you set it to something smaller + than 1, all window decorations become smaller, and you compensate + by zooming in on the website more (you can set the default zoom to + be greater than 100% to compensate). Overall, you get more + information and less distraction. + + +## How to switch between teaching setup and work setup? + +- Make a dedicated "demos" profile in your terminal emulator, if + relevant. Or use a different terminal emulator just for demos. +- Same idea for the browser: Consider using a different browser profile for + teaching/demos. +- Another idea is to containerize the setup for teaching. + We might demonstrate this during the {ref}`cool-gems` session later. + +--- + +:::{keypoints} +- Share **portrait layout** instead of sharing entire screen +- **Adjust your prompt** to make commands easy to read +- **Readability** and beauty is important: adjust your setup for your audience +- **Share the history** of your commands +- Get set up a **few days in advance** and get feedback from someone else. + Feedback and time to improve is very important to make things clear and accessible. + 10 minutes before the session starts is typically too late. +::: + + +## Exercises + +:::{exercise} Evaluate screen captures (20 min) + +Evaluate screenshots on this page. Discuss the trade-offs of each one. Which +one do you prefer? Which are useful in each situation? + +Please take notes in the collaborative document. +::: + +:::{exercise} Set up your own environment (20 min) + +Set up your screen to teach something. Get some feedback from another learner +or your exercise group. +::: + + +## Other resources + +- +- diff --git a/branch/cff/_sources/session-4-intro.md.txt b/branch/cff/_sources/session-4-intro.md.txt new file mode 100644 index 0000000..15cf32e --- /dev/null +++ b/branch/cff/_sources/session-4-intro.md.txt @@ -0,0 +1,28 @@ +(session-4-intro)= + +# Session 4 intro + +This session covers streaming and technical production. Some +introductory notes: + +* (As of 2024) This is the first and only comprehensive introduction + to our online streaming. +* These practices are new and well-refined internally, but a + *different* kind of refinement is needed to teach and reuse them. +* The lessons have outlines of what to talk about, but it's just an + outline. It is *not* refined, since thees things are *new*. Many + things will have to be figured out as we talk. +* This session is a demo of lots of basics. + * Ask questions - otherwise it will be boring + * If you want to use this in real life: you will need *mentoring + sessions* and active help. Contact us to do that. + + +:::{warning} + +**Audio and video weirdness** + +We are setting up video and audio recording, but also capturing that +for re-sharing it. There may be anomalies as video or audio +feedback. Please be prepared. +::: diff --git a/branch/cff/_sources/sound.md.txt b/branch/cff/_sources/sound.md.txt new file mode 100644 index 0000000..bc4ba16 --- /dev/null +++ b/branch/cff/_sources/sound.md.txt @@ -0,0 +1,170 @@ +(sound)= + +# Sound + +:::{objectives} +- Understand that sound quality is very important +- Evaluate your and others sound quality and know how to improve it +- Test tips and tricks for achieving good sound quality +::: + +:::{instructor-note} +- Teaching: 10 min +- Exercises: 10 min +::: + + + +## The importance of audio + +- Pleasing audio quality makes events much more enjoyable +- Audio is one of the most important things you can control +- Things that can go wrong: + - Too quiet + - Too loud + - Instructors' volumes imbalanced + - Background noise + - Low-quality/breaking up audio hard to hear. + - "Ducking" (first words lower volume, or lower volume other times) + + + +## Tips for good sound quality + +- Have a headset with mounted microphone + - Even if you have a professional external microphone, it doesn't + matter if your room has bad acoustics. + - The close pickup can't be beat with normal tools. + - As long as it's headset mounted, price doesn't seem to matter + *that* much. +- Don't use Bluetooth + - Bluetooth can have too much latency (300-500ms) + - This may seem small but for interactive work, it's a lot + - Use a wired headset, or wireless with a non-Bluetooth USB plug + (like gaming headsets have). These have much lower latency. + - Bluetooth 5 can have much lower latency, but you probably + shouldn't count on that without testing. + - It can also have lower sound quality on some devices due to + bandwidth limitations. +- Once you have a headset, turn input noise cancellation to low + (wherever it might be: headphone, meeting software, etc.). + + + +## Balancing and dynamic adjustment + +- It's important that instructors volumes match. +- An exercise will go over a systematic procedure for matching + volumes. + - Practice so that you can do this quickly. +- May need re-adjusting when instructors swap out or start getting + excited. +- An exercise below will demonstrate our procedure. + + + +## Speak up when there are problems + +- If you notice someone with audio issues, let them know right away + (voice if bad, or chat/notes if less urgent). +- Take the time to fix it as soon as practical. +- Make a culture of *speaking up, helping, and not suffering*. + + + +## Recommendations + +- Procure some reasonable headset. +- Low/medium-priced gaming-type headsets have worked well for us. + - (gaming headsets usually aren't Bluetooth, because gaming needs + low latency.) +- Show this page to your workplace (if you have one) and call a good + headset work equipment. + + + +## Exercises + +:::{exercise} Sound-1: Evaluate sound quality +It's important to be able to discuss with others the quality of their +audio. They can't hear themselves, after all. + +- Within the teams, discuss each person's audio quality and what kind + of setup they have. +- Be respectful and constructive (and realize that people came + prepared to listen, not teach). +- Consider, for example + - Volume + - Clarity + - Background noise + - Noise cancellation artifacts + - "Ducking": first words at lower volume or missing +- Discuss how to bring this up during other courses and meetings. +::: + + +:::{exercise} Sound-2: Adjust volume up and down +In addition to individual quality, it is important that sound is +balanced among all instructors. Have you ever been to a event when +one person is too quiet and they can't make themselves any louder? +And they can't adjust it? + +You should ensure that you have a range of volumes available to you. +You might have to look into several different locations in order to +make the full adjustment (). + +- Go to your sound settings +- One by one, each person + - Adjusts their microphone volume so quiet that they can't be heard. + - Adjusts their microphone volume so that it is extremely loud (this + may require going beyond 100% if possible). +- Basically, make sure you aren't so close to either end that you have + no potential to make an adjustment in that direction. +- Everyone tries to set the volume to something reasonable, in + preparation for the next exercise. + +Once you know where these settings are , you won't be panicked when the +volume is too low or high during a course. +::: + + +:::{exercise} Sound-3: Do a balance check +It's important that instructor audio is balanced (the same volume). +But how can you do this? + +- Pick a leader. +- The leader decides the order ("I am first, then [name-1] and + [name-2]") +- The leader says "one". Everyone else says "one" in the order + specified. +- The leader says "two". Everyone else says "two" in the order. +- The leader asks for opinions on who they think is louder or softer. + If there are more than three people, you can figure it out + yourselves. With less than two, you have to ask someone in the + audience. + +Example: +- Leader: Let's do a sound check. I am first, then AAA and BBB. +- Leader: One +- AAA: One +- BBB: One +- Leader: Two +- AAA: Two +- BBB: Two +- Leader: Three +- AAA: Three +- BBB: Three +- Leader: How did that sound to everyone? +- [Someone else]: Leader and BBB were pretty similar but AAA is a bit + lower. +::: + + + +## Summary + +:::{keypoints} +- Audio quality is important and one of the most notable parts of the + workshop. +- Improving audio isn't hard or expensive, but does require preparation. +::: diff --git a/branch/cff/_sources/streaming-whats-next.md.txt b/branch/cff/_sources/streaming-whats-next.md.txt new file mode 100644 index 0000000..68a62d9 --- /dev/null +++ b/branch/cff/_sources/streaming-whats-next.md.txt @@ -0,0 +1,31 @@ +(streaming-whats-next)= + +# What's next? + +:::{objectives} +- Know next steps if you want to do streaming +::: + +:::{instructor-note} +- Teaching: 5 min +- Q&A 5 min +::: + +What comes next? + +- We talked a lot about theory, and gave demonstrations. +- Hands-on is very different. We recommend working with someone to + put it in practice. +- + + +- Work with someone who can show you the way +- Use it for smaller courses with a backup plan + + +## See also + +:::{keypoints} +- These lessons about streaming have been the theoretical part of +streaming training. +::: diff --git a/branch/cff/_sources/streaming.md.txt b/branch/cff/_sources/streaming.md.txt new file mode 100644 index 0000000..614b847 --- /dev/null +++ b/branch/cff/_sources/streaming.md.txt @@ -0,0 +1,94 @@ +(streaming)= + +# Behind the stream + +:::{objectives} +- Take a first look at the broadcaster's view. +- Get to know what happens "behind the stream" of a workshop +- See what the "broadcaster" sees and what they need to do. +- Not yet: learn details of how to do this. +::: + +:::{instructor-note} +- Teaching: 20 min +- Q&A 10 min +::: + +In this episode, you'll see an end-to-end view of streaming from the +broadcaster's point of view. It's a tour but not an explanation or +tutorial. + + + +## Who does what + +We have certain role definitions: + +- **Broadcaster**: Our term for the person who manages the streaming. +- **Director**: Person who is guiding the instructors to their + sessions, changing the scenes, calling the breaks, etc. + - Could be the same as broadcaster. +- **Instructor**: One who is teaching. They don't have to know + anything else about how streaming works. + +This lesson describes what the Broadcaster/Director sees. + + +## Window layouts + +What does the broadcaster see on their screen? + +- What are the main windows you see? +- What do each of them do? +- Which ones do you need to focus on? +- How do you keep all this straight in your head? + + +## CodeRefinery control panel + +- A custom application that controls scenes +- Based on OBS-websocket (remote control connection for OBS - we'll + learn about this later) +- Can also work remotely, so that you can have a remote director + + +## How scenes are controlled + +What has to be done during a course? + +- How do you start the stream? +- How do you change the view? +- How do you adjust things based on what the instructors share? +- How do you coordinate with the instructors? +- How do you know when to change the view? + + +## Getting it set up + +- How hard was it to figure this out? +- How hard is it to set it up for each new workshop? + + +## What can go wrong + +- What's the worst that has happened? +- What if you need to walk away for a bit? +- Someone broadcasts something unexpectedly + + +## Alternatives + +- Youtube vs Twitch +- Zoom stream directly to YouTube/Twitch +- Direct streaming platform, e.g. streamyard + + +## Q&A + +Q&A from audience + + +:::{keypoints} +- The broadcaster's view shouldn't be so scary. +- There is a lot to manage, but each individual part isn't that hard. +::: diff --git a/branch/cff/_sources/teaching-philosophies.md.txt b/branch/cff/_sources/teaching-philosophies.md.txt new file mode 100644 index 0000000..7609af2 --- /dev/null +++ b/branch/cff/_sources/teaching-philosophies.md.txt @@ -0,0 +1,155 @@ +(teaching-philosophies)= + +# CodeRefinery teaching philosophies + +:::{objectives} +- Get to know the teaching philosophies of CodeRefinery instructors +::: + +:::{instructor-note} +- Teaching: 10 min +- Discussion: 20 min +::: + + +## Introduction + +During this episode we split into breakoutrooms and discuss own teaching philosophies. +Collect your teaching philosophies in the collaborative document. We will be going through +these and the end of the lesson. + +:::{challenge} Ice-breaker in groups (20 minutes) +- Share your approach to teaching and your teaching philosophy with your group. +- Please share your tricks and solutions in the live document for others. + +Additional ice-breaker questions: +- What is your motivation for taking this training? +- How structured or informal are your own teaching needs? +- What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching? +- What other skills need to be taught, but academic teaching isn't the right setting? +::: + + +## Instructor views + +Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops. + +It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us. + +:::{prereq} Video recordings +We have recorded some of the below as videos: +::: + +:::{challenge} Bjørn Lindi +My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this "BLOB" (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the "BLOB", to be able to share it with others. + +In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic. + +When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson. + +Tools that I find useful in preparing a lesson is concept maps and Learner Personas (though I have developed too few of them): +- [Concept Maps](https://teachtogether.tech/#s:memory-concept-maps) +- [Learner Personas](https://teachtogether.tech/#s:process-personas) +::: + +:::{challenge} Radovan Bast +My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos. + +My goal for a lesson is to spark curiosity to try things after the lesson, both +for the novices ("This looks like a useful tool, I want to try using it after +the workshop.") and the more experienced participants ("Aha - I did not know +you could do this. I wonder whether I can make it work with X."). I like to +start lessons with a question because this makes participants look up from +their browsers. + +Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise. + +For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate the +answer. + +I try to avoid jargon and "war stories" from the professional developers' +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid "customer", +"production", also a lot of Agile jargon is hard to relate to. + +Less and clear is better than more and unclear. Simple examples are better than +complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +"simply", "just", "easy". If participants take home one or two points from a +lesson, that's for me success. + +I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don't want to be +surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or slide. +This allows me to skip and distill the essence and not read bullet point by +bullet point. + +I try to never deviate from the script and if I do, be very explicit about it. + +A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel listening to me. + +I very much like the co-teaching approach where the other person helps +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson. +::: + +:::{challenge} Sabry Razick +My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case. +::: + +:::{challenge} Richard Darst +Like many people, I've often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I've realized long ago that my most important lessons weren't +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I've realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds. + +My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I'm often start at the +very basics, because this is what I see missing most often. + +When teaching, I like lots of audience questions and don't mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don't have to know everything perfectly, just show how +you'd approach a problem. +::: + +:::{challenge} Stepas Toliautas +I aim for my learners to understand things (concepts, techniques...), instead of just memorizing them. The phrase I use from time to time when teaching information technology topics (be it hardware or software) is "there is no magic": everything can be explained if necessary. While CodeRefinery also emphasizes usefulness/ immediate applicability of the content, often having the correct notions actually helps to start using them sooner and with less mistakes. + +I try to guide my audience through the presented material with occasional questions related to previous topics and common knowledge -- to help them link the concepts already during the lesson. I'm also fully aware that waiting for someone to answer is quite uncomfortable in-person and doubly so in an online environment, especially if no one uses their cameras :) + +And if I get the question I don't have the answer for (or material to show it) at the moment, in university classes I prepare and come back to it next time. While with one-off workshops there might not be a "next time", open-source material used by CodeRefinery allows to have the same outcome: the latest and greatest version stays available for self-study afterwards. +::: + + +## Summary + +:::{keypoints} +- People have different viewpoints on teaching. +::: diff --git a/branch/cff/_sources/video-editing.md.txt b/branch/cff/_sources/video-editing.md.txt new file mode 100644 index 0000000..b41ee26 --- /dev/null +++ b/branch/cff/_sources/video-editing.md.txt @@ -0,0 +1,468 @@ +(video-editing)= + +# Video editing + +:::{objectives} +- Get to know ways of quick video editing to be able to provide + accessible videos +- Learn how video editing can be distributed and done the same day. +::: + +:::{instructor-note} +- Teaching: 20 min +- Exercises: 20 min +::: + + +Video recordings could be useful for people watching later, +but also are (perhaps more) useful for **immediate review and catching +up after missing a day in a workshop**. For this, they need to be +released immediately, within a few hours of the workshop. +CodeRefinery does this, and you can too. + +Hypothesis: videos must be processed the same evening as they were +recorded, otherwise (it may never happen) or (it's too late to be +useful). To do that, we have to make processing *good enough* (not +perfect) and *fast* and the work *distributeable*. + + + +## Primary articles + +* Video editor role description: + +* ffmpeg-editlist: the primary tool: + + * Example YAML editlists: + + + +## How this relates to streaming + +- If you stream, then the audience *can not* appear in the recorded + videos +- This allows you to release videos *very quickly* if you have the + right tools. +- When you have a large audience, the videos start helping more + (review a missed day, catch up later, review later) +- Thus + - If you would never want videos, there may never be a benefit to + streaming + - If you want videos, it gives motivation to stream. + + +## Summary + +* Basic principle: privacy is more important than any other factor. + If we can't guarantee privacy, we can't release videos at all. + + - Disclaimers such as "if you don't want to appear in a recording, + leave your video off and don't say anything", since a) accidents + happen especially when coming back from breakout rooms. b) it + creates an incentive to not interact or participate in the course. + +* Livestreaming is important here: by separating the instruction from + the audience audio/video, there is no privacy risk in the raw + recording. They could be released or shared unprocessed. + +* Our overall priorities + + 1) No learner (or anyone not staff) video, audio, names, etc. are + present in the recordings. + 2) Good descriptions. + 3) Removing breaks and other dead time. + 4) Splitting videos into useful chunks (e.g. per-episode), perhaps + equal with the next one: + 5) Good Table of Contents information so learners can jump to the + right spots (this also helps with “good description”.) + +* [ffmpeg-editlist](https://github.com/coderefinery/ffmpeg-editlist) + allows us to define an edit in a text file (crowdsourceable on + Github), and then generate videos very quickly. + + +## How we do it + +The full explanation is in the form of the exercises below. As a +summary: + +- Record raw video (if from a stream, audience can't possibly be in + it) +- Run Whisper to get good-enough subtitles. Distribute to someone for + checking and improving. +- Define the editing steps (which segments become which videos and + their descriptions) in a YAML file. +- Run ffmpeg-editlist, which takes combines the previous three steps + into final videos. + + + +## Exercises + +### Exercise A + +These exercises will take you through the whole sequence. + +:::::{exercise} Editing-1: Get your sample video + +Download a sample video: + +* Video (raw): +* Whisper subtitles (of raw video): + +* [Schedule of + workshop](https://scicomp.aalto.fi/training/scip/kickstart-2023/#schedule) + (day 1, 11:35--12:25) - used for making the descriptions. ::::: + + +:::::{exercise} Editing-2: Run Whisper to generate raw subtitles and test video. + +First off, install Whisper and generate the base subtitles, based +on the. Since this is probably too much to expect for a short +lesson, they are provided for you (above), but if you want you can +try using Whisper, or generating the subtitles some other way. + +You can start generating subtitles now, while you do the next +steps, so that they are ready by the time you are ready to apply +the editlist. ffmpeg-editlist can also slice up the subtitles from +the main video to make subtitles for each segment you cut out. + +Whisper is left as an exercise to the reader. + +::::{solution} + +Example Whisper command: + +```console +$ whisper --device cuda --output_format srt --initial_prompt="Welcome to CodeRefinery day four." --lang en --condition_on_previous_text False INPUT.mkv +``` + +An initial prompt like this make Whisper more likely to output +full sentences, instead of a stream of words with no +punctuation. +:::: +::::: + +:::::{exercise} Editing-3: Create the basic editlist.yaml file + +Install +[ffmpeg-editlist](https://github.com/coderefinery/ffmpeg-editlist) and +try to follow its instructions, to create an edit with these features: + +* The input definition. +* Two output sections: the "Intro to the course", and "From data + storage to your science" talks (Remember it said the recording + started at 11:35... look at the schedule for hints on when it + might start!). This should have a start/end timestamp from the + *original* video. + +A basic example: + +```yaml +- input: day1-raw.mkv + +# This is the output from one section. Your result should have two of these sections. +- output: part1.mkv + title: something + description: >- + some long + description of the + segment + editlist: + - start: 10:00 # start timestamp of the section, in *original* video + - end: 20:00 # end timestamp of the section, in the *original* video +``` + +::::{solution} + +This is an excerpt from our [actual editlist file of this +course](https://github.com/AaltoSciComp/video-editlists-asc/blob/master/kickstart-2023.yaml#L16-L53) + +```yaml +- input: day1-obs.mkv + +- output: day1-intro.mkv + title: 1.2 Introduction + description: >- + General introduction to the workshop. + + https://scicomp.aalto.fi/training/kickstart/intro/ + + editlist: + - start: 00:24:10 + - end: 00:37:31 + + +- output: day1-from-data-storage-to-your-science.mkv + title: "1.3 From data storage to your science" + description: >- + Data is how most computational work starts, whether it is + externally collected, simulation code, or generated. And these + days, you can work on data even remotely, and these workflows + aren't obvious. We discuss how data storage choices lead to + computational workflows. + + https://hackmd.io/@AaltoSciComp/SciCompIntro + + editlist: + - start: 00:37:43 + - end: 00:50:05 +``` +:::: +::::: + +:::::{admonition} Discussion: what makes a video easy to edit? +--- +class: discussion +--- + +* Clear speaking and have high audio quality. +* For subtitle generation: Separate sentences cleanly, otherwise it + gets in a "stream of words" instead of "punctuated sentences" + mode. +* Clearly screen-sharing the place you are at, including section + name. +* Clear transitions, "OK, now let's move on to the next lesson, + LESSON-NAME. Going back to the main page, we see it here." +* Clearly indicate where the transitions are +* Hover mouse cursor over the area you are currently talking about. +* Scroll screen when you move on to a new topic. +* Accurate course webpage and sticking to the schedule + +All of these are also good for learners. By editing videos, you +become an advocate for good teaching overall. +::::: + + +:::::{exercise} Editing-4: Run ffmpeg-editlist + +Install ffmpeg-editlist: ``pip install ffmpeg-editlist[srt]`` (you +may want to use a virtual environment, but these are very minimal +dependencies). + +The ``ffmpeg`` command line tool must be available in your +``PATH``. + +::::{solution} + +It can be run with (where ``.`` is the directory containing the +input files): + +```console +$ ffmpeg-editlist editlist.yaml . +``` + +Just running like this is quick and works, but the stream may be +garbled in the first few seconds (because it's missing a key +frame). (A future exercise will go over fixing this. +Basically, add the ``--reencode`` option, which re-encodes the +video (this is **slow**). Don't do it yet. + +Look at the ``.info.txt`` files that come out. +:::: +::::: + + +:::::{exercise} Editing-5: Add more features + +* Several chapter definitions.(re-run and you should see a + ``.info.txt`` file also generated). Video chapter definitions + are timestamps of the *original* video, that get translated to + timestamps of the *output* video. + + ```yaml + + - output: part1.mkv + editlist: + - start: 10:00 + - -: Introduction # <-- New, `-` means "at start time" + - 10:45: Part 1 # <-- New + - 15:00: Part 2 # <-- New + - end: 20:00 + ``` + + Look at the ``.info.txt`` files that come out now. What is new in it? + +* Add in "workshop title", "workshop description", and see the + ``.info.txt`` files that come out now. This is ready for + copy-pasting into a YouTube description (first line is the title, + rest is the description). + + Look at the new ``.info.txt`` files. What is new? + +::::{solution} + +* This course actually didn't have chapters for the first day + sessions, but you can [see chapters for day 2 + here](https://github.com/AaltoSciComp/video-editlists-asc/blob/master/kickstart-2023.yaml#L239-L262), + for example. +* [Example of the workshop description for this + course](https://github.com/AaltoSciComp/video-editlists-asc/blob/master/kickstart-2023.yaml#L1-L13) +* Example info.txt file for the general introduction to the + course. The part after the ``-----`` is the workshop description. + + ``` + 1.2 Introduction - HPC/SciComp Kickstart summer 2023 + + General introduction to the workshop. + + https://scicomp.aalto.fi/training/kickstart/intro/ + + 00:00 Begin introduction <-- Invented for the exercise demo, not real + 03:25 Ways to attend <-- Invented for the exercise demo, not real + 07:12 What if you get lost <-- Invented for the exercise demo, not real + + ----- + + This is part of the Aalto Scientific Computing "Getting + started with Scientific Computing and HPC Kickstart" 2023 + workshop. The videos are available to everyone, but may be + most useful to the people who attended the workshop and want + to review later. + + Playlist: + https://www.youtube.com/playlist?list=PLZLVmS9rf3nMKR2jMglaN4su3ojWtWMVw + + Workshop webpage: + https://scicomp.aalto.fi/training/scip/kickstart-2023/ + + Aalto Scientific Computing: https://scicomp.aalto.fi/ + ``` +:::: +::::: + +:::::{exercise} Editing-6: Subtitles + +Re-run ffmpeg-editlist with the ``--srt`` option (you have to +install it with ``pip install ffmpeg-editlist[srt]`` to pull in the +necessary dependency). Notice how ``.srt`` files come out now. + +Use some subtitle editor to edit the *original* subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use ``subtitle-editor`` on Linux, or find some other +tool. + +What do you learn from editing the subtitles? + +::::{solution} + +```console +$ ffmpeg-editlist --srt editlist.yaml +``` + +There should now be a ``.srt`` file also generated. It +generated by finding the ``.srt`` of the original video, and +cutting it the same way it cuts the video. Look and you see it +aligns with the original. + +This means that someone could have been working on fixing the +Whisper subtitles while someone else was doing the yaml-editing. +:::: +::::: + + +:::::{exercise} Editing-6: Subtitles + +Re-run ffmpeg-editlist with the ``--srt`` option (you have to +install it with ``pip install ffmpeg-editlist[srt]`` to pull in the +necessary dependency). Notice how ``.srt`` files come out now. + +Use some subtitle editor to edit the *original* subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use ``subtitle-editor`` on Linux, or find some other +tool. + +What do you learn from editing the subtitles? +::::: + + +:::::{exercise} Editing-7: Generate the final output file. + +* Run ffmpeg-editlist with the ``--reencode`` option: this + re-encodes the video and makes sure that there is no black point + at the start. + +* If you re-run with ``--check``, it won't output a new video file, + but it *will* re-output the ``.info.txt`` and ``.srt`` files. + This is useful when you adjust descriptions or chapters. +::::: + + +:::::{admonition} Discussion: how to distribute this? +--- +class: discussion +--- + +Create a flowchat of all the parts that need to be done, and which +parts can be done in parallel. Don't forget things that you might +need to do before the workshop starts. + +How hard was this editing? Was it worth it? +::::: + + +### Exercise B + + +This is a more limited (and older) version of the above exercise, +using an synthetic example video. + +:::::{exercise} Use ffmpeg-editlist to edit this sample video + +Prerequisites: ``ffmpeg`` must be installed on your computer +outside of Python. Be able to install ffmpeg-editlist. This is +simple in a Python virtual environment, but if not the only +dependency is ``PyYAML``. + +* Download the sample video: +* Copy a sample editlist YAML +* Modify it to cut out the dead time at the beginning and the end. +* If desired, add a description and table-of-contents to the + video. +* Run ffmpeg-editlist to produce a processed video. + +::::{solution} + +```yaml +- input: sample-video-to-edit.raw.mkv +- output: sample-video-to-edit.processed.mkv + description: > + editlist: + - start: 00:16 + - 00:15: demonstration + - 00:20: discussion + - stop: 00:25 +``` + +```console +$ ffmpeg-editlist editlist.yaml video/ -o video/ +``` + +Along with the processed video, we get +``sample-video-to-edit.processed.mkv.info.txt``:: + +``` +This is a sample video + + +00:00 Demonstration +00:04 Discussion +``` +:::: +::::: + +## See also + +* ffmpeg-editlist demo: +* Full demo of producing videos (everything in these exercises): +* Example YAML editlists: + + + + + +:::{keypoints} +- Video editing is very useful for learning +- Set your time budget and make it good enough in that time +- Reviewing videos improves your teaching, too. +::: diff --git a/branch/cff/_sources/why-we-stream.md.txt b/branch/cff/_sources/why-we-stream.md.txt new file mode 100644 index 0000000..56d5e5e --- /dev/null +++ b/branch/cff/_sources/why-we-stream.md.txt @@ -0,0 +1,100 @@ +(why-we-stream)= + +# Why we stream + +:::{objectives} +- Learn the general history of CodeRefinery streaming. +- Discuss the benefits of streaming and recording +- Discuss the downsides and difficulties +::: + +:::{instructor-note} +- Discussion: 10 min +- Q&A: 5 min +- Exercises: 0 min +::: + + +This is a general discussion of the topics of the day, focused on the +history of why we stream and record, how we got here, and how people +feel about it. We won't focus on how anything is done. + + +## Icebreaker questions + +- What is the most people you have taught for? +- What are the distinct parts of teaching, that can be + separated? (teaching, helping, etc) + + +## What is streaming and recording? + +- Streaming is mass communication: one to many + - Interaction audience→presenters is more limited (but different) +- Using consumer-grade tools, normal people can reach huge audiences + by Twitch/YouTube/etc. +- This isn't actually that hard: people with much less training than + us do it all the time. +- They reach huge audiences and maintain engagement for long events. + +**Recording and rapid video editing is useful even without +streaming.** + + +## History + +- In-person workshops + - 3 × full day, required travel, infrequent, one-shot +- Covid and remote teaching + - Traditional "Zoom" teaching several times +- Mega-CodeRefinery workshop + - 100-person Zoom teaching + - Emphasis on teams +- Research Software Hour + - Livestream free-form discussions on Twitch +- Streamed "HPC Kickstart" courses + + + +## Benefits and disadvantages + +Benefits: +- Larger size gives more (but different) interaction possibility + - "Notes" for async Q&A +- Recording (with no privacy risk) allows instant reviews +- Stream-scale allows for many of the things you have learned about in + days 1-3. + +Disadvantages: +- Requires training for using the tools +- Requires a certain scale to be worth it +- Coordination is much harder for big events + +When would I recommend it? +- No: For small courses +- Questionable: Medium sized courses with no videos +- Yes: When you want the largest audience +- Yes: When you want without registration required +- Yes: When you want good reusability/fast videos + + +## Future prospects (briefly) + +- Streaming probably stays as a CodeRefinery tool +- We *can* scale our courses much larger than they are now. Why don't + we, together with others? +- These tools are useful in other places too + - I've used them to record my own talks to make videos of my + single-person presentations or record conference talks nicer than Zoom. + + +## Q&A + +Q&A from audience + + +:::{keypoints} +- Streaming optimizes a course for different things +- The disadvantages can be compensated for +- There are benefits and disadvantages +::: diff --git a/branch/cff/_sphinx_design_static/design-tabs.js b/branch/cff/_sphinx_design_static/design-tabs.js new file mode 100644 index 0000000..b25bd6a --- /dev/null +++ b/branch/cff/_sphinx_design_static/design-tabs.js @@ -0,0 +1,101 @@ +// @ts-check + +// Extra JS capability for selected tabs to be synced +// The selection is stored in local storage so that it persists across page loads. + +/** + * @type {Record} + */ +let sd_id_to_elements = {}; +const storageKeyPrefix = "sphinx-design-tab-id-"; + +/** + * Create a key for a tab element. + * @param {HTMLElement} el - The tab element. + * @returns {[string, string, string] | null} - The key. + * + */ +function create_key(el) { + let syncId = el.getAttribute("data-sync-id"); + let syncGroup = el.getAttribute("data-sync-group"); + if (!syncId || !syncGroup) return null; + return [syncGroup, syncId, syncGroup + "--" + syncId]; +} + +/** + * Initialize the tab selection. + * + */ +function ready() { + // Find all tabs with sync data + + /** @type {string[]} */ + let groups = []; + + document.querySelectorAll(".sd-tab-label").forEach((label) => { + if (label instanceof HTMLElement) { + let data = create_key(label); + if (data) { + let [group, id, key] = data; + + // add click event listener + // @ts-ignore + label.onclick = onSDLabelClick; + + // store map of key to elements + if (!sd_id_to_elements[key]) { + sd_id_to_elements[key] = []; + } + sd_id_to_elements[key].push(label); + + if (groups.indexOf(group) === -1) { + groups.push(group); + // Check if a specific tab has been selected via URL parameter + const tabParam = new URLSearchParams(window.location.search).get( + group + ); + if (tabParam) { + console.log( + "sphinx-design: Selecting tab id for group '" + + group + + "' from URL parameter: " + + tabParam + ); + window.sessionStorage.setItem(storageKeyPrefix + group, tabParam); + } + } + + // Check is a specific tab has been selected previously + let previousId = window.sessionStorage.getItem( + storageKeyPrefix + group + ); + if (previousId === id) { + // console.log( + // "sphinx-design: Selecting tab from session storage: " + id + // ); + // @ts-ignore + label.previousElementSibling.checked = true; + } + } + } + }); +} + +/** + * Activate other tabs with the same sync id. + * + * @this {HTMLElement} - The element that was clicked. + */ +function onSDLabelClick() { + let data = create_key(this); + if (!data) return; + let [group, id, key] = data; + for (const label of sd_id_to_elements[key]) { + if (label === this) continue; + // @ts-ignore + label.previousElementSibling.checked = true; + } + window.sessionStorage.setItem(storageKeyPrefix + group, id); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/branch/cff/_sphinx_design_static/sphinx-design.min.css b/branch/cff/_sphinx_design_static/sphinx-design.min.css new file mode 100644 index 0000000..860c36d --- /dev/null +++ b/branch/cff/_sphinx_design_static/sphinx-design.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative;font-size:var(--sd-fontsize-dropdown)}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary.sd-summary-title{padding:.5em .6em .5em 1em;font-size:var(--sd-fontsize-dropdown-title);font-weight:var(--sd-fontweight-dropdown-title);user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;list-style:none;display:inline-flex;justify-content:space-between}details.sd-dropdown summary.sd-summary-title::-webkit-details-marker{display:none}details.sd-dropdown summary.sd-summary-title:focus{outline:none}details.sd-dropdown summary.sd-summary-title .sd-summary-icon{margin-right:.6em;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary.sd-summary-title .sd-summary-text{flex-grow:1;line-height:1.5;padding-right:.5rem}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker{pointer-events:none;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker svg{opacity:.6}details.sd-dropdown summary.sd-summary-title:hover .sd-summary-state-marker svg{opacity:1;transform:scale(1.1)}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown .sd-summary-chevron-right{transition:.25s}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-right{transform:rotate(90deg)}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-down{transform:rotate(180deg)}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-bg: rgba(0, 113, 188, 0.2);--sd-color-secondary-bg: rgba(108, 117, 125, 0.2);--sd-color-success-bg: rgba(40, 167, 69, 0.2);--sd-color-info-bg: rgba(23, 162, 184, 0.2);--sd-color-warning-bg: rgba(240, 179, 126, 0.2);--sd-color-danger-bg: rgba(220, 53, 69, 0.2);--sd-color-light-bg: rgba(248, 249, 250, 0.2);--sd-color-muted-bg: rgba(108, 117, 125, 0.2);--sd-color-dark-bg: rgba(33, 37, 41, 0.2);--sd-color-black-bg: rgba(0, 0, 0, 0.2);--sd-color-white-bg: rgba(255, 255, 255, 0.2);--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem;--sd-fontsize-dropdown: inherit;--sd-fontsize-dropdown-title: 1rem;--sd-fontweight-dropdown-title: 700} diff --git a/branch/cff/_static/_sphinx_javascript_frameworks_compat.js b/branch/cff/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 0000000..8141580 --- /dev/null +++ b/branch/cff/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/branch/cff/_static/basic.css b/branch/cff/_static/basic.css new file mode 100644 index 0000000..f316efc --- /dev/null +++ b/branch/cff/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/branch/cff/_static/check-solid.svg b/branch/cff/_static/check-solid.svg new file mode 100644 index 0000000..92fad4b --- /dev/null +++ b/branch/cff/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/branch/cff/_static/clipboard.min.js b/branch/cff/_static/clipboard.min.js new file mode 100644 index 0000000..54b3c46 --- /dev/null +++ b/branch/cff/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/branch/cff/_static/copybutton.css b/branch/cff/_static/copybutton.css new file mode 100644 index 0000000..f1916ec --- /dev/null +++ b/branch/cff/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/branch/cff/_static/copybutton.js b/branch/cff/_static/copybutton.js new file mode 100644 index 0000000..2ea7ff3 --- /dev/null +++ b/branch/cff/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/branch/cff/_static/copybutton_funcs.js b/branch/cff/_static/copybutton_funcs.js new file mode 100644 index 0000000..dbe1aaa --- /dev/null +++ b/branch/cff/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/branch/cff/_static/css/badge_only.css b/branch/cff/_static/css/badge_only.css new file mode 100644 index 0000000..c718cee --- /dev/null +++ b/branch/cff/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/branch/cff/_static/css/fonts/Roboto-Slab-Bold.woff b/branch/cff/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/branch/cff/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/branch/cff/_static/css/fonts/Roboto-Slab-Bold.woff2 b/branch/cff/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/branch/cff/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/branch/cff/_static/css/fonts/Roboto-Slab-Regular.woff b/branch/cff/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/branch/cff/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/branch/cff/_static/css/fonts/Roboto-Slab-Regular.woff2 b/branch/cff/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/branch/cff/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/branch/cff/_static/css/fonts/fontawesome-webfont.eot b/branch/cff/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/branch/cff/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/branch/cff/_static/css/fonts/fontawesome-webfont.svg b/branch/cff/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/branch/cff/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/branch/cff/_static/css/fonts/fontawesome-webfont.ttf b/branch/cff/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/branch/cff/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/branch/cff/_static/css/fonts/fontawesome-webfont.woff b/branch/cff/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/branch/cff/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/branch/cff/_static/css/fonts/fontawesome-webfont.woff2 b/branch/cff/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/branch/cff/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/branch/cff/_static/css/fonts/lato-bold-italic.woff b/branch/cff/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/branch/cff/_static/css/fonts/lato-bold-italic.woff differ diff --git a/branch/cff/_static/css/fonts/lato-bold-italic.woff2 b/branch/cff/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/branch/cff/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/branch/cff/_static/css/fonts/lato-bold.woff b/branch/cff/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/branch/cff/_static/css/fonts/lato-bold.woff differ diff --git a/branch/cff/_static/css/fonts/lato-bold.woff2 b/branch/cff/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/branch/cff/_static/css/fonts/lato-bold.woff2 differ diff --git a/branch/cff/_static/css/fonts/lato-normal-italic.woff b/branch/cff/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/branch/cff/_static/css/fonts/lato-normal-italic.woff differ diff --git a/branch/cff/_static/css/fonts/lato-normal-italic.woff2 b/branch/cff/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/branch/cff/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/branch/cff/_static/css/fonts/lato-normal.woff b/branch/cff/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/branch/cff/_static/css/fonts/lato-normal.woff differ diff --git a/branch/cff/_static/css/fonts/lato-normal.woff2 b/branch/cff/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/branch/cff/_static/css/fonts/lato-normal.woff2 differ diff --git a/branch/cff/_static/css/theme.css b/branch/cff/_static/css/theme.css new file mode 100644 index 0000000..19a446a --- /dev/null +++ b/branch/cff/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/branch/cff/_static/design-tabs.js b/branch/cff/_static/design-tabs.js new file mode 100644 index 0000000..b25bd6a --- /dev/null +++ b/branch/cff/_static/design-tabs.js @@ -0,0 +1,101 @@ +// @ts-check + +// Extra JS capability for selected tabs to be synced +// The selection is stored in local storage so that it persists across page loads. + +/** + * @type {Record} + */ +let sd_id_to_elements = {}; +const storageKeyPrefix = "sphinx-design-tab-id-"; + +/** + * Create a key for a tab element. + * @param {HTMLElement} el - The tab element. + * @returns {[string, string, string] | null} - The key. + * + */ +function create_key(el) { + let syncId = el.getAttribute("data-sync-id"); + let syncGroup = el.getAttribute("data-sync-group"); + if (!syncId || !syncGroup) return null; + return [syncGroup, syncId, syncGroup + "--" + syncId]; +} + +/** + * Initialize the tab selection. + * + */ +function ready() { + // Find all tabs with sync data + + /** @type {string[]} */ + let groups = []; + + document.querySelectorAll(".sd-tab-label").forEach((label) => { + if (label instanceof HTMLElement) { + let data = create_key(label); + if (data) { + let [group, id, key] = data; + + // add click event listener + // @ts-ignore + label.onclick = onSDLabelClick; + + // store map of key to elements + if (!sd_id_to_elements[key]) { + sd_id_to_elements[key] = []; + } + sd_id_to_elements[key].push(label); + + if (groups.indexOf(group) === -1) { + groups.push(group); + // Check if a specific tab has been selected via URL parameter + const tabParam = new URLSearchParams(window.location.search).get( + group + ); + if (tabParam) { + console.log( + "sphinx-design: Selecting tab id for group '" + + group + + "' from URL parameter: " + + tabParam + ); + window.sessionStorage.setItem(storageKeyPrefix + group, tabParam); + } + } + + // Check is a specific tab has been selected previously + let previousId = window.sessionStorage.getItem( + storageKeyPrefix + group + ); + if (previousId === id) { + // console.log( + // "sphinx-design: Selecting tab from session storage: " + id + // ); + // @ts-ignore + label.previousElementSibling.checked = true; + } + } + } + }); +} + +/** + * Activate other tabs with the same sync id. + * + * @this {HTMLElement} - The element that was clicked. + */ +function onSDLabelClick() { + let data = create_key(this); + if (!data) return; + let [group, id, key] = data; + for (const label of sd_id_to_elements[key]) { + if (label === this) continue; + // @ts-ignore + label.previousElementSibling.checked = true; + } + window.sessionStorage.setItem(storageKeyPrefix + group, id); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/branch/cff/_static/doctools.js b/branch/cff/_static/doctools.js new file mode 100644 index 0000000..4d67807 --- /dev/null +++ b/branch/cff/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/branch/cff/_static/documentation_options.js b/branch/cff/_static/documentation_options.js new file mode 100644 index 0000000..87fc516 --- /dev/null +++ b/branch/cff/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'dirhtml', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/branch/cff/_static/file.png b/branch/cff/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/branch/cff/_static/file.png differ diff --git a/branch/cff/_static/jquery.js b/branch/cff/_static/jquery.js new file mode 100644 index 0000000..c4c6022 --- /dev/null +++ b/branch/cff/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!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(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=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,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).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 w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\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(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.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,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){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 H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.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--)b.attrHandle[n[r]]=t}function pe(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 de(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 d=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")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.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}},b.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[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.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},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),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(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.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},j=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)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(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==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(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?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{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 G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.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("(^|"+M+")"+e+"("+M+"|$)"))&&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:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.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 S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(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").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.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),m(t)&&(t=t.call(e,n,S.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)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.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"===S.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"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.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)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.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?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.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)}}),S.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){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/cff/_static/js/html5shiv.min.js b/branch/cff/_static/js/html5shiv.min.js new file mode 100644 index 0000000..cd1c674 --- /dev/null +++ b/branch/cff/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/cff/_static/js/theme.js b/branch/cff/_static/js/theme.js new file mode 100644 index 0000000..1fddb6e --- /dev/null +++ b/branch/cff/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/branch/cff/_static/minipres.js b/branch/cff/_static/minipres.js new file mode 100644 index 0000000..ad11c87 --- /dev/null +++ b/branch/cff/_static/minipres.js @@ -0,0 +1,223 @@ +// Add goTo method to elements +// http://stackoverflow.com/questions/4801655/how-to-go-to-a-specific-element-on-page +(function($) { + $.fn.goTo = function() { + $('html, body').animate({ + scrollTop: $(this).offset().top //+ 'px' + }, 'fast'); + return this; // for chaining... + } +})(jQuery); + +// NO good way to do this!. Copy a hack from here +// https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript +// https://stackoverflow.com/a/2880929 +var urlParams; +(window.onpopstate = function () { + var match, + pl = /\+/g, // Regex for replacing addition symbol with a space + search = /([^&=]+)=?([^&]*)/g, + decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, + query = window.location.search.substring(1); + urlParams = {}; + while (match = search.exec(query)) + urlParams[decode(match[1])] = decode(match[2]); +})(); + +// Select heading levels +var maxHeading = urlParams['h'] +if (maxHeading === undefined) maxHeading = 2 +var headingLevels = []; +for (h=2 ; h (sections.length-1) ) { + // if we would scroll past bottom, or above top, do nothing + return; + } + + console.log('xxxxxx'); + var targetSection = sections[targetPos]; + console.log(targetSection, typeof(targetSection)); + + // Return targetSection top and height + var secProperties = section_top_and_height(targetSection); + var top = secProperties['top']; + var height = secProperties['height'] + var win_height = window.innerHeight; + //console.info(top, height, win_height) + + var scroll_to = 0; + if (height >= win_height || height == 0) { + scroll_to = top; + } else { + scroll_to = top - (win_height-height)/3.; + } + //console.info(top, height, win_height, scroll_to) + + $('html, body').animate({ + scrollTop: scroll_to //+ 'px' + }, 'fast'); + +} + + +function minipres() { + /* Enable the minipres mode: + - call the hide() function + - set up the scrolling listener + */ + document.addEventListener('keydown', function (event) { + switch(event.which) { + case 37: // left + switch_slide(-1); + event.preventDefault(); + return false; + break; + //case 38: // up + case 39: // right + switch_slide(+1); + event.preventDefault(); + return false; + break; + //case 40: // down + default: + return; // exit this handler for other keys + } + }, true) + + hide() + + // Increase space between sections + //$("div .section").css('margin-bottom', '50%'); + $(sectionSelector).css('margin-top', '50%'); + + // Reduce size/color of other sections + if (hiddenSectionSelector.length > 0) { + var hideNodes = $(hiddenSectionSelector); + console.log(typeof hideNodes, hideNodes); + for (node in hideNodes) { + console.log("a", typeof node, node); + node = hideNodes[node]; // what's right way to iterate values? + console.log("b", typeof node, node); + if (node.parentNode && node.parentNode.className == "section") { + node = node.parentNode; + console.log("c", typeof node, node); + //node.css['transform'] = 'scale(.5)'; + //node.css['transform-origin'] = 'top center'; + $(node).css('color', 'lightgrey'); + //$(node).css('font-size', '20%'); + //$(node).css('visibility', 'collapse'); + //ntahousnatouhasno; + } + } + } +} + +function hide() { + /* Hide all non-essential elements on the page + */ + + // This is for sphinx_rst_theme and readthedocs + $(".wy-nav-side").remove(); + $(".wy-nav-content-wrap").css('margin-left', 0); + $('.rst-versions').remove(); // readthedocs version selector + + // Add other formats here. +} + + +var slideshow = minipres; + +if (window.location.search.match(/[?&](minipres|slideshow|pres)([=&]|$)/) ) { + //minipres() + window.addEventListener("load", minipres); +} else if (window.location.search.match(/[?&](plain)([=&]|$)/) ) { + window.addEventListener("load", hide); +} diff --git a/branch/cff/_static/minus.png b/branch/cff/_static/minus.png new file mode 100644 index 0000000..d96755f Binary files /dev/null and b/branch/cff/_static/minus.png differ diff --git a/branch/cff/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css b/branch/cff/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css new file mode 100644 index 0000000..3356631 --- /dev/null +++ b/branch/cff/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css @@ -0,0 +1,2342 @@ +/* Variables */ +:root { + --mystnb-source-bg-color: #f7f7f7; + --mystnb-stdout-bg-color: #fcfcfc; + --mystnb-stderr-bg-color: #fdd; + --mystnb-traceback-bg-color: #fcfcfc; + --mystnb-source-border-color: #ccc; + --mystnb-source-margin-color: green; + --mystnb-stdout-border-color: #f7f7f7; + --mystnb-stderr-border-color: #f7f7f7; + --mystnb-traceback-border-color: #ffd6d6; + --mystnb-hide-prompt-opacity: 70%; + --mystnb-source-border-radius: .4em; + --mystnb-source-border-width: 1px; +} + +/* Whole cell */ +div.container.cell { + padding-left: 0; + margin-bottom: 1em; +} + +/* Removing all background formatting so we can control at the div level */ +.cell_input div.highlight, +.cell_output pre, +.cell_input pre, +.cell_output .output { + border: none; + box-shadow: none; +} + +.cell_output .output pre, +.cell_input pre { + margin: 0px; +} + +/* Input cells */ +div.cell div.cell_input, +div.cell details.above-input>summary { + padding-left: 0em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + background-color: var(--mystnb-source-bg-color); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; + border-radius: var(--mystnb-source-border-radius); +} + +div.cell_input>div, +div.cell_output div.output>div.highlight { + margin: 0em !important; + border: none !important; +} + +/* All cell outputs */ +.cell_output { + padding-left: 1em; + padding-right: 0em; + margin-top: 1em; +} + +/* Text outputs from cells */ +.cell_output .output.text_plain, +.cell_output .output.traceback, +.cell_output .output.stream, +.cell_output .output.stderr { + margin-top: 1em; + margin-bottom: 0em; + box-shadow: none; +} + +.cell_output .output.text_plain, +.cell_output .output.stream { + background: var(--mystnb-stdout-bg-color); + border: 1px solid var(--mystnb-stdout-border-color); +} + +.cell_output .output.stderr { + background: var(--mystnb-stderr-bg-color); + border: 1px solid var(--mystnb-stderr-border-color); +} + +.cell_output .output.traceback { + background: var(--mystnb-traceback-bg-color); + border: 1px solid var(--mystnb-traceback-border-color); +} + +/* Collapsible cell content */ +div.cell details.above-input div.cell_input { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-top: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; +} + +div.cell div.cell_input.above-output-prompt { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +div.cell details.above-input>summary { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; + padding-left: 1em; + margin-bottom: 0; +} + +div.cell details.above-output>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.below-input>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-top: none; + border-bottom-left-radius: var(--mystnb-source-border-radius); + border-bottom-right-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.hide>summary>span { + opacity: var(--mystnb-hide-prompt-opacity); +} + +div.cell details.hide[open]>summary>span.collapsed { + display: none; +} + +div.cell details.hide:not([open])>summary>span.expanded { + display: none; +} + +@keyframes collapsed-fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} +div.cell details.hide[open]>summary~* { + -moz-animation: collapsed-fade-in 0.3s ease-in-out; + -webkit-animation: collapsed-fade-in 0.3s ease-in-out; + animation: collapsed-fade-in 0.3s ease-in-out; +} + +/* Math align to the left */ +.cell_output .MathJax_Display { + text-align: left !important; +} + +/* Pandas tables. Pulled from the Jupyter / nbsphinx CSS */ +div.cell_output table { + border: none; + border-collapse: collapse; + border-spacing: 0; + color: black; + font-size: 1em; + table-layout: fixed; +} + +div.cell_output thead { + border-bottom: 1px solid black; + vertical-align: bottom; +} + +div.cell_output tr, +div.cell_output th, +div.cell_output td { + text-align: right; + vertical-align: middle; + padding: 0.5em 0.5em; + line-height: normal; + white-space: normal; + max-width: none; + border: none; +} + +div.cell_output th { + font-weight: bold; +} + +div.cell_output tbody tr:nth-child(odd) { + background: #f5f5f5; +} + +div.cell_output tbody tr:hover { + background: rgba(66, 165, 245, 0.2); +} + +/** source code line numbers **/ +span.linenos { + opacity: 0.5; +} + +/* Inline text from `paste` operation */ + +span.pasted-text { + font-weight: bold; +} + +span.pasted-inline img { + max-height: 2em; +} + +tbody span.pasted-inline img { + max-height: none; +} + +/* Font colors for translated ANSI escape sequences +Color values are copied from Jupyter Notebook +https://github.com/jupyter/notebook/blob/52581f8eda9b319eb0390ac77fe5903c38f81e3e/notebook/static/notebook/less/ansicolors.less#L14-L21 +Background colors from +https://nbsphinx.readthedocs.io/en/latest/code-cells.html#ANSI-Colors +*/ +div.highlight .-Color-Bold { + font-weight: bold; +} + +div.highlight .-Color[class*=-Black] { + color: #3E424D +} + +div.highlight .-Color[class*=-Red] { + color: #E75C58 +} + +div.highlight .-Color[class*=-Green] { + color: #00A250 +} + +div.highlight .-Color[class*=-Yellow] { + color: #DDB62B +} + +div.highlight .-Color[class*=-Blue] { + color: #208FFB +} + +div.highlight .-Color[class*=-Magenta] { + color: #D160C4 +} + +div.highlight .-Color[class*=-Cyan] { + color: #60C6C8 +} + +div.highlight .-Color[class*=-White] { + color: #C5C1B4 +} + +div.highlight .-Color[class*=-BGBlack] { + background-color: #3E424D +} + +div.highlight .-Color[class*=-BGRed] { + background-color: #E75C58 +} + +div.highlight .-Color[class*=-BGGreen] { + background-color: #00A250 +} + +div.highlight .-Color[class*=-BGYellow] { + background-color: #DDB62B +} + +div.highlight .-Color[class*=-BGBlue] { + background-color: #208FFB +} + +div.highlight .-Color[class*=-BGMagenta] { + background-color: #D160C4 +} + +div.highlight .-Color[class*=-BGCyan] { + background-color: #60C6C8 +} + +div.highlight .-Color[class*=-BGWhite] { + background-color: #C5C1B4 +} + +/* Font colors for 8-bit ANSI */ + +div.highlight .-Color[class*=-C0] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC0] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C1] { + color: #800000 +} + +div.highlight .-Color[class*=-BGC1] { + background-color: #800000 +} + +div.highlight .-Color[class*=-C2] { + color: #008000 +} + +div.highlight .-Color[class*=-BGC2] { + background-color: #008000 +} + +div.highlight .-Color[class*=-C3] { + color: #808000 +} + +div.highlight .-Color[class*=-BGC3] { + background-color: #808000 +} + +div.highlight .-Color[class*=-C4] { + color: #000080 +} + +div.highlight .-Color[class*=-BGC4] { + background-color: #000080 +} + +div.highlight .-Color[class*=-C5] { + color: #800080 +} + +div.highlight .-Color[class*=-BGC5] { + background-color: #800080 +} + +div.highlight .-Color[class*=-C6] { + color: #008080 +} + +div.highlight .-Color[class*=-BGC6] { + background-color: #008080 +} + +div.highlight .-Color[class*=-C7] { + color: #C0C0C0 +} + +div.highlight .-Color[class*=-BGC7] { + background-color: #C0C0C0 +} + +div.highlight .-Color[class*=-C8] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC8] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C9] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC9] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C10] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC10] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C11] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC11] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C12] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC12] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C13] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC13] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C14] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC14] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C15] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC15] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C16] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC16] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C17] { + color: #00005F +} + +div.highlight .-Color[class*=-BGC17] { + background-color: #00005F +} + +div.highlight .-Color[class*=-C18] { + color: #000087 +} + +div.highlight .-Color[class*=-BGC18] { + background-color: #000087 +} + +div.highlight .-Color[class*=-C19] { + color: #0000AF +} + +div.highlight .-Color[class*=-BGC19] { + background-color: #0000AF +} + +div.highlight .-Color[class*=-C20] { + color: #0000D7 +} + +div.highlight .-Color[class*=-BGC20] { + background-color: #0000D7 +} + +div.highlight .-Color[class*=-C21] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC21] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C22] { + color: #005F00 +} + +div.highlight .-Color[class*=-BGC22] { + background-color: #005F00 +} + +div.highlight .-Color[class*=-C23] { + color: #005F5F +} + +div.highlight .-Color[class*=-BGC23] { + background-color: #005F5F +} + +div.highlight .-Color[class*=-C24] { + color: #005F87 +} + +div.highlight .-Color[class*=-BGC24] { + background-color: #005F87 +} + +div.highlight .-Color[class*=-C25] { + color: #005FAF +} + +div.highlight .-Color[class*=-BGC25] { + background-color: #005FAF +} + +div.highlight .-Color[class*=-C26] { + color: #005FD7 +} + +div.highlight .-Color[class*=-BGC26] { + background-color: #005FD7 +} + +div.highlight .-Color[class*=-C27] { + color: #005FFF +} + +div.highlight .-Color[class*=-BGC27] { + background-color: #005FFF +} + +div.highlight .-Color[class*=-C28] { + color: #008700 +} + +div.highlight .-Color[class*=-BGC28] { + background-color: #008700 +} + +div.highlight .-Color[class*=-C29] { + color: #00875F +} + +div.highlight .-Color[class*=-BGC29] { + background-color: #00875F +} + +div.highlight .-Color[class*=-C30] { + color: #008787 +} + +div.highlight .-Color[class*=-BGC30] { + background-color: #008787 +} + +div.highlight .-Color[class*=-C31] { + color: #0087AF +} + +div.highlight .-Color[class*=-BGC31] { + background-color: #0087AF +} + +div.highlight .-Color[class*=-C32] { + color: #0087D7 +} + +div.highlight .-Color[class*=-BGC32] { + background-color: #0087D7 +} + +div.highlight .-Color[class*=-C33] { + color: #0087FF +} + +div.highlight .-Color[class*=-BGC33] { + background-color: #0087FF +} + +div.highlight .-Color[class*=-C34] { + color: #00AF00 +} + +div.highlight .-Color[class*=-BGC34] { + background-color: #00AF00 +} + +div.highlight .-Color[class*=-C35] { + color: #00AF5F +} + +div.highlight .-Color[class*=-BGC35] { + background-color: #00AF5F +} + +div.highlight .-Color[class*=-C36] { + color: #00AF87 +} + +div.highlight .-Color[class*=-BGC36] { + background-color: #00AF87 +} + +div.highlight .-Color[class*=-C37] { + color: #00AFAF +} + +div.highlight .-Color[class*=-BGC37] { + background-color: #00AFAF +} + +div.highlight .-Color[class*=-C38] { + color: #00AFD7 +} + +div.highlight .-Color[class*=-BGC38] { + background-color: #00AFD7 +} + +div.highlight .-Color[class*=-C39] { + color: #00AFFF +} + +div.highlight .-Color[class*=-BGC39] { + background-color: #00AFFF +} + +div.highlight .-Color[class*=-C40] { + color: #00D700 +} + +div.highlight .-Color[class*=-BGC40] { + background-color: #00D700 +} + +div.highlight .-Color[class*=-C41] { + color: #00D75F +} + +div.highlight .-Color[class*=-BGC41] { + background-color: #00D75F +} + +div.highlight .-Color[class*=-C42] { + color: #00D787 +} + +div.highlight .-Color[class*=-BGC42] { + background-color: #00D787 +} + +div.highlight .-Color[class*=-C43] { + color: #00D7AF +} + +div.highlight .-Color[class*=-BGC43] { + background-color: #00D7AF +} + +div.highlight .-Color[class*=-C44] { + color: #00D7D7 +} + +div.highlight .-Color[class*=-BGC44] { + background-color: #00D7D7 +} + +div.highlight .-Color[class*=-C45] { + color: #00D7FF +} + +div.highlight .-Color[class*=-BGC45] { + background-color: #00D7FF +} + +div.highlight .-Color[class*=-C46] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC46] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C47] { + color: #00FF5F +} + +div.highlight .-Color[class*=-BGC47] { + background-color: #00FF5F +} + +div.highlight .-Color[class*=-C48] { + color: #00FF87 +} + +div.highlight .-Color[class*=-BGC48] { + background-color: #00FF87 +} + +div.highlight .-Color[class*=-C49] { + color: #00FFAF +} + +div.highlight .-Color[class*=-BGC49] { + background-color: #00FFAF +} + +div.highlight .-Color[class*=-C50] { + color: #00FFD7 +} + +div.highlight .-Color[class*=-BGC50] { + background-color: #00FFD7 +} + +div.highlight .-Color[class*=-C51] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC51] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C52] { + color: #5F0000 +} + +div.highlight .-Color[class*=-BGC52] { + background-color: #5F0000 +} + +div.highlight .-Color[class*=-C53] { + color: #5F005F +} + +div.highlight .-Color[class*=-BGC53] { + background-color: #5F005F +} + +div.highlight .-Color[class*=-C54] { + color: #5F0087 +} + +div.highlight .-Color[class*=-BGC54] { + background-color: #5F0087 +} + +div.highlight .-Color[class*=-C55] { + color: #5F00AF +} + +div.highlight .-Color[class*=-BGC55] { + background-color: #5F00AF +} + +div.highlight .-Color[class*=-C56] { + color: #5F00D7 +} + +div.highlight .-Color[class*=-BGC56] { + background-color: #5F00D7 +} + +div.highlight .-Color[class*=-C57] { + color: #5F00FF +} + +div.highlight .-Color[class*=-BGC57] { + background-color: #5F00FF +} + +div.highlight .-Color[class*=-C58] { + color: #5F5F00 +} + +div.highlight .-Color[class*=-BGC58] { + background-color: #5F5F00 +} + +div.highlight .-Color[class*=-C59] { + color: #5F5F5F +} + +div.highlight .-Color[class*=-BGC59] { + background-color: #5F5F5F +} + +div.highlight .-Color[class*=-C60] { + color: #5F5F87 +} + +div.highlight .-Color[class*=-BGC60] { + background-color: #5F5F87 +} + +div.highlight .-Color[class*=-C61] { + color: #5F5FAF +} + +div.highlight .-Color[class*=-BGC61] { + background-color: #5F5FAF +} + +div.highlight .-Color[class*=-C62] { + color: #5F5FD7 +} + +div.highlight .-Color[class*=-BGC62] { + background-color: #5F5FD7 +} + +div.highlight .-Color[class*=-C63] { + color: #5F5FFF +} + +div.highlight .-Color[class*=-BGC63] { + background-color: #5F5FFF +} + +div.highlight .-Color[class*=-C64] { + color: #5F8700 +} + +div.highlight .-Color[class*=-BGC64] { + background-color: #5F8700 +} + +div.highlight .-Color[class*=-C65] { + color: #5F875F +} + +div.highlight .-Color[class*=-BGC65] { + background-color: #5F875F +} + +div.highlight .-Color[class*=-C66] { + color: #5F8787 +} + +div.highlight .-Color[class*=-BGC66] { + background-color: #5F8787 +} + +div.highlight .-Color[class*=-C67] { + color: #5F87AF +} + +div.highlight .-Color[class*=-BGC67] { + background-color: #5F87AF +} + +div.highlight .-Color[class*=-C68] { + color: #5F87D7 +} + +div.highlight .-Color[class*=-BGC68] { + background-color: #5F87D7 +} + +div.highlight .-Color[class*=-C69] { + color: #5F87FF +} + +div.highlight .-Color[class*=-BGC69] { + background-color: #5F87FF +} + +div.highlight .-Color[class*=-C70] { + color: #5FAF00 +} + +div.highlight .-Color[class*=-BGC70] { + background-color: #5FAF00 +} + +div.highlight .-Color[class*=-C71] { + color: #5FAF5F +} + +div.highlight .-Color[class*=-BGC71] { + background-color: #5FAF5F +} + +div.highlight .-Color[class*=-C72] { + color: #5FAF87 +} + +div.highlight .-Color[class*=-BGC72] { + background-color: #5FAF87 +} + +div.highlight .-Color[class*=-C73] { + color: #5FAFAF +} + +div.highlight .-Color[class*=-BGC73] { + background-color: #5FAFAF +} + +div.highlight .-Color[class*=-C74] { + color: #5FAFD7 +} + +div.highlight .-Color[class*=-BGC74] { + background-color: #5FAFD7 +} + +div.highlight .-Color[class*=-C75] { + color: #5FAFFF +} + +div.highlight .-Color[class*=-BGC75] { + background-color: #5FAFFF +} + +div.highlight .-Color[class*=-C76] { + color: #5FD700 +} + +div.highlight .-Color[class*=-BGC76] { + background-color: #5FD700 +} + +div.highlight .-Color[class*=-C77] { + color: #5FD75F +} + +div.highlight .-Color[class*=-BGC77] { + background-color: #5FD75F +} + +div.highlight .-Color[class*=-C78] { + color: #5FD787 +} + +div.highlight .-Color[class*=-BGC78] { + background-color: #5FD787 +} + +div.highlight .-Color[class*=-C79] { + color: #5FD7AF +} + +div.highlight .-Color[class*=-BGC79] { + background-color: #5FD7AF +} + +div.highlight .-Color[class*=-C80] { + color: #5FD7D7 +} + +div.highlight .-Color[class*=-BGC80] { + background-color: #5FD7D7 +} + +div.highlight .-Color[class*=-C81] { + color: #5FD7FF +} + +div.highlight .-Color[class*=-BGC81] { + background-color: #5FD7FF +} + +div.highlight .-Color[class*=-C82] { + color: #5FFF00 +} + +div.highlight .-Color[class*=-BGC82] { + background-color: #5FFF00 +} + +div.highlight .-Color[class*=-C83] { + color: #5FFF5F +} + +div.highlight .-Color[class*=-BGC83] { + background-color: #5FFF5F +} + +div.highlight .-Color[class*=-C84] { + color: #5FFF87 +} + +div.highlight .-Color[class*=-BGC84] { + background-color: #5FFF87 +} + +div.highlight .-Color[class*=-C85] { + color: #5FFFAF +} + +div.highlight .-Color[class*=-BGC85] { + background-color: #5FFFAF +} + +div.highlight .-Color[class*=-C86] { + color: #5FFFD7 +} + +div.highlight .-Color[class*=-BGC86] { + background-color: #5FFFD7 +} + +div.highlight .-Color[class*=-C87] { + color: #5FFFFF +} + +div.highlight .-Color[class*=-BGC87] { + background-color: #5FFFFF +} + +div.highlight .-Color[class*=-C88] { + color: #870000 +} + +div.highlight .-Color[class*=-BGC88] { + background-color: #870000 +} + +div.highlight .-Color[class*=-C89] { + color: #87005F +} + +div.highlight .-Color[class*=-BGC89] { + background-color: #87005F +} + +div.highlight .-Color[class*=-C90] { + color: #870087 +} + +div.highlight .-Color[class*=-BGC90] { + background-color: #870087 +} + +div.highlight .-Color[class*=-C91] { + color: #8700AF +} + +div.highlight .-Color[class*=-BGC91] { + background-color: #8700AF +} + +div.highlight .-Color[class*=-C92] { + color: #8700D7 +} + +div.highlight .-Color[class*=-BGC92] { + background-color: #8700D7 +} + +div.highlight .-Color[class*=-C93] { + color: #8700FF +} + +div.highlight .-Color[class*=-BGC93] { + background-color: #8700FF +} + +div.highlight .-Color[class*=-C94] { + color: #875F00 +} + +div.highlight .-Color[class*=-BGC94] { + background-color: #875F00 +} + +div.highlight .-Color[class*=-C95] { + color: #875F5F +} + +div.highlight .-Color[class*=-BGC95] { + background-color: #875F5F +} + +div.highlight .-Color[class*=-C96] { + color: #875F87 +} + +div.highlight .-Color[class*=-BGC96] { + background-color: #875F87 +} + +div.highlight .-Color[class*=-C97] { + color: #875FAF +} + +div.highlight .-Color[class*=-BGC97] { + background-color: #875FAF +} + +div.highlight .-Color[class*=-C98] { + color: #875FD7 +} + +div.highlight .-Color[class*=-BGC98] { + background-color: #875FD7 +} + +div.highlight .-Color[class*=-C99] { + color: #875FFF +} + +div.highlight .-Color[class*=-BGC99] { + background-color: #875FFF +} + +div.highlight .-Color[class*=-C100] { + color: #878700 +} + +div.highlight .-Color[class*=-BGC100] { + background-color: #878700 +} + +div.highlight .-Color[class*=-C101] { + color: #87875F +} + +div.highlight .-Color[class*=-BGC101] { + background-color: #87875F +} + +div.highlight .-Color[class*=-C102] { + color: #878787 +} + +div.highlight .-Color[class*=-BGC102] { + background-color: #878787 +} + +div.highlight .-Color[class*=-C103] { + color: #8787AF +} + +div.highlight .-Color[class*=-BGC103] { + background-color: #8787AF +} + +div.highlight .-Color[class*=-C104] { + color: #8787D7 +} + +div.highlight .-Color[class*=-BGC104] { + background-color: #8787D7 +} + +div.highlight .-Color[class*=-C105] { + color: #8787FF +} + +div.highlight .-Color[class*=-BGC105] { + background-color: #8787FF +} + +div.highlight .-Color[class*=-C106] { + color: #87AF00 +} + +div.highlight .-Color[class*=-BGC106] { + background-color: #87AF00 +} + +div.highlight .-Color[class*=-C107] { + color: #87AF5F +} + +div.highlight .-Color[class*=-BGC107] { + background-color: #87AF5F +} + +div.highlight .-Color[class*=-C108] { + color: #87AF87 +} + +div.highlight .-Color[class*=-BGC108] { + background-color: #87AF87 +} + +div.highlight .-Color[class*=-C109] { + color: #87AFAF +} + +div.highlight .-Color[class*=-BGC109] { + background-color: #87AFAF +} + +div.highlight .-Color[class*=-C110] { + color: #87AFD7 +} + +div.highlight .-Color[class*=-BGC110] { + background-color: #87AFD7 +} + +div.highlight .-Color[class*=-C111] { + color: #87AFFF +} + +div.highlight .-Color[class*=-BGC111] { + background-color: #87AFFF +} + +div.highlight .-Color[class*=-C112] { + color: #87D700 +} + +div.highlight .-Color[class*=-BGC112] { + background-color: #87D700 +} + +div.highlight .-Color[class*=-C113] { + color: #87D75F +} + +div.highlight .-Color[class*=-BGC113] { + background-color: #87D75F +} + +div.highlight .-Color[class*=-C114] { + color: #87D787 +} + +div.highlight .-Color[class*=-BGC114] { + background-color: #87D787 +} + +div.highlight .-Color[class*=-C115] { + color: #87D7AF +} + +div.highlight .-Color[class*=-BGC115] { + background-color: #87D7AF +} + +div.highlight .-Color[class*=-C116] { + color: #87D7D7 +} + +div.highlight .-Color[class*=-BGC116] { + background-color: #87D7D7 +} + +div.highlight .-Color[class*=-C117] { + color: #87D7FF +} + +div.highlight .-Color[class*=-BGC117] { + background-color: #87D7FF +} + +div.highlight .-Color[class*=-C118] { + color: #87FF00 +} + +div.highlight .-Color[class*=-BGC118] { + background-color: #87FF00 +} + +div.highlight .-Color[class*=-C119] { + color: #87FF5F +} + +div.highlight .-Color[class*=-BGC119] { + background-color: #87FF5F +} + +div.highlight .-Color[class*=-C120] { + color: #87FF87 +} + +div.highlight .-Color[class*=-BGC120] { + background-color: #87FF87 +} + +div.highlight .-Color[class*=-C121] { + color: #87FFAF +} + +div.highlight .-Color[class*=-BGC121] { + background-color: #87FFAF +} + +div.highlight .-Color[class*=-C122] { + color: #87FFD7 +} + +div.highlight .-Color[class*=-BGC122] { + background-color: #87FFD7 +} + +div.highlight .-Color[class*=-C123] { + color: #87FFFF +} + +div.highlight .-Color[class*=-BGC123] { + background-color: #87FFFF +} + +div.highlight .-Color[class*=-C124] { + color: #AF0000 +} + +div.highlight .-Color[class*=-BGC124] { + background-color: #AF0000 +} + +div.highlight .-Color[class*=-C125] { + color: #AF005F +} + +div.highlight .-Color[class*=-BGC125] { + background-color: #AF005F +} + +div.highlight .-Color[class*=-C126] { + color: #AF0087 +} + +div.highlight .-Color[class*=-BGC126] { + background-color: #AF0087 +} + +div.highlight .-Color[class*=-C127] { + color: #AF00AF +} + +div.highlight .-Color[class*=-BGC127] { + background-color: #AF00AF +} + +div.highlight .-Color[class*=-C128] { + color: #AF00D7 +} + +div.highlight .-Color[class*=-BGC128] { + background-color: #AF00D7 +} + +div.highlight .-Color[class*=-C129] { + color: #AF00FF +} + +div.highlight .-Color[class*=-BGC129] { + background-color: #AF00FF +} + +div.highlight .-Color[class*=-C130] { + color: #AF5F00 +} + +div.highlight .-Color[class*=-BGC130] { + background-color: #AF5F00 +} + +div.highlight .-Color[class*=-C131] { + color: #AF5F5F +} + +div.highlight .-Color[class*=-BGC131] { + background-color: #AF5F5F +} + +div.highlight .-Color[class*=-C132] { + color: #AF5F87 +} + +div.highlight .-Color[class*=-BGC132] { + background-color: #AF5F87 +} + +div.highlight .-Color[class*=-C133] { + color: #AF5FAF +} + +div.highlight .-Color[class*=-BGC133] { + background-color: #AF5FAF +} + +div.highlight .-Color[class*=-C134] { + color: #AF5FD7 +} + +div.highlight .-Color[class*=-BGC134] { + background-color: #AF5FD7 +} + +div.highlight .-Color[class*=-C135] { + color: #AF5FFF +} + +div.highlight .-Color[class*=-BGC135] { + background-color: #AF5FFF +} + +div.highlight .-Color[class*=-C136] { + color: #AF8700 +} + +div.highlight .-Color[class*=-BGC136] { + background-color: #AF8700 +} + +div.highlight .-Color[class*=-C137] { + color: #AF875F +} + +div.highlight .-Color[class*=-BGC137] { + background-color: #AF875F +} + +div.highlight .-Color[class*=-C138] { + color: #AF8787 +} + +div.highlight .-Color[class*=-BGC138] { + background-color: #AF8787 +} + +div.highlight .-Color[class*=-C139] { + color: #AF87AF +} + +div.highlight .-Color[class*=-BGC139] { + background-color: #AF87AF +} + +div.highlight .-Color[class*=-C140] { + color: #AF87D7 +} + +div.highlight .-Color[class*=-BGC140] { + background-color: #AF87D7 +} + +div.highlight .-Color[class*=-C141] { + color: #AF87FF +} + +div.highlight .-Color[class*=-BGC141] { + background-color: #AF87FF +} + +div.highlight .-Color[class*=-C142] { + color: #AFAF00 +} + +div.highlight .-Color[class*=-BGC142] { + background-color: #AFAF00 +} + +div.highlight .-Color[class*=-C143] { + color: #AFAF5F +} + +div.highlight .-Color[class*=-BGC143] { + background-color: #AFAF5F +} + +div.highlight .-Color[class*=-C144] { + color: #AFAF87 +} + +div.highlight .-Color[class*=-BGC144] { + background-color: #AFAF87 +} + +div.highlight .-Color[class*=-C145] { + color: #AFAFAF +} + +div.highlight .-Color[class*=-BGC145] { + background-color: #AFAFAF +} + +div.highlight .-Color[class*=-C146] { + color: #AFAFD7 +} + +div.highlight .-Color[class*=-BGC146] { + background-color: #AFAFD7 +} + +div.highlight .-Color[class*=-C147] { + color: #AFAFFF +} + +div.highlight .-Color[class*=-BGC147] { + background-color: #AFAFFF +} + +div.highlight .-Color[class*=-C148] { + color: #AFD700 +} + +div.highlight .-Color[class*=-BGC148] { + background-color: #AFD700 +} + +div.highlight .-Color[class*=-C149] { + color: #AFD75F +} + +div.highlight .-Color[class*=-BGC149] { + background-color: #AFD75F +} + +div.highlight .-Color[class*=-C150] { + color: #AFD787 +} + +div.highlight .-Color[class*=-BGC150] { + background-color: #AFD787 +} + +div.highlight .-Color[class*=-C151] { + color: #AFD7AF +} + +div.highlight .-Color[class*=-BGC151] { + background-color: #AFD7AF +} + +div.highlight .-Color[class*=-C152] { + color: #AFD7D7 +} + +div.highlight .-Color[class*=-BGC152] { + background-color: #AFD7D7 +} + +div.highlight .-Color[class*=-C153] { + color: #AFD7FF +} + +div.highlight .-Color[class*=-BGC153] { + background-color: #AFD7FF +} + +div.highlight .-Color[class*=-C154] { + color: #AFFF00 +} + +div.highlight .-Color[class*=-BGC154] { + background-color: #AFFF00 +} + +div.highlight .-Color[class*=-C155] { + color: #AFFF5F +} + +div.highlight .-Color[class*=-BGC155] { + background-color: #AFFF5F +} + +div.highlight .-Color[class*=-C156] { + color: #AFFF87 +} + +div.highlight .-Color[class*=-BGC156] { + background-color: #AFFF87 +} + +div.highlight .-Color[class*=-C157] { + color: #AFFFAF +} + +div.highlight .-Color[class*=-BGC157] { + background-color: #AFFFAF +} + +div.highlight .-Color[class*=-C158] { + color: #AFFFD7 +} + +div.highlight .-Color[class*=-BGC158] { + background-color: #AFFFD7 +} + +div.highlight .-Color[class*=-C159] { + color: #AFFFFF +} + +div.highlight .-Color[class*=-BGC159] { + background-color: #AFFFFF +} + +div.highlight .-Color[class*=-C160] { + color: #D70000 +} + +div.highlight .-Color[class*=-BGC160] { + background-color: #D70000 +} + +div.highlight .-Color[class*=-C161] { + color: #D7005F +} + +div.highlight .-Color[class*=-BGC161] { + background-color: #D7005F +} + +div.highlight .-Color[class*=-C162] { + color: #D70087 +} + +div.highlight .-Color[class*=-BGC162] { + background-color: #D70087 +} + +div.highlight .-Color[class*=-C163] { + color: #D700AF +} + +div.highlight .-Color[class*=-BGC163] { + background-color: #D700AF +} + +div.highlight .-Color[class*=-C164] { + color: #D700D7 +} + +div.highlight .-Color[class*=-BGC164] { + background-color: #D700D7 +} + +div.highlight .-Color[class*=-C165] { + color: #D700FF +} + +div.highlight .-Color[class*=-BGC165] { + background-color: #D700FF +} + +div.highlight .-Color[class*=-C166] { + color: #D75F00 +} + +div.highlight .-Color[class*=-BGC166] { + background-color: #D75F00 +} + +div.highlight .-Color[class*=-C167] { + color: #D75F5F +} + +div.highlight .-Color[class*=-BGC167] { + background-color: #D75F5F +} + +div.highlight .-Color[class*=-C168] { + color: #D75F87 +} + +div.highlight .-Color[class*=-BGC168] { + background-color: #D75F87 +} + +div.highlight .-Color[class*=-C169] { + color: #D75FAF +} + +div.highlight .-Color[class*=-BGC169] { + background-color: #D75FAF +} + +div.highlight .-Color[class*=-C170] { + color: #D75FD7 +} + +div.highlight .-Color[class*=-BGC170] { + background-color: #D75FD7 +} + +div.highlight .-Color[class*=-C171] { + color: #D75FFF +} + +div.highlight .-Color[class*=-BGC171] { + background-color: #D75FFF +} + +div.highlight .-Color[class*=-C172] { + color: #D78700 +} + +div.highlight .-Color[class*=-BGC172] { + background-color: #D78700 +} + +div.highlight .-Color[class*=-C173] { + color: #D7875F +} + +div.highlight .-Color[class*=-BGC173] { + background-color: #D7875F +} + +div.highlight .-Color[class*=-C174] { + color: #D78787 +} + +div.highlight .-Color[class*=-BGC174] { + background-color: #D78787 +} + +div.highlight .-Color[class*=-C175] { + color: #D787AF +} + +div.highlight .-Color[class*=-BGC175] { + background-color: #D787AF +} + +div.highlight .-Color[class*=-C176] { + color: #D787D7 +} + +div.highlight .-Color[class*=-BGC176] { + background-color: #D787D7 +} + +div.highlight .-Color[class*=-C177] { + color: #D787FF +} + +div.highlight .-Color[class*=-BGC177] { + background-color: #D787FF +} + +div.highlight .-Color[class*=-C178] { + color: #D7AF00 +} + +div.highlight .-Color[class*=-BGC178] { + background-color: #D7AF00 +} + +div.highlight .-Color[class*=-C179] { + color: #D7AF5F +} + +div.highlight .-Color[class*=-BGC179] { + background-color: #D7AF5F +} + +div.highlight .-Color[class*=-C180] { + color: #D7AF87 +} + +div.highlight .-Color[class*=-BGC180] { + background-color: #D7AF87 +} + +div.highlight .-Color[class*=-C181] { + color: #D7AFAF +} + +div.highlight .-Color[class*=-BGC181] { + background-color: #D7AFAF +} + +div.highlight .-Color[class*=-C182] { + color: #D7AFD7 +} + +div.highlight .-Color[class*=-BGC182] { + background-color: #D7AFD7 +} + +div.highlight .-Color[class*=-C183] { + color: #D7AFFF +} + +div.highlight .-Color[class*=-BGC183] { + background-color: #D7AFFF +} + +div.highlight .-Color[class*=-C184] { + color: #D7D700 +} + +div.highlight .-Color[class*=-BGC184] { + background-color: #D7D700 +} + +div.highlight .-Color[class*=-C185] { + color: #D7D75F +} + +div.highlight .-Color[class*=-BGC185] { + background-color: #D7D75F +} + +div.highlight .-Color[class*=-C186] { + color: #D7D787 +} + +div.highlight .-Color[class*=-BGC186] { + background-color: #D7D787 +} + +div.highlight .-Color[class*=-C187] { + color: #D7D7AF +} + +div.highlight .-Color[class*=-BGC187] { + background-color: #D7D7AF +} + +div.highlight .-Color[class*=-C188] { + color: #D7D7D7 +} + +div.highlight .-Color[class*=-BGC188] { + background-color: #D7D7D7 +} + +div.highlight .-Color[class*=-C189] { + color: #D7D7FF +} + +div.highlight .-Color[class*=-BGC189] { + background-color: #D7D7FF +} + +div.highlight .-Color[class*=-C190] { + color: #D7FF00 +} + +div.highlight .-Color[class*=-BGC190] { + background-color: #D7FF00 +} + +div.highlight .-Color[class*=-C191] { + color: #D7FF5F +} + +div.highlight .-Color[class*=-BGC191] { + background-color: #D7FF5F +} + +div.highlight .-Color[class*=-C192] { + color: #D7FF87 +} + +div.highlight .-Color[class*=-BGC192] { + background-color: #D7FF87 +} + +div.highlight .-Color[class*=-C193] { + color: #D7FFAF +} + +div.highlight .-Color[class*=-BGC193] { + background-color: #D7FFAF +} + +div.highlight .-Color[class*=-C194] { + color: #D7FFD7 +} + +div.highlight .-Color[class*=-BGC194] { + background-color: #D7FFD7 +} + +div.highlight .-Color[class*=-C195] { + color: #D7FFFF +} + +div.highlight .-Color[class*=-BGC195] { + background-color: #D7FFFF +} + +div.highlight .-Color[class*=-C196] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC196] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C197] { + color: #FF005F +} + +div.highlight .-Color[class*=-BGC197] { + background-color: #FF005F +} + +div.highlight .-Color[class*=-C198] { + color: #FF0087 +} + +div.highlight .-Color[class*=-BGC198] { + background-color: #FF0087 +} + +div.highlight .-Color[class*=-C199] { + color: #FF00AF +} + +div.highlight .-Color[class*=-BGC199] { + background-color: #FF00AF +} + +div.highlight .-Color[class*=-C200] { + color: #FF00D7 +} + +div.highlight .-Color[class*=-BGC200] { + background-color: #FF00D7 +} + +div.highlight .-Color[class*=-C201] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC201] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C202] { + color: #FF5F00 +} + +div.highlight .-Color[class*=-BGC202] { + background-color: #FF5F00 +} + +div.highlight .-Color[class*=-C203] { + color: #FF5F5F +} + +div.highlight .-Color[class*=-BGC203] { + background-color: #FF5F5F +} + +div.highlight .-Color[class*=-C204] { + color: #FF5F87 +} + +div.highlight .-Color[class*=-BGC204] { + background-color: #FF5F87 +} + +div.highlight .-Color[class*=-C205] { + color: #FF5FAF +} + +div.highlight .-Color[class*=-BGC205] { + background-color: #FF5FAF +} + +div.highlight .-Color[class*=-C206] { + color: #FF5FD7 +} + +div.highlight .-Color[class*=-BGC206] { + background-color: #FF5FD7 +} + +div.highlight .-Color[class*=-C207] { + color: #FF5FFF +} + +div.highlight .-Color[class*=-BGC207] { + background-color: #FF5FFF +} + +div.highlight .-Color[class*=-C208] { + color: #FF8700 +} + +div.highlight .-Color[class*=-BGC208] { + background-color: #FF8700 +} + +div.highlight .-Color[class*=-C209] { + color: #FF875F +} + +div.highlight .-Color[class*=-BGC209] { + background-color: #FF875F +} + +div.highlight .-Color[class*=-C210] { + color: #FF8787 +} + +div.highlight .-Color[class*=-BGC210] { + background-color: #FF8787 +} + +div.highlight .-Color[class*=-C211] { + color: #FF87AF +} + +div.highlight .-Color[class*=-BGC211] { + background-color: #FF87AF +} + +div.highlight .-Color[class*=-C212] { + color: #FF87D7 +} + +div.highlight .-Color[class*=-BGC212] { + background-color: #FF87D7 +} + +div.highlight .-Color[class*=-C213] { + color: #FF87FF +} + +div.highlight .-Color[class*=-BGC213] { + background-color: #FF87FF +} + +div.highlight .-Color[class*=-C214] { + color: #FFAF00 +} + +div.highlight .-Color[class*=-BGC214] { + background-color: #FFAF00 +} + +div.highlight .-Color[class*=-C215] { + color: #FFAF5F +} + +div.highlight .-Color[class*=-BGC215] { + background-color: #FFAF5F +} + +div.highlight .-Color[class*=-C216] { + color: #FFAF87 +} + +div.highlight .-Color[class*=-BGC216] { + background-color: #FFAF87 +} + +div.highlight .-Color[class*=-C217] { + color: #FFAFAF +} + +div.highlight .-Color[class*=-BGC217] { + background-color: #FFAFAF +} + +div.highlight .-Color[class*=-C218] { + color: #FFAFD7 +} + +div.highlight .-Color[class*=-BGC218] { + background-color: #FFAFD7 +} + +div.highlight .-Color[class*=-C219] { + color: #FFAFFF +} + +div.highlight .-Color[class*=-BGC219] { + background-color: #FFAFFF +} + +div.highlight .-Color[class*=-C220] { + color: #FFD700 +} + +div.highlight .-Color[class*=-BGC220] { + background-color: #FFD700 +} + +div.highlight .-Color[class*=-C221] { + color: #FFD75F +} + +div.highlight .-Color[class*=-BGC221] { + background-color: #FFD75F +} + +div.highlight .-Color[class*=-C222] { + color: #FFD787 +} + +div.highlight .-Color[class*=-BGC222] { + background-color: #FFD787 +} + +div.highlight .-Color[class*=-C223] { + color: #FFD7AF +} + +div.highlight .-Color[class*=-BGC223] { + background-color: #FFD7AF +} + +div.highlight .-Color[class*=-C224] { + color: #FFD7D7 +} + +div.highlight .-Color[class*=-BGC224] { + background-color: #FFD7D7 +} + +div.highlight .-Color[class*=-C225] { + color: #FFD7FF +} + +div.highlight .-Color[class*=-BGC225] { + background-color: #FFD7FF +} + +div.highlight .-Color[class*=-C226] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC226] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C227] { + color: #FFFF5F +} + +div.highlight .-Color[class*=-BGC227] { + background-color: #FFFF5F +} + +div.highlight .-Color[class*=-C228] { + color: #FFFF87 +} + +div.highlight .-Color[class*=-BGC228] { + background-color: #FFFF87 +} + +div.highlight .-Color[class*=-C229] { + color: #FFFFAF +} + +div.highlight .-Color[class*=-BGC229] { + background-color: #FFFFAF +} + +div.highlight .-Color[class*=-C230] { + color: #FFFFD7 +} + +div.highlight .-Color[class*=-BGC230] { + background-color: #FFFFD7 +} + +div.highlight .-Color[class*=-C231] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC231] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C232] { + color: #080808 +} + +div.highlight .-Color[class*=-BGC232] { + background-color: #080808 +} + +div.highlight .-Color[class*=-C233] { + color: #121212 +} + +div.highlight .-Color[class*=-BGC233] { + background-color: #121212 +} + +div.highlight .-Color[class*=-C234] { + color: #1C1C1C +} + +div.highlight .-Color[class*=-BGC234] { + background-color: #1C1C1C +} + +div.highlight .-Color[class*=-C235] { + color: #262626 +} + +div.highlight .-Color[class*=-BGC235] { + background-color: #262626 +} + +div.highlight .-Color[class*=-C236] { + color: #303030 +} + +div.highlight .-Color[class*=-BGC236] { + background-color: #303030 +} + +div.highlight .-Color[class*=-C237] { + color: #3A3A3A +} + +div.highlight .-Color[class*=-BGC237] { + background-color: #3A3A3A +} + +div.highlight .-Color[class*=-C238] { + color: #444444 +} + +div.highlight .-Color[class*=-BGC238] { + background-color: #444444 +} + +div.highlight .-Color[class*=-C239] { + color: #4E4E4E +} + +div.highlight .-Color[class*=-BGC239] { + background-color: #4E4E4E +} + +div.highlight .-Color[class*=-C240] { + color: #585858 +} + +div.highlight .-Color[class*=-BGC240] { + background-color: #585858 +} + +div.highlight .-Color[class*=-C241] { + color: #626262 +} + +div.highlight .-Color[class*=-BGC241] { + background-color: #626262 +} + +div.highlight .-Color[class*=-C242] { + color: #6C6C6C +} + +div.highlight .-Color[class*=-BGC242] { + background-color: #6C6C6C +} + +div.highlight .-Color[class*=-C243] { + color: #767676 +} + +div.highlight .-Color[class*=-BGC243] { + background-color: #767676 +} + +div.highlight .-Color[class*=-C244] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC244] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C245] { + color: #8A8A8A +} + +div.highlight .-Color[class*=-BGC245] { + background-color: #8A8A8A +} + +div.highlight .-Color[class*=-C246] { + color: #949494 +} + +div.highlight .-Color[class*=-BGC246] { + background-color: #949494 +} + +div.highlight .-Color[class*=-C247] { + color: #9E9E9E +} + +div.highlight .-Color[class*=-BGC247] { + background-color: #9E9E9E +} + +div.highlight .-Color[class*=-C248] { + color: #A8A8A8 +} + +div.highlight .-Color[class*=-BGC248] { + background-color: #A8A8A8 +} + +div.highlight .-Color[class*=-C249] { + color: #B2B2B2 +} + +div.highlight .-Color[class*=-BGC249] { + background-color: #B2B2B2 +} + +div.highlight .-Color[class*=-C250] { + color: #BCBCBC +} + +div.highlight .-Color[class*=-BGC250] { + background-color: #BCBCBC +} + +div.highlight .-Color[class*=-C251] { + color: #C6C6C6 +} + +div.highlight .-Color[class*=-BGC251] { + background-color: #C6C6C6 +} + +div.highlight .-Color[class*=-C252] { + color: #D0D0D0 +} + +div.highlight .-Color[class*=-BGC252] { + background-color: #D0D0D0 +} + +div.highlight .-Color[class*=-C253] { + color: #DADADA +} + +div.highlight .-Color[class*=-BGC253] { + background-color: #DADADA +} + +div.highlight .-Color[class*=-C254] { + color: #E4E4E4 +} + +div.highlight .-Color[class*=-BGC254] { + background-color: #E4E4E4 +} + +div.highlight .-Color[class*=-C255] { + color: #EEEEEE +} + +div.highlight .-Color[class*=-BGC255] { + background-color: #EEEEEE +} diff --git a/branch/cff/_static/plus.png b/branch/cff/_static/plus.png new file mode 100644 index 0000000..7107cec Binary files /dev/null and b/branch/cff/_static/plus.png differ diff --git a/branch/cff/_static/pygments.css b/branch/cff/_static/pygments.css new file mode 100644 index 0000000..84ab303 --- /dev/null +++ b/branch/cff/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/branch/cff/_static/searchtools.js b/branch/cff/_static/searchtools.js new file mode 100644 index 0000000..b08d58c --- /dev/null +++ b/branch/cff/_static/searchtools.js @@ -0,0 +1,620 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/branch/cff/_static/sphinx-design.min.css b/branch/cff/_static/sphinx-design.min.css new file mode 100644 index 0000000..860c36d --- /dev/null +++ b/branch/cff/_static/sphinx-design.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative;font-size:var(--sd-fontsize-dropdown)}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary.sd-summary-title{padding:.5em .6em .5em 1em;font-size:var(--sd-fontsize-dropdown-title);font-weight:var(--sd-fontweight-dropdown-title);user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;list-style:none;display:inline-flex;justify-content:space-between}details.sd-dropdown summary.sd-summary-title::-webkit-details-marker{display:none}details.sd-dropdown summary.sd-summary-title:focus{outline:none}details.sd-dropdown summary.sd-summary-title .sd-summary-icon{margin-right:.6em;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary.sd-summary-title .sd-summary-text{flex-grow:1;line-height:1.5;padding-right:.5rem}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker{pointer-events:none;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker svg{opacity:.6}details.sd-dropdown summary.sd-summary-title:hover .sd-summary-state-marker svg{opacity:1;transform:scale(1.1)}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown .sd-summary-chevron-right{transition:.25s}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-right{transform:rotate(90deg)}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-down{transform:rotate(180deg)}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-bg: rgba(0, 113, 188, 0.2);--sd-color-secondary-bg: rgba(108, 117, 125, 0.2);--sd-color-success-bg: rgba(40, 167, 69, 0.2);--sd-color-info-bg: rgba(23, 162, 184, 0.2);--sd-color-warning-bg: rgba(240, 179, 126, 0.2);--sd-color-danger-bg: rgba(220, 53, 69, 0.2);--sd-color-light-bg: rgba(248, 249, 250, 0.2);--sd-color-muted-bg: rgba(108, 117, 125, 0.2);--sd-color-dark-bg: rgba(33, 37, 41, 0.2);--sd-color-black-bg: rgba(0, 0, 0, 0.2);--sd-color-white-bg: rgba(255, 255, 255, 0.2);--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem;--sd-fontsize-dropdown: inherit;--sd-fontsize-dropdown-title: 1rem;--sd-fontweight-dropdown-title: 700} diff --git a/branch/cff/_static/sphinx_highlight.js b/branch/cff/_static/sphinx_highlight.js new file mode 100644 index 0000000..8a96c69 --- /dev/null +++ b/branch/cff/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/branch/cff/_static/sphinx_lesson.css b/branch/cff/_static/sphinx_lesson.css new file mode 100644 index 0000000..14b20c6 --- /dev/null +++ b/branch/cff/_static/sphinx_lesson.css @@ -0,0 +1,51 @@ +/* sphinx_lesson.css */ + +body.wy-body-for-nav img.with-border { + border: 2px solid; +} + +.rst-content .admonition-no-content { + padding-bottom: 0px; +} + +.rst-content .demo > .admonition-title::before { + content: "\01F440"; /* Eyes */ } +.rst-content .type-along > .admonition-title::before { + content: "\02328\0FE0F"; /* Keyboard */ } +.rst-content .exercise > .admonition-title::before { + content: "\0270D\0FE0F"; /* Hand */ } +.rst-content .solution > .admonition-title::before { + content: "\02714\0FE0E"; /* Check mark */ } +.rst-content .homework > .admonition-title::before { + content: "\01F4DD"; /* Memo */ } +.rst-content .discussion > .admonition-title::before { + content: "\01F4AC"; /* Speech balloon */ } +.rst-content .questions > .admonition-title::before { + content: "\02753\0FE0E"; /* Question mark */ } +.rst-content .prerequisites > .admonition-title::before { + content: "\02699"; /* Gear */ } +.rst-content .seealso > .admonition-title::before { + content: "\027A1\0FE0E"; /* Question mark */ } + + +/* instructor-note */ +.rst-content .instructor-note { + background: #e7e7e7; +} +.rst-content .instructor-note > .admonition-title { + background: #6a6a6a; +} +.rst-content .instructor-note > .admonition-title::before { + content: ""; +} + + +/* sphinx_toggle_button, make the font white */ +.rst-content .toggle.admonition button.toggle-button { + color: white; +} + +/* sphinx-togglebutton, remove underflow when toggled to hidden mode */ +.rst-content .admonition.toggle-hidden { + padding-bottom: 0px; +} diff --git a/branch/cff/_static/sphinx_rtd_theme_ext_color_contrast.css b/branch/cff/_static/sphinx_rtd_theme_ext_color_contrast.css new file mode 100644 index 0000000..e68feb8 --- /dev/null +++ b/branch/cff/_static/sphinx_rtd_theme_ext_color_contrast.css @@ -0,0 +1,47 @@ +/* The following are for web accessibility of sphinx_rtd_theme: they + * solve some of the most frequent contrast issues. Remove when this + * solved: + * https://github.com/readthedocs/sphinx_rtd_theme/issues/971 + */ +/* background: #fcfcfc, note boxes #E7F2FA */ +a { color: #2573A7; } /* original #2980B9, #1F5C84; */ +body { color: #242424; } /* original #404040, #383838 */ +.wy-side-nav-search>a, .wy-side-nav-search .wy-dropdown>a { + color: #ffffff; +} /* original #fcfcfc */ +footer { color: #737373; } /* original gray=#808080*/ +footer span.commit code, footer span.commit .rst-content tt, .rst-content footer span.commit tt { + color: #737373; +} /* original gray=#808080*/ +.rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal { + color: #AB2314; +} +/* Sidebar background */ +.wy-side-nav-search { background-color: #277CB4;} + +/* Same, but for pygments */ +.highlight .ch { color: #3E7A89; } /* #! line */ +.highlight .c1 { color: #3E7A89; } /* also comments */ +.highlight .nv { color: #AD3ECC; } /* variable */ +.highlight .gp { color: #B45608; } /* prompt character, $*/ +.highlight .si { color: #3975B1; } /* ${} variable text */ +.highlight .nc { color: #0C78A7; } + +/* Sphinx admonitions */ +/* warning */ +.wy-alert.wy-alert-warning .wy-alert-title, .rst-content .wy-alert-warning.note .wy-alert-title, .rst-content .attention .wy-alert-title, .rst-content .caution .wy-alert-title, .rst-content .wy-alert-warning.danger .wy-alert-title, .rst-content .wy-alert-warning.error .wy-alert-title, .rst-content .wy-alert-warning.hint .wy-alert-title, .rst-content .wy-alert-warning.important .wy-alert-title, .rst-content .wy-alert-warning.tip .wy-alert-title, .rst-content .warning .wy-alert-title, .rst-content .wy-alert-warning.seealso .wy-alert-title, .rst-content .admonition-todo .wy-alert-title, .rst-content .wy-alert-warning.admonition .wy-alert-title, .wy-alert.wy-alert-warning .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-warning .admonition-title, .rst-content .wy-alert-warning.note .admonition-title, .rst-content .attention .admonition-title, .rst-content .caution .admonition-title, .rst-content .wy-alert-warning.danger .admonition-title, .rst-content .wy-alert-warning.error .admonition-title, .rst-content .wy-alert-warning.hint .admonition-title, .rst-content .wy-alert-warning.important .admonition-title, .rst-content .wy-alert-warning.tip .admonition-title, .rst-content .warning .admonition-title, .rst-content .wy-alert-warning.seealso .admonition-title, .rst-content .admonition-todo .admonition-title, .rst-content .wy-alert-warning.admonition .admonition-title { + background: #B15E16; } +/* important */ +.wy-alert.wy-alert-success .wy-alert-title, .rst-content .wy-alert-success.note .wy-alert-title, .rst-content .wy-alert-success.attention .wy-alert-title, .rst-content .wy-alert-success.caution .wy-alert-title, .rst-content .wy-alert-success.danger .wy-alert-title, .rst-content .wy-alert-success.error .wy-alert-title, .rst-content .hint .wy-alert-title, .rst-content .important .wy-alert-title, .rst-content .tip .wy-alert-title, .rst-content .wy-alert-success.warning .wy-alert-title, .rst-content .wy-alert-success.seealso .wy-alert-title, .rst-content .wy-alert-success.admonition-todo .wy-alert-title, .rst-content .wy-alert-success.admonition .wy-alert-title, .wy-alert.wy-alert-success .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-success .admonition-title, .rst-content .wy-alert-success.note .admonition-title, .rst-content .wy-alert-success.attention .admonition-title, .rst-content .wy-alert-success.caution .admonition-title, .rst-content .wy-alert-success.danger .admonition-title, .rst-content .wy-alert-success.error .admonition-title, .rst-content .hint .admonition-title, .rst-content .important .admonition-title, .rst-content .tip .admonition-title, .rst-content .wy-alert-success.warning .admonition-title, .rst-content .wy-alert-success.seealso .admonition-title, .rst-content .wy-alert-success.admonition-todo .admonition-title, .rst-content .wy-alert-success.admonition .admonition-title { + background: #12826C; } +/* seealso, note, etc */ +.wy-alert.wy-alert-info .wy-alert-title, .rst-content .note .wy-alert-title, .rst-content .wy-alert-info.attention .wy-alert-title, .rst-content .wy-alert-info.caution .wy-alert-title, .rst-content .wy-alert-info.danger .wy-alert-title, .rst-content .wy-alert-info.error .wy-alert-title, .rst-content .wy-alert-info.hint .wy-alert-title, .rst-content .wy-alert-info.important .wy-alert-title, .rst-content .wy-alert-info.tip .wy-alert-title, .rst-content .wy-alert-info.warning .wy-alert-title, .rst-content .seealso .wy-alert-title, .rst-content .wy-alert-info.admonition-todo .wy-alert-title, .rst-content .wy-alert-info.admonition .wy-alert-title, .wy-alert.wy-alert-info .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-info .admonition-title, .rst-content .note .admonition-title, .rst-content .wy-alert-info.attention .admonition-title, .rst-content .wy-alert-info.caution .admonition-title, .rst-content .wy-alert-info.danger .admonition-title, .rst-content .wy-alert-info.error .admonition-title, .rst-content .wy-alert-info.hint .admonition-title, .rst-content .wy-alert-info.important .admonition-title, .rst-content .wy-alert-info.tip .admonition-title, .rst-content .wy-alert-info.warning .admonition-title, .rst-content .seealso .admonition-title, .rst-content .wy-alert-info.admonition-todo .admonition-title, .rst-content .wy-alert-info.admonition .admonition-title { + background: #277CB4; } +/* error, danger */ +.rst-content .danger .admonition-title, .rst-content .danger .wy-alert-title, .rst-content .error .admonition-title, .rst-content .error .wy-alert-title, .rst-content .wy-alert-danger.admonition-todo .admonition-title, .rst-content .wy-alert-danger.admonition-todo .wy-alert-title, .rst-content .wy-alert-danger.admonition .admonition-title, .rst-content .wy-alert-danger.admonition .wy-alert-title, .rst-content .wy-alert-danger.attention .admonition-title, .rst-content .wy-alert-danger.attention .wy-alert-title, .rst-content .wy-alert-danger.caution .admonition-title, .rst-content .wy-alert-danger.caution .wy-alert-title, .rst-content .wy-alert-danger.hint .admonition-title, .rst-content .wy-alert-danger.hint .wy-alert-title, .rst-content .wy-alert-danger.important .admonition-title, .rst-content .wy-alert-danger.important .wy-alert-title, .rst-content .wy-alert-danger.note .admonition-title, .rst-content .wy-alert-danger.note .wy-alert-title, .rst-content .wy-alert-danger.seealso .admonition-title, .rst-content .wy-alert-danger.seealso .wy-alert-title, .rst-content .wy-alert-danger.tip .admonition-title, .rst-content .wy-alert-danger.tip .wy-alert-title, .rst-content .wy-alert-danger.warning .admonition-title, .rst-content .wy-alert-danger.warning .wy-alert-title, .rst-content .wy-alert.wy-alert-danger .admonition-title, .wy-alert.wy-alert-danger .rst-content .admonition-title, .wy-alert.wy-alert-danger .wy-alert-title { + background: #e31704; +} + +/* Generic admonition titles */ +.wy-alert-title, .rst-content .admonition-title { + background: #277CB4; } diff --git a/branch/cff/_static/tabs.css b/branch/cff/_static/tabs.css new file mode 100644 index 0000000..957ba60 --- /dev/null +++ b/branch/cff/_static/tabs.css @@ -0,0 +1,89 @@ +.sphinx-tabs { + margin-bottom: 1rem; +} + +[role="tablist"] { + border-bottom: 1px solid #a0b3bf; +} + +.sphinx-tabs-tab { + position: relative; + font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; + color: #1D5C87; + line-height: 24px; + margin: 0; + font-size: 16px; + font-weight: 400; + background-color: rgba(255, 255, 255, 0); + border-radius: 5px 5px 0 0; + border: 0; + padding: 1rem 1.5rem; + margin-bottom: 0; +} + +.sphinx-tabs-tab[aria-selected="true"] { + font-weight: 700; + border: 1px solid #a0b3bf; + border-bottom: 1px solid white; + margin: -1px; + background-color: white; +} + +.sphinx-tabs-tab:focus { + z-index: 1; + outline-offset: 1px; +} + +.sphinx-tabs-panel { + position: relative; + padding: 1rem; + border: 1px solid #a0b3bf; + margin: 0px -1px -1px -1px; + border-radius: 0 0 5px 5px; + border-top: 0; + background: white; +} + +.sphinx-tabs-panel.code-tab { + padding: 0.4rem; +} + +.sphinx-tab img { + margin-bottom: 24 px; +} + +/* Dark theme preference styling */ + +@media (prefers-color-scheme: dark) { + body[data-theme="auto"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); + } + + body[data-theme="auto"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); + } + + body[data-theme="auto"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 1px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); + } +} + +/* Explicit dark theme styling */ + +body[data-theme="dark"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); +} + +body[data-theme="dark"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); +} + +body[data-theme="dark"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 2px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); +} diff --git a/branch/cff/_static/tabs.js b/branch/cff/_static/tabs.js new file mode 100644 index 0000000..48dc303 --- /dev/null +++ b/branch/cff/_static/tabs.js @@ -0,0 +1,145 @@ +try { + var session = window.sessionStorage || {}; +} catch (e) { + var session = {}; +} + +window.addEventListener("DOMContentLoaded", () => { + const allTabs = document.querySelectorAll('.sphinx-tabs-tab'); + const tabLists = document.querySelectorAll('[role="tablist"]'); + + allTabs.forEach(tab => { + tab.addEventListener("click", changeTabs); + }); + + tabLists.forEach(tabList => { + tabList.addEventListener("keydown", keyTabs); + }); + + // Restore group tab selection from session + const lastSelected = session.getItem('sphinx-tabs-last-selected'); + if (lastSelected != null) selectNamedTabs(lastSelected); +}); + +/** + * Key focus left and right between sibling elements using arrows + * @param {Node} e the element in focus when key was pressed + */ +function keyTabs(e) { + const tab = e.target; + let nextTab = null; + if (e.keyCode === 39 || e.keyCode === 37) { + tab.setAttribute("tabindex", -1); + // Move right + if (e.keyCode === 39) { + nextTab = tab.nextElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.firstElementChild; + } + // Move left + } else if (e.keyCode === 37) { + nextTab = tab.previousElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.lastElementChild; + } + } + } + + if (nextTab !== null) { + nextTab.setAttribute("tabindex", 0); + nextTab.focus(); + } +} + +/** + * Select or deselect clicked tab. If a group tab + * is selected, also select tab in other tabLists. + * @param {Node} e the element that was clicked + */ +function changeTabs(e) { + // Use this instead of the element that was clicked, in case it's a child + const notSelected = this.getAttribute("aria-selected") === "false"; + const positionBefore = this.parentNode.getBoundingClientRect().top; + const notClosable = !this.parentNode.classList.contains("closeable"); + + deselectTabList(this); + + if (notSelected || notClosable) { + selectTab(this); + const name = this.getAttribute("name"); + selectNamedTabs(name, this.id); + + if (this.classList.contains("group-tab")) { + // Persist during session + session.setItem('sphinx-tabs-last-selected', name); + } + } + + const positionAfter = this.parentNode.getBoundingClientRect().top; + const positionDelta = positionAfter - positionBefore; + // Scroll to offset content resizing + window.scrollTo(0, window.scrollY + positionDelta); +} + +/** + * Select tab and show associated panel. + * @param {Node} tab tab to select + */ +function selectTab(tab) { + tab.setAttribute("aria-selected", true); + + // Show the associated panel + document + .getElementById(tab.getAttribute("aria-controls")) + .removeAttribute("hidden"); +} + +/** + * Hide the panels associated with all tabs within the + * tablist containing this tab. + * @param {Node} tab a tab within the tablist to deselect + */ +function deselectTabList(tab) { + const parent = tab.parentNode; + const grandparent = parent.parentNode; + + Array.from(parent.children) + .forEach(t => t.setAttribute("aria-selected", false)); + + Array.from(grandparent.children) + .slice(1) // Skip tablist + .forEach(panel => panel.setAttribute("hidden", true)); +} + +/** + * Select grouped tabs with the same name, but no the tab + * with the given id. + * @param {Node} name name of grouped tab to be selected + * @param {Node} clickedId id of clicked tab + */ +function selectNamedTabs(name, clickedId=null) { + const groupedTabs = document.querySelectorAll(`.sphinx-tabs-tab[name="${name}"]`); + const tabLists = Array.from(groupedTabs).map(tab => tab.parentNode); + + tabLists + .forEach(tabList => { + // Don't want to change the tabList containing the clicked tab + const clickedTab = tabList.querySelector(`[id="${clickedId}"]`); + if (clickedTab === null ) { + // Select first tab with matching name + const tab = tabList.querySelector(`.sphinx-tabs-tab[name="${name}"]`); + deselectTabList(tab); + selectTab(tab); + } + }) +} + +if (typeof exports === 'undefined') { + exports = {}; +} + +exports.keyTabs = keyTabs; +exports.changeTabs = changeTabs; +exports.selectTab = selectTab; +exports.deselectTabList = deselectTabList; +exports.selectNamedTabs = selectNamedTabs; diff --git a/branch/cff/_static/term_role_formatting.css b/branch/cff/_static/term_role_formatting.css new file mode 100644 index 0000000..0b66095 --- /dev/null +++ b/branch/cff/_static/term_role_formatting.css @@ -0,0 +1,4 @@ +/* Make terms bold */ +a.reference span.std-term { + font-weight: bold; +} diff --git a/branch/cff/_static/togglebutton.css b/branch/cff/_static/togglebutton.css new file mode 100644 index 0000000..54a6787 --- /dev/null +++ b/branch/cff/_static/togglebutton.css @@ -0,0 +1,160 @@ +/** + * Admonition-based toggles + */ + +/* Visibility of the target */ +.admonition.toggle .admonition-title ~ * { + transition: opacity .3s, height .3s; +} + +/* Toggle buttons inside admonitions so we see the title */ +.admonition.toggle { + position: relative; +} + +/* Titles should cut off earlier to avoid overlapping w/ button */ +.admonition.toggle .admonition-title { + padding-right: 25%; + cursor: pointer; +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:hover { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 1%); +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:active { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 3%); +} + +/* Remove extra whitespace below the admonition title when hidden */ +.admonition.toggle-hidden { + padding-bottom: 0; +} + +.admonition.toggle-hidden .admonition-title { + margin-bottom: 0; +} + +/* hides all the content of a page until de-toggled */ +.admonition.toggle-hidden .admonition-title ~ * { + height: 0; + margin: 0; + opacity: 0; + visibility: hidden; +} + +/* General button style and position*/ +button.toggle-button { + /** + * Background and shape. By default there's no background + * but users can style as they wish + */ + background: none; + border: none; + outline: none; + + /* Positioning just inside the admonition title */ + position: absolute; + right: 0.5em; + padding: 0px; + border: none; + outline: none; +} + +/* Display the toggle hint on wide screens */ +@media (min-width: 768px) { + button.toggle-button.toggle-button-hidden:before { + content: attr(data-toggle-hint); /* This will be filled in by JS */ + font-size: .8em; + align-self: center; + } +} + +/* Icon behavior */ +.tb-icon { + transition: transform .2s ease-out; + height: 1.5em; + width: 1.5em; + stroke: currentColor; /* So that we inherit the color of other text */ +} + +/* The icon should point right when closed, down when open. */ +/* Open */ +.admonition.toggle button .tb-icon { + transform: rotate(90deg); +} + +/* Closed */ +.admonition.toggle button.toggle-button-hidden .tb-icon { + transform: rotate(0deg); +} + +/* With details toggles, we don't rotate the icon so it points right */ +details.toggle-details .tb-icon { + height: 1.4em; + width: 1.4em; + margin-top: 0.1em; /* To center the button vertically */ +} + + +/** + * Details-based toggles. + * In this case, we wrap elements with `.toggle` in a details block. + */ + +/* Details blocks */ +details.toggle-details { + margin: 1em 0; +} + + +details.toggle-details summary { + display: flex; + align-items: center; + cursor: pointer; + list-style: none; + border-radius: .2em; + border-left: 3px solid #1976d2; + background-color: rgb(204 204 204 / 10%); + padding: 0.2em 0.7em 0.3em 0.5em; /* Less padding on left because the SVG has left margin */ + font-size: 0.9em; +} + +details.toggle-details summary:hover { + background-color: rgb(204 204 204 / 20%); +} + +details.toggle-details summary:active { + background: rgb(204 204 204 / 28%); +} + +.toggle-details__summary-text { + margin-left: 0.2em; +} + +details.toggle-details[open] summary { + margin-bottom: .5em; +} + +details.toggle-details[open] summary .tb-icon { + transform: rotate(90deg); +} + +details.toggle-details[open] summary ~ * { + animation: toggle-fade-in .3s ease-out; +} + +@keyframes toggle-fade-in { + from {opacity: 0%;} + to {opacity: 100%;} +} + +/* Print rules - we hide all toggle button elements at print */ +@media print { + /* Always hide the summary so the button doesn't show up */ + details.toggle-details summary { + display: none; + } +} \ No newline at end of file diff --git a/branch/cff/_static/togglebutton.js b/branch/cff/_static/togglebutton.js new file mode 100644 index 0000000..215a7ee --- /dev/null +++ b/branch/cff/_static/togglebutton.js @@ -0,0 +1,187 @@ +/** + * Add Toggle Buttons to elements + */ + +let toggleChevron = ` + + + +`; + +var initToggleItems = () => { + var itemsToToggle = document.querySelectorAll(togglebuttonSelector); + console.log(`[togglebutton]: Adding toggle buttons to ${itemsToToggle.length} items`) + // Add the button to each admonition and hook up a callback to toggle visibility + itemsToToggle.forEach((item, index) => { + if (item.classList.contains("admonition")) { + // If it's an admonition block, then we'll add a button inside + // Generate unique IDs for this item + var toggleID = `toggle-${index}`; + var buttonID = `button-${toggleID}`; + + item.setAttribute('id', toggleID); + if (!item.classList.contains("toggle")){ + item.classList.add("toggle"); + } + // This is the button that will be added to each item to trigger the toggle + var collapseButton = ` + `; + + title = item.querySelector(".admonition-title") + title.insertAdjacentHTML("beforeend", collapseButton); + thisButton = document.getElementById(buttonID); + + // Add click handlers for the button + admonition title (if admonition) + admonitionTitle = document.querySelector(`#${toggleID} > .admonition-title`) + if (admonitionTitle) { + // If an admonition, then make the whole title block clickable + admonitionTitle.addEventListener('click', toggleClickHandler); + admonitionTitle.dataset.target = toggleID + admonitionTitle.dataset.button = buttonID + } else { + // If not an admonition then we'll listen for the button click + thisButton.addEventListener('click', toggleClickHandler); + } + + // Now hide the item for this toggle button unless explicitly noted to show + if (!item.classList.contains("toggle-shown")) { + toggleHidden(thisButton); + } + } else { + // If not an admonition, wrap the block in a
block + // Define the structure of the details block and insert it as a sibling + var detailsBlock = ` +
+ + ${toggleChevron} + ${toggleHintShow} + +
`; + item.insertAdjacentHTML("beforebegin", detailsBlock); + + // Now move the toggle-able content inside of the details block + details = item.previousElementSibling + details.appendChild(item) + item.classList.add("toggle-details__container") + + // Set up a click trigger to change the text as needed + details.addEventListener('click', (click) => { + let parent = click.target.parentElement; + if (parent.tagName.toLowerCase() == "details") { + summary = parent.querySelector("summary"); + details = parent; + } else { + summary = parent; + details = parent.parentElement; + } + // Update the inner text for the proper hint + if (details.open) { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintShow; + } else { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintHide; + } + + }); + + // If we have a toggle-shown class, open details block should be open + if (item.classList.contains("toggle-shown")) { + details.click(); + } + } + }) +}; + +// This should simply add / remove the collapsed class and change the button text +var toggleHidden = (button) => { + target = button.dataset['target'] + var itemToToggle = document.getElementById(target); + if (itemToToggle.classList.contains("toggle-hidden")) { + itemToToggle.classList.remove("toggle-hidden"); + button.classList.remove("toggle-button-hidden"); + } else { + itemToToggle.classList.add("toggle-hidden"); + button.classList.add("toggle-button-hidden"); + } +} + +var toggleClickHandler = (click) => { + // Be cause the admonition title is clickable and extends to the whole admonition + // We only look for a click event on this title to trigger the toggle. + + if (click.target.classList.contains("admonition-title")) { + button = click.target.querySelector(".toggle-button"); + } else if (click.target.classList.contains("tb-icon")) { + // We've clicked the icon and need to search up one parent for the button + button = click.target.parentElement; + } else if (click.target.tagName == "polyline") { + // We've clicked the SVG elements inside the button, need to up 2 layers + button = click.target.parentElement.parentElement; + } else if (click.target.classList.contains("toggle-button")) { + // We've clicked the button itself and so don't need to do anything + button = click.target; + } else { + console.log(`[togglebutton]: Couldn't find button for ${click.target}`) + } + target = document.getElementById(button.dataset['button']); + toggleHidden(target); +} + +// If we want to blanket-add toggle classes to certain cells +var addToggleToSelector = () => { + const selector = ""; + if (selector.length > 0) { + document.querySelectorAll(selector).forEach((item) => { + item.classList.add("toggle"); + }) + } +} + +// Helper function to run when the DOM is finished +const sphinxToggleRunWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} +sphinxToggleRunWhenDOMLoaded(addToggleToSelector) +sphinxToggleRunWhenDOMLoaded(initToggleItems) + +/** Toggle details blocks to be open when printing */ +if (toggleOpenOnPrint == "true") { + window.addEventListener("beforeprint", () => { + // Open the details + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.dataset["togglestatus"] = el.open; + el.open = true; + }); + + // Open the admonitions + document.querySelectorAll(".admonition.toggle.toggle-hidden").forEach((el) => { + console.log(el); + el.querySelector("button.toggle-button").click(); + el.dataset["toggle_after_print"] = "true"; + }); + }); + window.addEventListener("afterprint", () => { + // Re-close the details that were closed + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.open = el.dataset["togglestatus"] == "true"; + delete el.dataset["togglestatus"]; + }); + + // Re-close the admonition toggle buttons + document.querySelectorAll(".admonition.toggle").forEach((el) => { + if (el.dataset["toggle_after_print"] == "true") { + el.querySelector("button.toggle-button").click(); + delete el.dataset["toggle_after_print"]; + } + }); + }); +} diff --git a/branch/cff/co-teaching/index.html b/branch/cff/co-teaching/index.html new file mode 100644 index 0000000..fee9eb9 --- /dev/null +++ b/branch/cff/co-teaching/index.html @@ -0,0 +1,301 @@ + + + + + + + Co-teaching — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Co-teaching

+
+

Objectives

+
    +
  • Get to know the principle of co-teaching: How we do it and how you can too.

  • +
  • Learn the team teaching concept and how to tailor it to your situation.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 15 min

  • +
  • Exercises: 10 min

  • +
  • Discussion: 5 min

  • +
+
+
+

Overview

+

CodeRefinery lessons benefit from the application of the concepts of co-teaching.

+
+

Co-teaching

+

Co-teaching can be defined as “the division of labor between educators to plan, organize, instruct and make assessments on the same group of students, generally in a common classroom, and often with a strong focus on those teaching as a team complementing one another’s particular skills or other strengths”.

+
+

Co-teaching can be used in various forms, some of which are present in our workshops:

+
    +
  • Teaching + support, e.g. one of the teachers leading instruction while the other watches over and maintains the collaborative document (HackMD/HedgeDoc/…).

  • +
  • Another similar example is remote learning groups that watch the streamed CodeRefinery lessons guided by the local instructors.

  • +
  • Having open-source material and planning jointly allows multiple instances of a lesson to be held by multiple teachers:

    +
      +
    • parallel teaching, to different audiences at the same time,

    • +
    • alternative teaching, to different audiences at the same or different time, with potential content adjustments (for example, different installation procedures).

    • +
    +
  • +
  • Team teaching, where the lesson is presented by multiple (in most cases, two) teachers who actively engage in conversation with each other. The team-teaching concept is explained in more detail in the CodeRefinery manual.

  • +
+

In reality, different forms are very often mixed or fused together, even within a single lesson.

+

Co-teaching is not an online-only concept. However, it is very practical in online teaching due to larger number of instructors and learners potentially available to join a teaching session.

+
+
+

Co-teaching and team teaching benefits

+
    +
  • It saves preparation time. Co-teachers can rely on each other’s strengths while creating/ revising the material as well as in unexpected situations during the lesson.

  • +
  • It helps with onboarding new instructors. One of the co-teachers can be learning at the same time, either the subtleties of the material taught (in this case literally being the “voice of the audience”) or the teaching process itself.

  • +
  • Team teaching looks more interactive and engaging to the audience in many cases, without forcing the learners to speak up if they can’t or don’t want to do so.

  • +
  • It also ensures responsive feedback and less workload by having more active minds.

  • +
+
+

Are there any downsides?

+

Not every learner and not every instructor might like the team-teaching approach.

+
    +
  • It might seem less structured, unprepared, and chaotic, even with preparation.

    +
      +
    • It might create situations where instructors accidentally talk over each other or “interrupt” and change the flow of the lesson.

    • +
    • For some instructors it can be stressful to not know in advance what questions they get asked from the co-instructor.

    • +
    • Sometimes when an unexpected question is asked that throws the other instructor off, it can add to the feeling of chaos and unpreparedness.

    • +
    +
  • +
  • It can be interactive and engaging but it can also end up awkward if the co-teachers don’t have a good synergy.

    +
      +
    • Can sound awkward: Main instructor talking all the time and at the end asking co-instructor whether everything is clear and co-instructor only saying “yes”.

    • +
    • Possibly more engaging: Co-instructor asking questions which help with the flow and a common understanding of the material.

    • +
    +
  • +
+
+
+
+

Team teaching specifics

+
    +
  • For successful team teaching, additional coordination is needed, first of all to agree on the teaching model (see below) and the person in control (the director) for the lesson or its parts.

  • +
  • It’s useful to keep track of the lecture plan. The discussion is a good way to make lesson more interactive and adjust to the audience, but deviating too much will become disorienting (for example, if someone dropped their attention for a minute and now is trying to catch-up by reading lecture notes).

  • +
  • Experienced solo teacher might have a habit to keep talking (lecturing), while the co-teacher might not want to “interrupt”. Therefore, it is important for the leading presenter to anticipate and allow for remarks/ questions, and this can be different from one’s previous teaching style at first.

  • +
+
+
+

Team teaching models

+

We propose two basic models, but of course there is a constant continuum.

+
+

Guide and demo-giver

+

One person serves the role of guide, explaining the big picture and context of the examples.

+

Another, the demo-giver,

+
    +
  • shows the typing and does the examples,

  • +
  • might take the role of a learner who is asking about what is going on, to actually explain the details, or to comment occasionally.

  • +
+

Hands-on demos and exercises work especially well like this.

+
+
+

Presenter and interviewer

+

In this case, one is the presenter who is mostly explaining (including demos or examples), and trying to move the forward through the material.

+

Another, the interviewer,

+
    +
  • serves as a learner or spotter,

  • +
  • fills in gaps by asking relevant questions,

  • +
  • tries to comment to the presenter when things are going off track.

  • +
+

This can be seen as closer to classical teaching, but with a dedicated and prepared “voice of the audience”.

+
+
+

Exercise

+
+

Discuss the models of team teaching (10 min)

+

While in breakout rooms, discuss one of the basic team-teaching models presented here:

+
    +
  • Have you already tried this or similar model in your teaching?

  • +
  • Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best?

  • +
+

Write your comments in the collaborative document.

+
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Co-teaching focuses on complementing individual skills and strengths in teaching process.

  • +
  • Co-teaching may save time, reduce teachers’ workload and make lessons more interactive/ engaging.

  • +
  • Team teaching requires some adjustments in lesson preparation and delivery.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/coderefinery-intro/index.html b/branch/cff/coderefinery-intro/index.html new file mode 100644 index 0000000..1e52a61 --- /dev/null +++ b/branch/cff/coderefinery-intro/index.html @@ -0,0 +1,280 @@ + + + + + + + About the CodeRefinery project and CodeRefinery workshops in general — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • + Edit on GitHub +
  • +
+
+
+
+
+ +
+

About the CodeRefinery project and CodeRefinery workshops in general

+
+

Objectives

+
    +
  • Discuss what CodeRefinery is and how we got here

  • +
  • Understand about the challenges to define our target audience

  • +
+
+

CodeRefinery is a +Nordic e-Infrastructure Collaboration (NeIC) +project that has started in October 2016 and is currently +funded until February 2025. We are working on the continuation plans.

+

The funding from 2022-2025 is designed to keep this project active +beyond 2025 by forming a support network and building a community of +instructors and contributors.

+
+

History

+

The CodeRefinery project idea grew out of two SeSE courses given at KTH Stockholm in 2014 and 2016. +The project proposal itself was submitted to NeIC in 2015, accepted in 2015, and started in 2016.

+

We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form.

+
+
+

Goals

+
    +
  • Develop and maintain training material on good enough software development practices for researchers that write code/scripts/notebooks.

  • +
  • Our material addresses all academic disciplines and tries to be as programming language-independent as possible.

  • +
  • Provide a code repository hosting service that is open and free +for all researchers based in universities and research institutes from Nordic countries.

  • +
  • Provide training opportunities in the Nordics using (Carpentries and) CodeRefinery training materials.

  • +
  • Evolve the project towards a community-driven project with a network of instructors and contributors.

  • +
+
+
+

Community

+
+../_images/community.png +
+

Image showing the key areas of the CodeRefinery community: Workshops, chat inlcuding help channel, online meetings and co-working, +other collaborative training, eg on High Performance Computing topics.

+
+
+

CodeRefinery is not just workshops, we are community and want you to be part of it!

+

There are many different levels of involvement, from the occasional commenter in chat, +CodeRefinery ambassador (people who like the project and workshops and help us spreading the word) or lesson issue creators and lesson contributors to +local host, co-instructor or co-organizer.

+

Best first step in any case is to join the CodeRefinery Zulip chat +or let us know about your interest at support@coderefinery.org.

+
+
+

Target audience

+

One common question we get is how do we relate to the Carpentries. +This section describes how we see it:

+
+

Carpentries audience

+

The Carpentries aims to teach computational competence to learners through an applied approach, +avoiding the theoretical and general in favor of the practical and specific.

+

Mostly, learners do not need to have any prior experience in programming. +One major goal of a Carpentries workshop is to raise awareness on the tools researchers can learn/use to speed up their research.

+

By showing learners how to solve specific problems with specific tools and providing hands-on practice, +learners develops confidence for future learning.

+
+

Novices

+

We often qualify Carpentries learners as novices: they do not know what they need to learn yet. +A typical example is the usage of version control: the Carpentries lesson +Version Control with Git +aims to give a +very high level conceptual overview of Git but it does not explain how it can be used in research projects.

+
+
+
+

CodeRefinery audience

+

In that sense, CodeRefinery workshops differ from Carpentries workshops as we assume +our audience already writes code and scripts and we aim at teaching them best software practices.

+

Our learners usually do not have a good overview of best software practices but are aware of the need to learn them. +Very often, they know of the tools (Git, Jupyter, etc.) we are teaching +but have difficulties to make the best use of them in their software development workflow.

+

Whenever we can, we direct learners that do not have sufficient coding experience to Carpentries workshops.

+
+

Competent practitioners

+

We often qualify CodeRefinery learners as competent practitioners because they already have an understanding of their needs.

+
+ +
+
+

Keypoints: CodeRefinery

+
    +
  • Teaches intermediate-level software development tool lessons

  • +
  • It is difficult to define “best practices”, we try to teach “good enough” practices

  • +
  • Training network for other lessons

  • +
  • Publicly-funded discrete projects (3 projects actually) transitioning towards an open community project

  • +
  • We have online material, teaching, and exercise sessions

  • +
  • Our main target audience are competent practitioners, but also novices and experts can get something out of the workshops

  • +
  • We want more people to work with us, and to work with more people

  • +
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/collaborative-notes/index.html b/branch/cff/collaborative-notes/index.html new file mode 100644 index 0000000..6062c6d --- /dev/null +++ b/branch/cff/collaborative-notes/index.html @@ -0,0 +1,530 @@ + + + + + + + Collaborative notes — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Collaborative notes

+
+

Objectives

+
    +
  • Be able to provide a highly interactive online workshop environment with collaborative documents

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Exercise: 15 min

  • +
  • Questions & Answers: 5 min

  • +
+
+
+

Introduction

+

The Collaborative document is how you interact with the participants. +The participants can ask questions and give feedback through the collaborative +document. During a CodeRefinery session there can be a large a volume of questions. +A dedicated person, a Collaborative document-manager, is needed to answer and edit the collaborative document. +Let us see how the collaborative document is used, then discuss the role of +the editor or collaborative document-manager.

+
+
+

Collaborative document mechanics and controls

+

Technologies that can be used as a collaborative document are Hackmd, HedgeDoc, +or Google Docs

+

Hackmd or HedgeDoc are real-time text editor online. We use it to:

+
    +
  • As a threaded chat, to answer questions and provide other information without +interrupting the main flow of the room.

  • +
  • provide everyone with a more equal opportunity to ask questions.

  • +
  • create notes which will be archived, for your later reference.

  • +
+

You do not need to login/create an account to be able to edit the document.

+
+

Basic controls

+
+../_images/hackmd--controls.png +
+

This may look slightly different on mobile devices and small windows.

+
+
+
    +
  • At the top (left or right), you can switch between view, +edit, and split view and edit modes.

  • +
  • You write in markdown here. Don’t +worry about the syntax, just see what others do and try to be like +that! Someone will come and fix any problems there may be.

  • +
  • Please go back to view mode if you think you won’t edit for a +while - it will still live update.

  • +
+
+
+

Asking questions

+

Always ask questions and add new sections at the very bottom. +You can also answer and comment on older questions, too.

+
+../_images/hackmd--questions2.png +
+

Questions and answers in bullet points

+
+
+

Since we plan to publish the questions and answers later as part +of the workshop page, we recommend to not use any names. You can indicate +your own name to make it easier to discuss more during the workshop but +then always use this form: [name=Myname]. This makes it easier for +us to automatically remove all names before publishing the notes.

+

Other hints:

+
    +
  • Use +1 to agree with a statement or question (we are more likely +to comment on it).

  • +
  • Please leave some blank lines at the bottom

  • +
  • NOTE: Please don’t “select all”, it highlights for everyone and adds a +risk of losing data (there are periodic backups, but not instant).

  • +
  • It can be quite demanding to follow the collaborative document closely. Keep an eye +on it, but consider how distracted you may get from the course. For +things beyond the scope of the course, we may come back and answer +later.

  • +
+
+
+

Don’t get overwhelmed

+

There can be a flood of information on the collaborative document. Scan for what is +important, then if you would like come back later. But it is +important to keep checking it.

+
+
+

Privacy

+
    +
  • Assume the collaborative document is public and published: you never +need to put your name there.

  • +
  • The collaborative document will be published on the website afterwards. We will +remove all non-instructors names, but it’s easier if you don’t add +it there in the first place.

  • +
  • Please keep the link private during the workshop, since since +security is “editable by those who have the link”.

  • +
  • You can use [name=YOURNAME], to name yourself. We will remove +all names (but not the comments) before archiving the notes (use +this format to make it easy for us).

  • +
+
+
+
+

Exercise

+
+

Discuss how to collaborate and handle questions (15 min)

+

Write down your conclusions in the shared document. Items to discuss are:

+
    +
  • What is your experience with questions and discussions while teaching?

  • +
  • How do you deal with them?

  • +
  • What kind of technologies do you prefer: chat, shared document, or voices +and discussion raised during instruction? And why?

  • +
+
+
+
+

Collaborative Document Manager

+

We have one person who is a “Collaborative Document helper”. This isn’t the only +person that should edit and answer, but one person shouldn’t have too +much else on their mind so can focus on it. They also make sure that +the collaborative document is updated with exercise, break, and other meta-information to +keep people on track.

+

Below, (*) = important.

+
+

Before the workshop

+
    +
  • Create a new collaborative document for the workshop

  • +
  • make sure that editing is enabled for anyone without login

  • +
  • Add workshop information, links to the workshop page and material +and an example question and answer to the top of the collaborative document(see below)

  • +
+
+
+

Most things to edit (everyone)

+

Make it easy to post after the course and consistent to follow:

+
    +
  • Tag all names with [name=XXX] (so they can be removed later), +remove other personal data or make it obvious.

  • +
  • Add in information on exercises (new section for them, link, end +time, what to accomplish)

  • +
  • Make a logical section structure (# for title, ## for sections, +### for episodes, etc. - or what makes sense)

  • +
+
+
+

General Collaborative Document practices

+
+../_images/hackmd--full-demo.png +
+

A live demo of a Collaborative Document during a Q&A time. The two instructors are +discussing some of the import answers. Multiple learners have asked +questions, multiple answers, and some remaining to be answered

+
+
+

Keep it formatted well:

+
    +
  • (*) Tag names you see with [name=XXX] so that we can remove it +later.

  • +
  • Heading level # is only the page title

  • +
  • Add a new ## heading when a new lesson or similar thing is +started (introduction, icebreaker, break between lessons, etc)

  • +
  • Add a new ### heading when a new episode, exercise, break +(within exercise session)

  • +
  • Ensure people are asking questions at the bottom, direct them there +if they aren’t.

  • +
  • (*) Ensure each question is a bullet point. Each answer or follow-up +should be a bullet point below.

    +
      +
    • Should you use more deeply nested bullet points, or have only one +level below the initial question? It depends on the context, but +if a conversation goes on too long, try not to let it go too +deep.

    • +
    +
  • +
+

Update with meta-talk, so that learners can follow along easily:

+
    +
  • Add Icebreaker and introductory material of the day. Try to talk to +people as they joined to get them to open the collaborative document and answer.

  • +
  • Anything important for following along should not be only said via +voice. It needs to be in the collaborative document, too.

  • +
  • New lessons or episodes, with links to them.

  • +
  • For exercises, link to exercise and add the duration, end time, +goals. If these are unclear, bring it up to the instructor by voice.

  • +
  • Add a status display about breaks.

  • +
+

Screenshare it when necessary:

+
    +
  • During breaks and other times, share the collaborative document(including the +notification about break, and when it ends).

  • +
  • It is nice if the arrangement allows some of the latest questions to +be seen, so people are reminded to ask there.

  • +
  • Someone else may do this, but should make sure it happens.

  • +
+

Answer questions

+
    +
  • If there is an question that should be answered by the instructor by +voice, bring it up (by voice) to the instructor immediately.

  • +
  • How soon do you answer questions? Two points of view:

    +
      +
    • Answer questions right away: can be really intense to follow.

    • +
    • Wait some so that we don’t overload learners: reduces the info +flow. But then do people need to check back more often.

    • +
    • You need to find your own balance. Maybe a quick answer right +away, and more detailed later. Or delay answers during the most +important parts of the lecture.

    • +
    +
  • +
  • Avoid wall-of-text answers. If reading an answer takes too long, it +puts the person (and other people who even try to read it) behind +even more by taking up valuable mental energy. If an answer needs a +wall of text, consider these alternatives:

    +
      +
    • Progressive bullet points getting more detailed (first ones +useful alone for basic cases)

    • +
    • Don’t be worried to say “don’t worry about this now, let’s talk +later.”

    • +
    • Figure out the root problem instead of answering every possible +interpretation

    • +
    • Declare it advanced and that you will come back later.

    • +
    +
  • +
+

Ensure it can be posted quickly:

+
    +
  • The collaborative document gets posted to the workshop webpage. For this, it needs some +minimal amount of formatting (it doesn’t need to be perfect, just +not horrible).

  • +
  • All names and private information needs to be stripped. This is why +you should rigorously tag all names with [name=XXX] so they can be +removed (see above).

    +
      +
    • Learner names can be completely removed. CR staff names can be +[name=CR] or something similar.

    • +
    • There may be other private URLs at the top or bottom.

    • +
    +
  • +
  • If possible, send the PR adding the collaborative document to the workshop webpage +(though others can do this, too).

  • +
+
+
+

Collaborative document format example

+
# Workshop, day 1
+
+
+## Lesson name
+https://coderefinery.github.io/lesson/
+
+### Episode name
+https://coderefinery.github.io/01-episode/
+
+- This is a question
+  - Anwser
+  - More detailed answer
+- question
+  - answer
+
+### Exercises:
+https://link-to-exercise/.../.../#section
+20 minutes, until xx:45
+Try to accomplish all of points 1-3.  Parts 4-5 are optional.
+
+Breakout room status:
+- room 2, need help with Linux permissions
+- room 5, done
+
+### Break
+:::danger
+We are on a 10 minute break until xx:10
+:::
+
+
+## Lesson 2
+https://coderefinery.github.io/lesson-2/
+
+
+
+
+
+

Posting the collaborative document to the website

+

The collaborative document should be posted sooner rather than later, and hopefully the +steps above will make it easy to do so quickly. You could wait a few +hours, to allow any remaining questions to be asked an answered.

+
    +
  • Download as markdown

  • +
  • Remove any private links at the top

  • +
  • Adjust headings so that they are reasonable

  • +
  • Look for private info and remove it

    +
      +
    • Search document for [name=???] (change to [name=staff] or +[name=learner])

    • +
    • Any names not tagged with [name=]

    • +
    • usernames in URLs

    • +
    • private links

    • +
    +
  • +
+
+
+

Feedback template

+
## Feedback, day N
+
+:::info
+### News for day N+1
+- .
+- .
+:::
+
+### Today was (multi-answer):
+- too fast: 
+- just right: 
+- too slow: 
+- too easy: 
+- right level: 
+- too advanced: 
+- I would recommend this course to others: 
+- Exercises were good: 
+- I would recommend today to others: 
+- I wouldn't recommend today: 
+
+### One good thing about today:
+- ...
+- ...
+
+### One thing to be improved for next time:
+- ...
+- ...
+
+### Any other comments:
+- ...
+- ...
+
+
+
+

Keypoints

+
    +
  • Having a collaborative document improves communication and interaction.

  • +
  • Answering questions requires a dedicated person - A Collaborative Document Manager.

  • +
  • The collaborative document should be posted on the web site as soon as possible.

  • +
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/computational-thinking/index.html b/branch/cff/computational-thinking/index.html new file mode 100644 index 0000000..26bd609 --- /dev/null +++ b/branch/cff/computational-thinking/index.html @@ -0,0 +1,189 @@ + + + + + + + Computational thinking — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Computational thinking

+
+

Objectives

+
    +
  • Explain what is computational thinking

  • +
  • Get to know how the theory of computational thinking can be used in teaching

  • +
  • Short exercise

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 10 min

  • +
+
+

Materials available as slides.

+
+

Keypoints

+
    +
  • Computational Thinking consists of 4 main parts: decomposition, pattern recognition, abstraction and algorithmic design.

  • +
  • How can this be a useful framework for solving problems?

  • +
  • How can this be used practically?

  • +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/cool-gems/index.html b/branch/cff/cool-gems/index.html new file mode 100644 index 0000000..d173047 --- /dev/null +++ b/branch/cff/cool-gems/index.html @@ -0,0 +1,181 @@ + + + + + + + Sharing teaching gems — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Sharing teaching gems

+
+

Objectives

+
    +
  • Our goal is to share our teaching tricks and tools and demonstrate them in +very short presentations/discussions.

  • +
+
+
+

Instructor note

+
    +
  • Demonstrations: 35 min

  • +
+
+

Here we encourage participants to take the screen share for 3 minutes and +demonstrate either some tool or trick they found useful for their teaching or +something from a course you liked.

+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/feedback-and-impact/index.html b/branch/cff/feedback-and-impact/index.html new file mode 100644 index 0000000..37a1f37 --- /dev/null +++ b/branch/cff/feedback-and-impact/index.html @@ -0,0 +1,421 @@ + + + + + + + How we collect feedback and measure impact — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

How we collect feedback and measure impact

+
+

Objectives

+
    +
  • Discuss how one can collect feedback from learners (“what can we improve?”).

  • +
  • Discuss how we convert feedback into actionable items.

  • +
  • Discuss how we measure the impact of teaching (“did we achieve our goals?”).

  • +
  • Discuss the “why”.

  • +
  • Get to know the reasons and sources of inspiration behind major lesson and workshop updates.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 20 min

  • +
  • Exercises: 10 min

  • +
+
+
+

Asking questions before the workshop

+ +
+
+

Collecting feedback as we teach

+
    +
  • Each day we ask for feedback in the collaborative notes.

    +
      +
    • One good thing about today.

    • +
    • One thing to improve for next time.

    • +
    • Any other comments?

    • +
    +
  • +
  • During the workshop we sometimes check in and ask about the pace, example:

    +
    How is the speed so far? (add an "o")
    +- Too fast:   oooooo
    +- Too slow:   ooo
    +- Just right: ooooooooooooooooooo
    +
    +
    +
  • +
  • We publish all questions, answers, and feedback. Example: https://coderefinery.github.io/2024-03-12-workshop/questions/

  • +
  • How we follow up:

    +
      +
    • Some problems we can fix already before the next workshop day.

    • +
    • We convert feedback/problems into GitHub issues and track these close to the lesson material.

    • +
    +
  • +
+
+
+

Trying to measure impact with longer-term surveys

+ +
+
+

Lessons learned

+
    +
  • Think about how to measure impact/success from the beginning.

  • +
  • Make the feedback and survey results public.

  • +
  • Make the results persistent and citable.

  • +
  • Have a mechanism to follow-up on feedback.

  • +
  • Anonymization is more than just removing or dissociating names.

  • +
  • Take time designing your survey and collect feedback on the survey itself.

  • +
+
+
+

Take time designing your survey

+

We are not experts in survey design but we reached out to RISE Research +Institutes of Sweden to get feedback on our survey questions. They provided us +with a lot of valuable feedback and suggestions for improvements. +Below are few examples.

+
+

Example 1

+

First version of our survey question about impact:

+
    +
  • “Do our workshops help to save time in future?” Please quantify in hours saved: …

  • +
+

Feedback:

+
    +
  • Difficult to answer.

  • +
  • Since when? Until all eternity?

  • +
+
+Screenshot of earlier version of the survey question about impact. +
+

Earlier version of the survey question about impact.

+
+
+

Feedback:

+
    +
  • The question “Do our workshops help to save time in future?” is unspecified, +unnecessary, and leading.

  • +
  • “No time saving” does not match the wording “save time” in the question.

  • +
+
+Screenshot of later version of the survey question about impact. +
+

Later version of the survey question about impact.

+
+
+
    +
  • The wording “have you saved” now matches “No time saved”.

  • +
+
+
+

Example 2

+
    +
  • Earlier version:

    +
    Would you judge your code to be better reusable/reproducible/modular/documented
    +as a result of attending the workshop?
    +
    +- More reusable
    +- More reproducible
    +- More modular
    +- Better documented
    +- None of the above
    +
    +
    +
  • +
  • Feedback: The question is not neutrally formulated and risks leading to +over-reporting of yes answers. Consider balancing so that the questions are +formulated more neutrally.

  • +
  • Reformulated to:

    +
    After attending the workshop, would you judge your code to be
    +more reusable or not more reusable?
    +
    +- My code is more reusable
    +- My code is not more reusable
    +- Not sure
    +
    +
    +
  • +
+
+
+

Example 3

+
    +
  • Early version:

    +
    What else has changed in how you write code since attending the workshop?
    +
    +[free-form text field]
    +
    +
    +
  • +
  • Feedback: Leading and assumes that something has changed.

  • +
  • Reformulated to:

    +
    Has anything else changed in how you write code for your research after
    +attending the workshop?
    +
    +[free-form text field]
    +
    +
    +
  • +
+
+
+

Example 4

+
    +
  • Earlier version:

    +
    Has it become easier for you to collaborate on software development with your
    +colleagues and collaborators?
    +
    +- Yes
    +- Not sure
    +- No
    +
    +
    +
  • +
  • Feedback:

    +
      +
    • Leading question.

    • +
    • Avoid “Yes” and “No” response options because respondents tend to answer +“Yes” if that option is available, leading to a risk of measurement error +(acquiescence bias).

    • +
    • Do not place “Not sure” in the middle of the scale because it captures +participants who actually don’t know and should therefore be placed at the +bottom instead of in the middle of the scale.

    • +
    +
  • +
  • Reformulated to:

    +
    After attending the workshop, has it become easier or not for you to
    +collaborate on software development with your colleagues and collaborators?
    +
    +- Collaboration is easier
    +- Collaboration is not easier
    +- Not sure
    +
    +
    +
  • +
+
+
+
+

Exercise: Group discussion (10 min)

+
+

Group discussion using the collaborative notes

+
    +
  • What tricks/techniques have you tried in your teaching or seen in someone +else’s teaching that you think have been particularly effective in collecting +feedback from learners?

  • +
  • Can you give tips or share your experiences about how to convert feedback +into actionable items?

  • +
  • How do you measure the impact of your teaching? Any tips or experiences about +what you have tried or seen other courses do?

  • +
  • Anybody knows of good resources on survey design? Please link them in +the collaborative notes.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/genindex/index.html b/branch/cff/genindex/index.html new file mode 100644 index 0000000..28d3c22 --- /dev/null +++ b/branch/cff/genindex/index.html @@ -0,0 +1,170 @@ + + + + + + Index — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/branch/cff/guide/index.html b/branch/cff/guide/index.html new file mode 100644 index 0000000..34d149f --- /dev/null +++ b/branch/cff/guide/index.html @@ -0,0 +1,223 @@ + + + + + + + Instructor guide — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Instructor guide

+
+

Target audience

+
    +
  • Everyone teaching online workshops about computational topics or interested in teaching.

  • +
  • Previous and future instructors and helpers of CodeRefinery workshops.

  • +
+
+
+

Timing

+

Session 1

+
    +
  • 15 min: Intro

  • +
  • 45 min: Lesson design and development

  • +
  • 15 min: Break

  • +
  • 45 min: Lesson template

  • +
  • 15 min: Break

  • +
  • 30 min: How we collect feedback and measure impact

  • +
  • 10 min: Outro and feedback

  • +
+

Session 2

+
    +
  • 15 min: Intro

  • +
  • 10 min: About the CodeRefinery project and CodeRefinery workshops in general

  • +
  • 30 min: Collaborative notes and interaction

  • +
  • 15 min: Break

  • +
  • 35 min: Workshop overview, roles, onboarding/installation, helpers

  • +
  • 20 min: Sound

  • +
  • 15 min: Break

  • +
  • 30 min: Screenshare

  • +
  • 10 min: Outro and feedback

  • +
+

Session 3

+
    +
  • 15 min: Intro

  • +
  • 30 min: Computational thinking

  • +
  • 15 min: Break

  • +
  • 30 min: Teaching philosohies

  • +
  • 30 min: Co-teaching

  • +
  • 15 min: Break

  • +
  • 35 min: Sharing teaching tips, tricks, tools etc

  • +
  • 10 min: Outro and feedback

  • +
+

Session 4

+
    +
  • 15 min: Intro

  • +
  • 10 min: Why we stream

  • +
  • 20 min: Behind the stream

  • +
  • 15 min: Video editing (part 1)

  • +
  • 15 min: Break

  • +
  • 25 min: Video editing (part 2, exercise)

  • +
  • 20 min: OBS introduction

  • +
  • 15 min: Break

  • +
  • 30 min: OBS setup

  • +
  • 15 min: What’s next?

  • +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/index.html b/branch/cff/index.html new file mode 100644 index 0000000..944e903 --- /dev/null +++ b/branch/cff/index.html @@ -0,0 +1,275 @@ + + + + + + + Train the trainer workshop — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Train the trainer workshop

+
+

August/September 2024 CodeRefinery train the trainer workshop

+

Do you teach the use of computers and computational tools? Are you curious about scaling your training and learn about tested and proven practices from CodeRefinery workshops and other trainers? Join us for the CodeRefinery train the trainer workshop: four self-contained sessions on tools and techniques for computational training offer a great chance to enhance your teaching skills and learn about new tools and practices. What you will learn is also used a lot outside CodeRefinery, whenever good beginner friendly training is needed.

+

Learning objectives:

+
    +
  • Learn about tools and techniques and practice to create engaging online teaching experiences (screenshare, audio, etc.).

  • +
  • Become mentally ready to be an instructor in a collaborative interactive online workshop (not only large workshops but in general).

  • +
  • Learn how to design and develop lesson material collaboratively.

  • +
+

Target audience:

+
    +
  • Everyone teaching online workshops about computational topics or interested in teaching.

  • +
  • Previous and future instructors and helpers of CodeRefinery workshops.

  • +
+

Prerequisites: +An interest in teaching.

+

Workshop structure: +We aim for a mix of modular presentations and work in small groups. The latter will be done in breakoutrooms - +be prepared to switch on your camera and have a fruitful exchange with fellow participants!

+

Organizers and instructors:

+

The workshop is organized by partner organizations of the CodeRefinery project.

+

Facilitators and instructors:

+
    +
  • Radovan Bast

  • +
  • Richard Darst

  • +
  • Bjørn Lindi

  • +
  • Dhanya Pushpadas

  • +
  • Jarno Rantaharju

  • +
  • Stephan Smuts

  • +
  • Stepas Toliautas

  • +
  • Samantha Wittke

  • +
+

Content and timing:

+

The workshop consists of four sessions every Tuesday between August +13th and September 3rd 2024, + to +:

+
    +
  • Session 1: About lesson design, deployment and iterative improvement (Aug 13)

  • +
  • Session 2: Tools and techniques adopted in CodeRefinery workshops (Aug 20)

  • +
  • Session 3: About teaching & cool things we all would like to share (Aug 27)

  • +
  • Session 4: Workshop streaming practices and post-workshop tasks (Sep 3)

  • +
+

You can join all sessions, or the just the ones that interest you. More details on each session will be shared later.

+

The workshop is free of charge for everyone, please register below to get the Zoom link and other useful information for the workshop.

+

The workshop is over and registration is closed now.

+

If you have any questions, please write to support@coderefinery.org.

+
+ + + + + +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/lesson-development/index.html b/branch/cff/lesson-development/index.html new file mode 100644 index 0000000..ba986b1 --- /dev/null +++ b/branch/cff/lesson-development/index.html @@ -0,0 +1,424 @@ + + + + + + + Lesson design and development — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Lesson design and development

+
+

Objectives

+
    +
  • We share our design processes for teaching material and presentations.

  • +
  • Learn how to design lessons “backwards”, starting from learning objectives +and learner personas.

  • +
  • Learn good practices for improving existing material based on feedback.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 20 min

  • +
  • Exercises: 35 min

  • +
+
+
+

Exercise: How do you design your teaching material?

+
+

We collect notes using a shared document (5 min)

+
    +
  • When you start preparing a new lesson or training material, where do you start?

  • +
  • What tricks help you with “writer’s block” or the empty page problem?

  • +
  • Maybe you haven’t designed training material yet. But how do you start when creating a new presentation?

  • +
  • If your design process has changed over time, please describe what you used to do and what you do now instead.

  • +
  • What do you know now about preparing lessons/training/presentations that you wish you knew earlier?

  • +
+
+
+
+

Creating new teaching material

+
+

Typical problems

+
    +
  • Someone creates a lesson, but they think about what is interesting to them, +not what is important for the learners.

  • +
  • “I want to show a number of things which I think are cool about +tool X - how do I press these into 90 minutes?”

  • +
  • Write down material you want to cover and then sprinkle in some exercises.

  • +
  • Thinking about how I work, not how the learners work.

  • +
  • Trying to bring learners to their level/setup, not trying to meet the learners +where they are.

  • +
  • Not really knowing the learning objectives or the learner personas.

  • +
+
+
+

Better approach

+

Good questions to ask and discuss with a group of colleagues from diverse backgrounds:

+
    +
  • What is the expected educational level of my audience?

  • +
  • Have they been already exposed to the technologies I am planning to teach?

  • +
  • What tools do they already use?

  • +
  • What are the main issues they are currently experiencing?

  • +
  • What do they need to remember/understand/apply/analyze/evaluate/create +(Bloom’s taxonomy)?

  • +
  • Define learner personas.

  • +
  • It may be an advantage to share an imperfect lesson with others early to +collect feedback and suggestions before the lesson “solidifies” too much. +Draft it and collect feedback. The result will probably be better than +working in isolation towards a “perfect” lesson.

  • +
+
+
+

The process of designing a lesson “backwards”

+

As described in “A lesson design process” in the book Teaching Tech +Together:

+
    +
  1. Understand your learners.

  2. +
  3. Brainstorm rough ideas.

  4. +
  5. Create an summative assessment to know your overall goal.

    +
    +

    [Think of the things your learners will be able to do at the end of the lesson]

    +
    +
  6. +
  7. Create formative assessments to go from the starting point to this.

    +
    +

    [Think of some engaging and active exercises]

    +
    +
  8. +
  9. Order the formative assessments (exercises) into a reasonable order.

  10. +
  11. Write just enough material to get from one assessment (exercise) to +another.

  12. +
  13. Describe the course so the learners know if it is relevant to them.

  14. +
+
+
+
+

Improving existing lessons

+
+

All CodeRefinery lessons are on GitHub

+ +
+

Collect feedback during the workshop:

+
    +
  • Collect feedback from learners and instructors (Example from a past +workshop).

  • +
  • Convert feedback about lessons and suggestions for improvements into issues +so that these don’t get lost and stay close to the lesson material.

  • +
+

Collect feedback before you start a big rewrite:

+
    +
  • First open an issue and describe your idea and collect feedback before you +start with an extensive rewrite.

  • +
  • For things still under construction, open a draft pull/merge request to collect +feedback and to signal to others what you are working on.

  • +
+

Small picture changes vs. big picture changes:

+
    +
  • Lesson changes should be accompanied with instructor guide changes (it’s like +a documentation for the lesson material).

  • +
  • Instructor guide is essential for new instructors.

  • +
  • Before making larger changes, talk with somebody and discuss these changes.

  • +
+
+
+

Use case: our lessons

+

As an example to demonstrate the process of designing and improving lessons, we +will have a look at one of our own lessons: Introduction to version control +with Git.

+
    +
  • Initial 2014-2016 version

    + +
  • +
  • Some time in 2014-2015 attended Carpentries instructor training.

  • +
  • 2016: CodeRefinery started.

  • +
  • 2017: Started a new repository based on the Carpentries lesson template (at the time using Jekyll).

    +
      +
    • Exercises become part of the lesson.

    • +
    • We start in the command line and only later move to GitHub.

    • +
    +
  • +
  • 2019: A lot more thought about learning objectives and personas.

    +
      +
    • Also license change to CC-BY.

    • +
    +
  • +
  • 2022: Convert lesson from Jekyll to Sphinx.

    +
      +
    • Using the tools that we teach/advocate.

    • +
    • We can have tabs and better code highlighting/emphasis.

    • +
    • Easier local preview (Python environment instead of Ruby environment which we were not used to in our daily work).

    • +
    +
  • +
  • 2024: Big redesign. We move the lesson closer to where learners are.

    +
      +
    • Start from GitHub instead of on the command line.

    • +
    • Start from an existing repository instead of with an empty one.

    • +
    • Offer several tracks to participate in the lesson (GitHub, VS Code, and command line) and learners can choose which one they want to follow.

    • +
    • Blog post: We have completely changed our Git lessons. Hopefully to the better.

    • +
    +
  • +
  • Next steps?

    +
      +
    • Making the lesson citable following +our blog post.

    • +
    • Improvements based on what we learn from this workshop.

    • +
    +
  • +
+

The overarching trend was to make the lesson simpler and more accessible - to +meet the learners where they are instead of pulling them to the tool choices of +the instructors. Looking back, we learned a lot and the learning process is +not over yet.

+
+
+

Exercise: Discussion about learning objectives and exercise design

+
+

We work in groups but use the shared document as result (20 min)

+
    +
  1. As a group pick a lesson topic. It can be one of the topics listed here but +you can also choose something else that your group is interested in, or a topic +that you have taught before or would like to teach. Some suggestions:

    +
      +
    • Git: Creating a repository and porting your project to Git and GitHub

    • +
    • Git: Basic commands

    • +
    • Git: Branching and merging

    • +
    • Git: Recovering from typical mistakes

    • +
    • Code documentation

    • +
    • Jupyter Notebooks

    • +
    • Collaboration using Git and GitHub/GitLab

    • +
    • Using GitHub without the command line

    • +
    • Project organization

    • +
    • Automated testing

    • +
    • Data transfer

    • +
    • Data management and versioning

    • +
    • Code quality and good practices

    • +
    • Modular code development

    • +
    • How to release and publish your code

    • +
    • How to document and track code dependencies

    • +
    • Recording environments in containers

    • +
    • Profiling memory and CPU usage

    • +
    • Strategies for parallelization

    • +
    • Conda environments

    • +
    • Data processing using workflow managers

    • +
    • Regular expressions

    • +
    • Making papers in LaTeX

    • +
    • Making figures in your favorite programming language

    • +
    • Linux shell basics

    • +
    • Something non-technical, such as painting a room

    • +
    • Introduction to high-performance computing

    • +
    • A lesson you always wanted to teach

    • +
    • +
    +
  2. +
  3. Try to define 2-3 learning objectives for the lesson and write them down. +You can think of these as “three simple enough messages that someone will +remember the next day” - they need to be pretty simple.

  4. +
  5. Can you come up with one or two engaging exercises that could be used to +demonstrate one of those objectives? +They should be simple enough people can actually do them. Creating simple exercises is not easy. +Some standard exercise types:

    +
      +
    • Multiple choice (easy to get feedback via a classroom tool - try to design each wrong answer so that it identifies a specific misconception).

    • +
    • Code yourself (traditional programming)

    • +
    • Code yourself + multiple choice to see what the answer is (allows you to get feedback)

    • +
    • Inverted coding (given code, have to debug)

    • +
    • Parsons problems (working solution but lines in random order, learner must only put in proper order)

    • +
    • Fill in the blank

    • +
    • Discussions, self directed learning exercises

    • +
    +
  6. +
+
+
+
+

Great resources

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/lesson.pdf b/branch/cff/lesson.pdf new file mode 100644 index 0000000..5b8b2c4 Binary files /dev/null and b/branch/cff/lesson.pdf differ diff --git a/branch/cff/lessons-with-git/index.html b/branch/cff/lessons-with-git/index.html new file mode 100644 index 0000000..01601a5 --- /dev/null +++ b/branch/cff/lessons-with-git/index.html @@ -0,0 +1,433 @@ + + + + + + + Lessons with version control — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Lessons with version control

+
+

Objectives

+
    +
  • Understand why version control is useful even for teaching material

  • +
  • Understand how version control managed lessons can be modified.

  • +
  • Understand how the CodeRefinery lesson template is used to create new lessons

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 25 min

  • +
  • Exercises or demos: 20 min

  • +
+
+
+

Why version control?

+
    +
  • If you are in CodeRefinery TTT, you probably know what version +control is and why it is important.

  • +
  • The benefits of version control also extend to lessons:

    +
      +
    • Change history

    • +
    • Others can submit contributions

    • +
    • Others can make derived versions and sync up later

    • +
    • Same workflow as everything else

    • +
    • Write it like documentation: probably more reading after than +watching it as a presentation.

    • +
    +
  • +
  • Disadvantages

    +
      +
    • “What you see is what you get” editing is hard

    • +
    • Requires knowing version control

    • +
    +
  • +
+
+

Accepting the smallest contribution

+

Question: if someone wants to make a tiny fix to your material, can they?

+
+
+
+

Tour of lesson templates options

+

There are different ways to make lessons with git. Some dedicated to +teaching:

+ +

Our philosophy is that anything works: it doesn’t have to be just +designed for lessons

+
    +
  • Jupyter Book

    +
      +
    • Example: https://jupyterbook.org/

    • +
    • Note: is based on sphinx, many extensions here are used in CR lessons

    • +
    +
  • +
  • Various ways to make slides out of Markdown

  • +
  • Cicero: GitHub-hosted Markdown to slides easily

    + +
  • +
  • Whatever your existing documentation is.

  • +
+

We like the CodeRefinery format, but think that you should use +whatever fits your needs the most.

+
+
+

Sphinx

+
    +
  • We build all our lesson material with Sphinx

  • +
  • Generate HTML/PDF/LaTeX from RST and Markdown.

  • +
  • Many Python projects use Sphinx for documentation but Sphinx is not limited to Python.

  • +
  • Read the docs hosts public Sphinx documentation for free!

  • +
  • Also hostable anywhere else, like Github pages, like our lesson material

  • +
  • For code a selling point for Sphinx is that also API documentation +is possible.

  • +
+

Sphinx is a doc generator, not HTML generator. It can:

+
    +
  • Markdown, Jupyter, and ReST (and more…) inputs. Executable inputs.

    +
      +
    • jupyter-book is Sphinx, so anything it can do we can do. This was one of the +inspirations for using Sphinx

    • +
    +
  • +
  • Good support for inline code. Much more than static code display, if +you want to look at extensions.

  • +
  • Generate different output formats (html, single-page html, pdf, epub, etc.)

  • +
  • Strong cross-referencing within and between projects

  • +
+
+
+

CodeRefinery lesson template

+

It is “just a normal Sphinx project” - with extensions:

+
    +
  • Sphinx lesson extension

    +
      +
    • adds is various directives (boxes) tuned to lesson purposes

    • +
    • provides a sample organization and template repo you can use so that lessons look consistent

    • +
    +
  • +
  • Sphinx gives us other nice features for free

    +
      +
    • Tabs: they are very important for us and allow us to customize in-place instead of copying everything and fragmenting lessons

    • +
    • Emphasize lines: they make it easier to spot what has changed in longer code snippets

    • +
    • Various input formats

      +
        +
      • Markdown (via the MyST-parser), ReStructured text, Jupyter +Notebooks.

      • +
      +
    • +
    • Many other features designed for presenting and interacting with code

    • +
    +
  • +
  • It’s fine if you use some other static site generator or git-based lesson method.

  • +
+
+

Instructors go through the building and contributing process

+

Depending on the course, instructors will demo what is roughly +exercise 4 below. Or a course might go straight to exercises.

+
    +
  • Instructors decide what change they would want to make

  • +
  • Instructors clone the repository

  • +
  • Instructors make the change

  • +
  • Instructors set up the build environment

  • +
  • Instructors build and preview

  • +
  • Instructors command and send upstream

  • +
+
+
+
+

Exercises

+

Some exercises have prerequisites (Git or Github accounts). Most +instances of this course will have you do 1 and 2 below.

+
+

Lesson-VCS-1: Present and discuss your own lesson formats

+

We don’t want to push everyone towards one format, but as long as you +use Git, it’s easy to share and reuse.

+
    +
  • Discuss what formats you do use

  • +
  • Within your team, show examples of the lessons formats you use +now. Discuss what is good and to-be-improved about them.

  • +
  • Look at how they source is managed and how easy it might be to edit.

  • +
+
+
+

Lesson-VCS-2: Tour a CodeRefinery or Carpentries lesson on Github

+
    +
  • Look at either a CodeRefinery or Carpentries lesson

    + +
  • +
  • Can you find

    +
      +
    • Where is the content of the lessons?

    • +
    • What recent change propsals (pull requests) have been made?

    • +
    • What are the open issues?

    • +
    • How you would contribute something?

    • +
    • How would you use this yourself?

    • +
    +
  • +
+
+
+

Lesson-VCS-3: Modify a CodeRefinery example lesson on Github

+

In this, you will make a change to a lesson on Github, using only the +Github interface. (Github account required, and we assume some +knowledge of Github. Ask for help in your team if it is new to you!)

+
    +
  • Navigate to the example lesson we have set up: +repo, web

  • +
  • Go to some page and follow the link to go to the respective page on +Github. (Alternatively, you can find the page from the Github repo directly).

  • +
  • Follow the Github flow to make a change, and open a Pull Request +with the change proposal:

    +
      +
    • Click on the pencil icon

    • +
    • Make a change

    • +
    • Follow the flow to make a commit and change. You’ll fork the +repository to make your own copy, add a message, and open a pull +request.

    • +
    +
  • +
+

We will look at these together and accept some changes.

+
+
+

Lesson-VCS-4: Clone and build a CodeRefinery lesson locally

+

In this exercise, you will use Git to clone one a CodeRefinery lesson +and try to preview it locally. It assumes installation and knowledge +of Git.

+
    +
  • Use this sample repository: +git-intro (or whatever +else you would like)

  • +
  • Clone the repository to your own computer

  • +
  • Create a virtual environment using the requirements.txt +contained within the repository.

  • +
  • Build the lesson.

    +
      +
    • Most people will probably run: sphinx-build content/ _build/

    • +
    • If you have make installed you can make html

    • +
    • Look in the _build directory for the built HTML files.

    • +
    +
  • +
+

Overall, this is pretty easy and straightforward, if you have a Python +environment set up. The CodeRefinery documentation +lesson teaches +this for every operating system.

+

This same tool can be used to build documentation for other software +projects and is pretty standard.

+
+
+

Lesson-VCS-5: (advanced) Create your own lesson using the CodeRefinery format

+

In this lesson, you’ll copy the CodeRefinery template and do basic +modifications for your own lesson.

+
    +
  • Clone the lesson template: +https://github.com/coderefinery/sphinx-lesson-template

  • +
  • Attempt to build it as it is (see the previous exercise)

  • +
  • How can you do tabs?

  • +
  • How can you highlight lines in code boxes?

  • +
  • How can you change color, logo and fonts?

  • +
  • What directives are available?

  • +
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Version control takes teaching materials to the next level: +shareable and easy to contribute

  • +
  • There are different formats that use version control, but we like +Sphinx with a sphinx-lesson extension.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/notes-archive/index.html b/branch/cff/notes-archive/index.html new file mode 100644 index 0000000..084aa0b --- /dev/null +++ b/branch/cff/notes-archive/index.html @@ -0,0 +1,2862 @@ + + + + + + + Collaborative notes archives from workshops — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Collaborative notes archives from workshops

+
+

August/September 2024

+
+

Day1: Session 1 (13.08.24) - About lesson design, deployment and iterative improvement

+
+

:calendar: Schedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 10.00

Lesson design and development

10.15 - 11.00

8.15 - 9.00

10.00 - 10.15

Break

11.00 - 11.15

9.00 - 9.15

10.15 - 11.00

Lessons with version control

11.15 - 12.00

9.15 - 10.00

11.00 - 11.15

Break

12.00 - 12.15

10.00 - 10.15

11.15 - 12.00

How we collect feedback and measure impact

12.15 - 13.00

10.15 - 11.00

+
+
+

:icecream: Icebreaker

+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :Decaffed … and going strong …

  • +
  • :coffee: 🤔

  • +
  • :100: (ironically!) :coffee: intake happening

  • +
  • :smile:

  • +
  • :tired_face:

  • +
  • :coffee: :party:

  • +
  • :coffee: :happy:

  • +
  • 😪

  • +
  • just got zoom installed / before my coffee

  • +
  • :smil-

  • +
  • :sweat_smile: (+)

  • +
  • :yawning_face:

  • +
  • :is it morning already?

  • +
  • :smile:

  • +
  • :yawning_face:

  • +
  • :nerded_face:

  • +
  • 🥵

  • +
  • :smile:

  • +
  • :sleeping:

  • +
  • :sleepy: :coffee: :smiley_cat:

  • +
  • 🥳

  • +
  • :coffee:

  • +
  • :coffee:

  • +
+
+
+
Introduction in breakoutrooms.
+
    +
  • Name / Affiliation / Location

  • +
+
+
+
About teaching
+

What is the hardest thing about teaching for you?

+
    +
  • Knowing how “it’s going”, whether learners are happy or not (especially when teaching online) :+1:

  • +
  • The preparation the night before. It is always much more that I would hope, no matter how prepared I want it to be :+1: :+1:

  • +
  • Managing groups with vastly different academic backgrounds

  • +
  • Teaching wide spectrum of skill level at the same time. :+1: :+1: :+1: :+1:

  • +
  • Time management! (Knowing how much can fit in a sessions) :+1: :+1:

  • +
  • General preparation time, how to fit it into the regular work schedule, and estimate how much time is needed for prep.

  • +
  • How to reduce too much text into just the right amount

  • +
  • Preparation of the session material and estimating the right amount of time for each section

  • +
  • Getting learners to take the first step: sign up for and attend a workshop, when they don’t think programming is a skill they can learn

  • +
  • Getting learners to take the second step: translating what they’ve learned in a workshop into something they can apply

  • +
  • preparation and time management

  • +
  • Engaging with the students which was much easier for me when I used to coach

  • +
  • Finding the right depth for an unknown audience for “my topic”

  • +
  • education background of participants and their learning objectives

  • +
+

What is the best thing about teaching for you?

+
    +
  • Seeing when learner gets interested/curious about something and takes inspiration from the course. :+1:

  • +
  • Seeing it works and someone can do something new.

  • +
  • Motivated students grasping new stuff

  • +
  • Students picking up and running with the matertial and skills I give them and using it for their own work. :+1:

  • +
  • The “ah-ha!” moment when a student gets it! :+1::100: :+1:

  • +
  • Learning from students who know about some topic more than you do. :+1:

  • +
  • Being able to help people reach their goals, by showing them something new.

  • +
  • Teaching is optimism acted out in the hope of making a difference both ways I suppose.

  • +
  • The feeling of accomplishment when you see learning grow and implement the learnings :book:

  • +
  • mutual learning and impact on learners :+1:

  • +
  • Results and feedbacks / Mutual interests and interesting discussions

  • +
  • mutual learning and I can also learn lots of things and new ideas from participants

  • +
+
+
+
+

:question: Questions

+
+
General / Practicalities
+
    +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms? I’m not in a place where I can talk, so if we’re going to talk a lot I’ll need to move offices

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    +
  • +
  • +
+
+
+
Episode 1: Lesson design and development
+

Materials: https://coderefinery.github.io/train-the-trainer/lesson-development/ +Discussion:

+
    +
  • When you start preparing a new lesson or training material, where do you start?

    +
      +
    • I look at existing materials on the same topic, but chose/refine topics based on the perceived needs/interests of the presumed audience

    • +
    • Outline of structure and Material collection for a new lesson :+1:

    • +
    • What material I have already? (what other material is already out there?)

    • +
    • Start by looking for related resources (documents, videos, courses, etc) to have a base data and better understanding of what have been done around the topic

    • +
    • Know your audience

    • +
    • Review existing material

    • +
    • Think about learning objectives (to keep focus on essential things)

    • +
    • Think of three things simple enough that they will be remembered the next day. Design around that.

    • +
    • I write down the thoughts that I have and then go back and structure it.

    • +
    +
  • +
  • What tricks help you with “writer’s block” or the empty page problem?

    +
      +
    • Write anything down that comes to mind, sometimes draw something, looking out the window :)

    • +
    • Do a mind map - what concepts do I want to get across?

    • +
    • Starting small, for example a list of headings and then building around it. :+1:

    • +
    • What does one know about the target audience and why should they be spending longer than 1 minute listening to what they will eventually get to hear?

    • +
    • Get some inspiration from another source.

    • +
    • Start with the three things above

    • +
    • Start with the plan and the overview design

    • +
    • Some kind of outline / main message(s)

    • +
    • Start with three things. Three supporting points for each of these.

    • +
    +
  • +
  • Maybe you haven’t designed training material yet. But how do you start when creating a new presentation?

    +
      +
    • Think about the learning objectives and try to break them down into steps

    • +
    • Title, Objectives, target audience and Plan

    • +
    • Some kind of outline / main message(s). Get as many images as I can, instead of words

    • +
    • Draft an outline and use chatgpt to fill in details

    • +
    • Example of how the teaching content is applied in a real-world context

    • +
    +
  • +
  • If your design process has changed over time, please describe what you used to do and what you do now instead.

    +
      +
    • I look more at existing materials and try to get more information about the audience. Unfortunately getting information about the audience before the event is hard

    • +
    • I used to start from the begginning and get from there but that often meant a very polished start and a rushed end. Now I try an overview first, then fil out sparsed details at every section

    • +
    • Updating the data and tweak the presentation

    • +
    • If I am teaching a small group (or one to one) talk to them before hand - find out what they know already, what they want to learn.

    • +
    +
  • +
  • What do you know now about preparing lessons/training/presentations that you wish you knew earlier?

    +
      +
    • less is more. It’s better to have 2-3 main messages rather than trying to show everything in one go :+1: :+1: :+1: :+1:

    • +
    • how much practice time the learners need to master what’s taught

    • +
    • Don’t worry about something going wrong. It often makes the lesson (and thus the material) more presistent in memory. :+1:

    • +
    • Try and remove everything except what you want the person to learn

      +
        +
      • That’s a very tough part for me in the sense that I never know how much of an underlying “black box” is still ok….

      • +
      +
    • +
    • Designing intermediate materials is hard, and requires putting some “gatekeeping” making sure that learners are directed to appropriate courses

    • +
    • When I see a cool graphic, concept, slide, etc., download it and save it in my ‘new-materials’ folder to use later on!

    • +
    • I have come to the conclusion that perhaps a more “agile” approach to developing materials (try to do design/teaching iterations quickly) might be the best way to go, but there are risks with this approach too

    • +
    +
  • +
+

Questions

+
    +
  • From zoom chat: Can you expand on what a learner persona is?

    +
      +
    • A defined example person described in terms of the materials you are preparing, making up a story about the background and interest of t

    • +
    • Answer from chat: A learner persona is a blackbox which has a very simple algorithm inside: GIGO.

    • +
    • Answer from chat: I think it’s the same as ICP (Ideal customer persona) where you describe the learner as a customer

    • +
    • Answer from chat: I’m a big fan of “How Learning Works” by Ambrose et al https://bookshop.org/p/books/how-learning-works-eight-research-based-principles-for-smart-teaching-michele-dipietro/18640868?ean=9781119861690

    • +
    • See also book: Teaching tech together

    • +
    +
  • +
+
+

CodeRefinery lessons: https://coderefinery.org/lessons/

+
+
    +
  • From chat: Do you have an example of an instructor guide?

    + +
  • +
  • From zoom chat: Do you have a “measure” of how better are the new lesson compared to the old ones? Does it make sense to talk about measurements here?

    +
      +
    • So far we only have daily feedback that we collect at the end of the day and we can compare that to earlier daily feedbacks. More about that in the last episode of today. But measuring this is indeed not easy and it also takes time to capture the effect during longer-term surveys. Some of the changes were more leap-of-faith than based on data.

    • +
    • I guess that sometimes one can use “compelling arguments” instead of data to justify a decision

    • +
    +
  • +
  • Software Carpentry does teach using the command line, and gives a session on the command line before. What do you think about this approach? Are you stating that a 3-hour lesson about CLI is not sufficient to make people comfortable enough to use that for version control?

    +
      +
    • Yes, good question. For CR we consider it a more advanced step: we do think people should learn command line, but it’s for a different course. We accept some people might not know it or want to know it so adapt to that.

    • +
    • In general, we’ve found the “you need X, but have to learn A, B, and C first” approach should be avoided if possible: people are busy, try to reach people where they are.

    • +
    +
  • +
+
+

Exercise in breakoutrooms

+
+
    +
  • Room 1

    +
      +
    • Research data management

    • +
    • Objectives

      +
        +
      • Research life cycle

      • +
      • FAIR principles (Findable, Accessible, Interoperable, Reusable)

      • +
      +
    • +
    • Exercise

      +
        +
      • develop a data management plan (DMP) that outlines how their research data will be handled throughout its lifecycle.

      • +
      +
    • +
    +
  • +
  • Room 2: What is the difference between eating breakfast and sitting through a lecture? (Tip: Start by listing the similarities …)

  • +
  • Room2 : Making papers in LaTeX +- What is LaTex and how is it different from editors like Word +- Basic Structures +- How to find and use a template +- Including figure & table +- How to use references and labels +- Exercise: to create a new LaTeX document & edit it +- Excercise: common error messages: can you find the error in this code? +- Exce

  • +
  • Room 3

    +
      +
    • GPU Programming (1 hour intro)

    • +
    • Learning objectives:

      +
        +
      • What is GPU programming.

      • +
      • When is it usable, beneficial to use GPU programming?

      • +
      • What are technologies to do GPU programming?

      • +
      • [What are and how to manage typical issues]

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • Git / Figures / Project management / data cleaning

    • +
    • Chose data cleaning

    • +
    • Three learning objectives:

      +
        +
      1. What do we mean by “clean”? How to identify it?

      2. +
      3. Identify some common problems in a dataset

      4. +
      5. Identifying and handling missing values/fields

      6. +
      +
    • +
    • Exercise

      +
        +
      1. Discuss problems, find the most common ones

        +
          +
        • In small groups

        • +
        • What problems have you run into with datasets you’ve worked with?

        • +
        • What problems can you imagine, or have you heard about from colleagues/news/social media?

        • +
        • Report back, instructor collects all problems into a list

        • +
        +
      2. +
      3. Have a dataset to clean; a clean and a messy example

        +
          +
        • (identifying) Using a visualisation or overviewing tool?

        • +
        +
      4. +
      +
    • +
    +
  • +
  • Room 5

    +
      +
    • Jupyter Notebooks

    • +
    • Learning Objectives

      +
        +
      • Can setup an enviroment you can reuse / can share with others / a project.

      • +
      • The order you run the commands in needs to match the order of the code in the Notebook - otherwise you end up in a pickle.

      • +
      • Why use a Jupyter Notebook? What are the advantages? Easy to use environment.

      • +
      +
    • +
    • Exercise

      +
        +
      • Print variable assignments from different cells - show that the order you run the code is important.

      • +
      • hand out a domain specific notebook that does some calculations and visualization to run and modify, to show that you can share easily

      • +
      • show !pip install to add dependencies/features

      • +
      +
    • +
    +
  • +
  • Room 6

    +
      +
    • Using GitHub without the command line

    • +
    • Learning Outcomes:

      +
        +
      • Be able to discuss changes before merging changes into the main repository.

      • +
      • Publish a personal repository page ( I think its called intro repository)

      • +
      • Share their script/notebook/code/small data on GitHub

      • +
      • Homepage using GitHub pages or the README that becomes the “index page” of the GitHub user account page

      • +
      +
    • +
    • Learner personas:

      +
        +
      • Check the Personas of the learners

        +
          +
        • Somebody who has seen/heard of GitHub but hasn’t used it yet

        • +
        • Someone using it for their own work but struggling with collaboration

        • +
        +
      • +
      +
    • +
    • Exercises:

      +
        +
      • Upload/share an example dataset or script

      • +
      • Review another collaborators pull request.

      • +
      • Take part in the discussion on a pull request.

      • +
      +
    • +
    +
  • +
  • Room 7 +Linux shell basics: why do we want to teach them? +(this took most of the time for the discussion)

    +
      +
    • Learning objectives:

      +
        +
      1. Filesystem: Directory (CLI) - Folder (GUI) analogy

      2. +
      3. Basic commands (which commands are basic? make a survey of shell histories and get the most common ones)

      4. +
      5. Basic constructs (e.g., for loops, pipes, while loops… which ones are basic? See above)

      6. +
      +
    • +
    +
  • +
+
+

Note from chat: Zoom timer: https://support.zoom.com/hc/en/article?id=zm_kb&sysparm_article=KB0068677

+
+
+
+
Episode 2: Lessons with version control
+

Materials: https://coderefinery.github.io/train-the-trainer/lessons-with-git/

+

Poll options: I want to hear about:

+
    +
  • A: Why use version control for teaching materials

  • +
  • B: Different template options

  • +
  • C: How CodeRefinery does it; CodeRefinerys lesson template

  • +
+

Poll vote (multi-select): add a o to your answer +- A: ooo +- B: oooooo +- C: oooooooo :ghost:

+

Question to audience: if someone wants to make a tiny fix to your material, how hard is it?

+
    +
  • If my material is only in pdf format which is not online, then it is hard.

  • +
  • I hope it is easy - my material is in GitHub. Nobody has ever done that though!

  • +
  • Slides: hard to find, easy to edit; Git repos somewhat easy, unless they have to be built locally or with an action; HackMD easiest to edit.

    +
      +
    • if you use something like google slides they are not that difficult to find

    • +
    • known permanent address. Google docs et al fail on that/same for many pads.

    • +
    +
  • +
  • For this material today - very easy! e.g. https://github.com/coderefinery/train-the-trainer/pull/128

  • +
  • Template with an edit button in the HTML pointing to the source-code in the repo.

  • +
+

Questions/Discussion topics

+
+

Upcoming CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/ +Please share with your networks, and let us know if you would like to co-teach a lesson (to support@coderefinery.org or in our Zulip chat)

+
+
    +
  • Changes to the material are sometimes not just tiny fixes. For example, one wants to present a slightly different selection of topics, but maybe some topics are “coupled” (perhaps naturally or perhaps just because of how they are presented), or change the general “theme” (e.g., life sciences vs theoretical physics) while keeping the actual topics the same. How could a lesson be developed to avoid having to do a huge rewrite?

    +
      +
    • You can try to modularize your material and keep non topic specific parts non themed. E.g. where you explain the functionality, don’t make reference to the example (not simple), so the example can be changed depending on the audience.

    • +
    +
  • +
  • What are the pros/cons of renaming a course / changing a repo name in GitHub?

    +
      +
    • It should be relatively unproblematic since GitHub will forward to the new name.

      +
        +
      • How long does Github keep the “old” name linked? Is there a max time it’s blocked, or changed as soon as a new one appears with the name?

        +
          +
        • in my experience it forwards “forever” until I create a new repo with the old name which will break the forward

        • +
        +
      • +
      +
    • +
    +
  • +
  • what should be in the readme for the git repo? (canonical address? contact points? license!)

    +
      +
    • https://coderefinery.github.io/mini-workshop/2/documentation/#often-a-readme-is-enough-checklist

      +
        +
      • I miss the url to the (main) repo in the readme

        +
          +
        • Do you mean the link to the rendered (lesson) page?

        • +
        +
      • +
      +
    • +
    • Link to rendered page: We often have this in the “about” section of the readme (see up right: https://github.com/coderefinery/train-the-trainer)

    • +
    • this gets lost in a fork, doesn’t it? so 20 folks forking and or reuploading the repo somewhere means the url gets lost?

      +
        +
      • True, but they might want to have their own version rendered?

        +
          +
        • yes, I have had issues finding and contributing to the “master” repo so all benefit. Else it gets cluttered. Both is valid

          +
            +
          • Good point though, the link to rendered page should probably also be included in the readme for completeness; ah and the link to the repository too, yes

            +
              +
            • so realistically we need a content folder and some more next to the readme as a best practice. sounds good!

            • +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • Is myst (markdown renderer) enabled by default in sphinx now?

    +
      +
    • to my knowledge no. we add the “myst_parser” extension to conf.py.

    • +
    +
  • +
+
+

Cicero: https://cicero.readthedocs.io/ +Sphinx documentation: https://www.sphinx-doc.org/en/master/ +Carpentries workbench for creating Carpentries lessons: https://carpentries.github.io/workbench/ +This is the testing lesson Richard showed: https://coderefinery.github.io/testing/ +And the corresponding repository: https://github.com/coderefinery/testing +You can lean back and watch, exercise coming in a bit :) +Richard will now edit our train the trainer material repository: https://github.com/coderefinery/train-the-trainer +The Sphinx extension for CodeRefinery lessons: https://github.com/coderefinery/sphinx-lesson +Empty lesson template to build your own lesson: https://github.com/coderefinery/sphinx-lesson-template

+
+

More questions

+
    +
  • Does the coderefinery.org page built on sphinx?

    +
      +
    • It’s built also from markdown but it uses https://www.getzola.org/ (which is more optimized to render websites, but we could do teaching also with Zola or create the project page using Sphinx)

    • +
    +
  • +
  • Is there a way to build and preview CR lessons without the command line?

    +
      +
    • The GitHub workflow we use creates HTML from all branches. This means that one can push a branch to GitHub, preview it there, and then open a pull request. One thing that would be nice but we don’t have yet is if a bot automatically posts the link to the preview to a pull request.

    • +
    +
  • +
  • For VCS-2, for the Carpentries Linux shell example, Lesson, Github repo, to me it seemed as though the Sandpaper setup they have makes a very nice interface, complicates the relationship between source and output. E.g on the soucre page https://github.com/swcarpentry/shell-novice/blob/main/index.md I could only see to ‘Prerequisits’ and not ‘Download files’ on the page https://swcarpentry.github.io/shell-novice/. Perhaps I have missed something?

    +
      +
    • I am sorry I don’t know the new Sandpaper setup well enough to answer this question.

    • +
    +
  • +
  • Do we have the instructions to build the lessons available somewhere to try out later?

    +
      +
    • https://github.com/coderefinery/sphinx-lesson

    • +
    +
  • +
+
+

Exercise VCS-1 (and VCS-2 (if time)) (https://coderefinery.github.io/train-the-trainer/lessons-with-git/#exercises) in breakoutrooms until xx:05

+

then short summary in main room and then break.

+

Use the notes below. Collect a list of lesson formats and discuss what you like about each of them.

+
+
    +
  • PDF slides by a presentation program

  • +
  • pdf slides with beamer in latex under source control.

  • +
  • Markdown slides via Github

  • +
  • CodeRefinery template

  • +
  • Carpentries template

  • +
  • Google Slides

  • +
  • git-book

  • +
  • Jupyter Book - allows creating a structured reference website using RST/Markdown, including Jupyter Notebooks to show result of running code

  • +
  • mdbook - create simple/minimal website using Markdown

  • +
  • Binder - allows learners to run their own live version of a github repository with Jupyter Notebooks, with only a web browser

  • +
  • Jupyter notebooks and jupyterhub platform

  • +
  • Jupyter + Nbviewer and custom css (read only) + Binder link (hands on)

  • +
  • RMarkdown

  • +
  • Quarto Slides

  • +
  • Reveal.js - write slides in HTML (also supports markdown)

    +
      +
    • Example: https://bl-presentations.erambler.co.uk/2024-02-21-idcc24/

    • +
    +
  • +
  • Remark.js - write slides in markdown

    +
      +
    • Example: https://bl-presentations.erambler.co.uk/2024-02-19-idcc-pids-workshop/

    • +
    +
  • +
+

Room discussions:

+
    +
  • Room 1

    +
      +
    • (https://smc-aau-cph.github.io/SPIS/README.html)

    • +
    • CodeRefinery template

    • +
    • Shared notes & blogs

    • +
    +
  • +
  • Room 2

    +
      +
    • demo the exercise

    • +
    +
  • +
  • Room 3

    +
      +
    • Mix of JupyterLab, Terminal within that, and traditional slides

    • +
    • Jupyter + RISE (benefit: slides that are editable and executable live)

    • +
    • Challenges

      +
        +
      • present code in an interactive way

      • +
      • handle lots of images/ figures without too much additional overhead when setting up the material

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • Material and tools depend on instructors

    • +
    • Some slide building tools

      +
        +
      • https://revealjs.com/

      • +
      • https://remarkjs.com/

      • +
      • https://github.com/rust-lang/mdBook

      • +
      +
    • +
    • Using flat git repos without fancy styling to make it easier to edit but still version controlled

    • +
    +
  • +
  • Room 5

    +
      +
    • Using R as a GIS: https://github.com/nickbearman/intro-r-spatial-analysis

      +
        +
      • Workbook: RMarkdown, Slides: Quarto

      • +
      • No continuous intergration

      • +
      +
    • +
    • Having a jupyter nbinder link to test the notebook

    • +
    • repo lives on codeberg in this example

    • +
    +
  • +
  • Room 7

    +
      +
    • Ex 1:

      +
        +
      • Sphinx, similar to CR

      • +
      • Sometimes pdfs generated with beamer package (or from pptx and odt), but blows up repository size if in version control

      • +
      +
    • +
    • Ex 2:

      +
        +
      • Content

        +
          +
        • CR: Content commonly found int the content folder

        • +
        • SC: Mostly under episodes

        • +
        +
      • +
      +
    • +
    • Question that came up:

      +
        +
      • is CR/Sphinx approach mostly for technical topics? What about language.

      • +
      • I guess by our nature it’s focused there. But probably could be used for others (I guess it it’s much easier to use git in a technical audience.)

      • +
      +
    • +
    +
  • +
+
+
+
Episode 3: How we collect feedback and measure impact
+

Materials: https://coderefinery.github.io/train-the-trainer/feedback-and-impact/

+

Questions to audience

+
    +
  • What tricks/techniques have you tried in your teaching or seen in someone else’s teaching that you think have been particularly effective in collecting feedback from learners?

    +
      +
    • preparing a survey and emailing it to participants as soon as the event ends (usually get <50% of answers but it’s a representative enough sample)

    • +
    • do engage with the audience, give them the time to get the courage to speak up

    • +
    • Be the audience yourself

      +
        +
      • yes! some problems/issues I don’t notice as instructor, only as listener

      • +
      +
    • +
    • Have time (e.g. 5 min) in the session to fill out the feedback form

    • +
    • If the course/workshop has several days/sections do a couple questions every change, then a full one afterwards

    • +
    • “Traffic light” feedback (e.g. for pacing or progress on exercises): give each learner two different coloured post-it notes for in-person, or use emoji for online, to indicate a current status

    • +
    +
  • +
  • Can you give tips or share your experiences about how to convert feedback into changes or actionable items?

    +
      +
    • ask questions about things you know you don’t know

    • +
    • “Don’t let the noise of others’ opinions drown out your own inner voice.” — Steve Jobs

    • +
    +
  • +
  • When people ask questions / get stuck with a specific step. Is there a typo I can change there and then in the workbook?

    +
      +
    • Being able to fix small things on the fly helps sometimes, otherwise open issues if working on github

    • +
    • If multiple people have the same question, then this is an indication that I should look at this in more detail

    • +
    +
  • +
  • How do you measure the impact of your teaching? Any tips or experiences about what you have tried or seen other courses do?

    +
      +
    • “How likely are you to recommend this workshop to others? (0/5)”

    • +
    • Check the ‘Garbage Out’ bin, what you find there will be what went across. The rest will be history…

    • +
    +
  • +
  • Anybody knows of good resources on survey design? Please link them here.

    +
      +
    • “Our job is to figure out what they’re going to want before they do… Our task is to read things that are not yet on the page.” - Steve Jobs

    • +
    +
  • +
+

Questions/Discussion points

+
    +
  • Feedback is necessary to design good lessons. Improvement can only be done iteratively. So the faster the iteration (design/teach), the better. But on the other hand, I cannot constantly bomb our community with training event emails. So I would like to try proposing a course many times a year, but I don’t want to spam everybody many times a year.

    +
      +
    • :+1:

    • +
    • With CR we also have a calendar that can be imported to different calendar applications, where we add all workshops: https://github.com/coderefinery/calendar/

    • +
    +
  • +
  • Does an even split of too fast / too slow mean speed is about right?!

    +
      +
    • I take it to mean “it’s roughly where it should be”. Would be better to accomdate the sides better though… (we do try to design for a broad audience: some easy stuff, some advanced stuff, so people can make their own path)

    • +
    • It could also indicate that the prerequisites/scope are not well defined :+1:

      +
        +
      • Based on long term surveys we also know though that even though the workshop might have been to fast, people appreciate having “heard things before and know where to find them later”

      • +
      +
    • +
    • perhaps the even split between too fast/too slow is ok only if the majority of votes goes for “just right” :+1:

    • +
    +
  • +
  • One of the most important disciplines in journalism is to challenge your working premises. (Bill Keller) This applies equally to learning as well.

    +
      +
    • Participants can be encouraged to write some posts on LinkedIn. If it is helpful some blurbs can be created for pre and post-workshop to generate more traction for Code Refinery and future participation.

    • +
    • Ask participants if they use Dev.to, hashnode etc to blog their work or use twitter etc to have a memory of their work.

    • +
    +
  • +
  • Do you have any suggestions for prerequisites? I try to make them clear, but occasionally people attend who clearly do not meet them. :+1:

    +
      +
    • I guess it depends how much it matters for the workshop itself. If you have group exercises etc, it probably matters? , lecture style maybe not so much?; important is that the participants themselves know that prerequisites exist and if they meet them

    • +
    • Sometimese people that do not meet the prerequisites join to get to “know what they don’t know”, find out where to find information on topics they might get interested in future etc

    • +
    • Other suggestions? Viewpoints? :)

    • +
    • Thank you - things for me to think about there :-)

    • +
    • With CR’s latest ideas, we try to make the prerequisites clear, but there is no capicity limit: it’s OK if people drop by and are less than prepared: it’s livestream, anyone can come. We try to have something for these people, too: learn what you are missing, why you might want to study more in the future.

    • +
    • Any thoughts on applying this to a more practical focused course, with a total capacity limit (i.e. not like CodeRefinery).

    • +
    +
  • +
  • Everytime you do a course on CodeRefinery, think of it as trying to bake a new cake with an old recipe with no idea about the individual taste preferences of the one you bake the cake for. Then, you will not experience too many surprises. Fine-tuning the recipe for one cohort still remains the ‘old recipe’ as far as the next ‘new cohort’ will be concerned. C’est la vie.

    +
      +
    • nice analogy!

    • +
    +
  • +
  • Question from chat: For examples 2 & 4, would you also consider using something like a Likert scale? E.g. Rate how well you agree with the statement “My code is more reusable as a result of attending a CodeRefinery workshop” (from 1 Strongly disagree to 5 Strongly agree)

    +
      +
    • Thanks! I am new to Likert scale and will read up on it. In my experience numbered answers can be useful for reporting. But I also like questions where we ask for what actually to change.

    • +
    +
  • +
  • Comment from chat: Richard, your point crowns the point of having CodeRefinery, With Radovan’s and Samantha’s acquiescence assured, I would like to suggest you wear a crown going forward, especially for the CodeRefinery session. Do we have a deal ?

    +
      +
    • I don’t quite understand this

    • +
    • I think it’s a tongue-in-cheek-comment (joke) but I am not sure…..

    • +
    +
  • +
  • What is the ideal way to allow people to interact while course is going on in the main online session, i.e. without a breakout room? Taking a pause or discussion in the background?

    +
      +
    • I’ve had some success with WhatsApp groups for a course - particually ones that run over 4 (or 2) sessions.

    • +
    • A quick survey/quiz

    • +
    • Question to the audience that we take time to answer but it helps to show the answers

    • +
    +
  • +
+
+
+
+
+
+

Wrapup

+
    +
  • Thank you for active participation :)

    +
      +
    • We’ll continue answering questions after the workshop and make the cleaned up (no names etc) available from the materials

    • +
    +
  • +
  • Next session Tuesday August 20, 9 CEST: Tools and techniques adopted in CodeRefinery workshops

    +
      +
    • we will talk about on-boarding, install help, roles, screensharing, sound, collaborative notes

    • +
    +
  • +
  • All workshop materials will stay available (after the full workshop also on Zenodo :tools:)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • If you want to co-teach with us in the upcoming (or next) CodeRefinery workshop (https://coderefinery.github.io/2024-09-10-workshop/); or just want to learn more about this opportunity: Send your name and e-mail address to support@coderefinery.org; we will contact you!

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • Lesson design approach

  • +
  • I liked the backwards lesson design, gives a name to a practice I’ve already been doing :+1: :+1:

  • +
  • Lessons from code refinery on lesson design. Learning about Sphinx.

  • +
  • Collaborative notes and anonymized archive of notes.

  • +
  • it’s nice to have a community to discuss these kinds of problems

  • +
  • Hearing the variety of tools people use for slides (PDF, Quarto, Beamer etc.)

  • +
  • Good intro of the tools, the jargon and the pedagogical philosophy of teaching tech.

  • +
  • The absolute openess in having everything publicly available - materials ofc but also questions, discussions, feedback, …

  • +
  • Thinking about all content being available publicly and as a git repo

  • +
  • Thanks for explaining the HedgeDoc interface, with view and edit options

    +
      +
    • Is there anyway to come back to this document later (e.g. tomorrow) and see what has changed since now? So I can see if any other questions have been asked/answered?

      +
        +
      • There is a “revision” point under “Menu” up right, which shows you different versions of this document

      • +
      +
    • +
    +
  • +
  • Modesty: the gentle art of enhancing your charm by pretending not to be aware of it. - Oliver Herford

  • +
  • +
+

What one thing would you improve about this session?

+
    +
  • Perhaps some more interactivity but can be hard to plan and time

    +
      +
    • We’ll see what we can do.

    • +
    +
  • +
  • Maybe mix the breakout groups up for each breakout session (although there are advantages to consistency too) :+1:

    +
      +
    • yes, pros and cons! For me, having consistency worked well this time.

    • +
    • Likely we will have different participants next week, and a bit of mixing will happen naturally.

    • +
    +
  • +
  • The pace of the presentations could be a little tighter (the pace is good for a discussion though)

  • +
  • Richard’s voice was only 80% audible

    +
      +
    • Sorry to hear that. It seemed fine on my end. Will check better for next session.

    • +
    +
  • +
  • Hands on simulation and collaborative notes

  • +
  • I found it difficult to follow the presentation and the collaborative notes at the same time

    +
      +
    • We will highlight the collaborative notes more in the next session. Our strategy usually is to say to focus on the “teaching part” and use the notes only when needed. Since you can go back and also check the notes later.

      +
        +
      • My problem is that I want to follow both since I don’t want to miss out on anything. As such, I have both windows (zoom and the notes) open side-by-side. Since there is near-constant real-time typing in the editor, and as such visible movement on screen, I get constantly distracted. This makes following the event quite exhausting.

      • +
      +
    • +
    +
  • +
  • Heads up to participants on using the break out rooms on voice interaction and screen sharing.

    +
      +
    • Do you mean that we should have mentioned it more clearly in the pre workshop email?

    • +
    +
  • +
  • I found it hard to follow with so many things going on at once…

    +
      +
    • A collaborative document being changed at the same time as…

    • +
    • Someone speaking and explaining content at the same time as…

    • +
    • Chat in a different application at the same time as…

    • +
    • Content changing in a termin application.

      +
        +
      • Thank you for the feedback. We will remove the Zoom chat out for the next session and explain the use of the collaborative notes more.

      • +
      +
    • +
    +
  • +
  • Make more use of defining and then making sure the learning objectives are met

    +
      +
    • True we did not talk about them much, will pick that up better for next session.

    • +
    +
  • +
  • UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. - Dennis Ritchie. You need to do a lot to prove that to be wrong, simply put.

  • +
  • Allocate some time for learners to type in the answers so that we don’t have to listen and type at the same time.

  • +
+

Any other comments?

+
    +
  • It’s great to hear other people’s experience

    +
      +
    • Good to hear :)

    • +
    +
  • +
  • Looking to meet you onsite if there are any events and get more emails from you :)

    +
      +
    • We will keep you informed :)

    • +
    +
  • +
  • Thanks for putting this together, I got a lot of inspiration for my own courses

    +
      +
    • Good to hear :)

    • +
    +
  • +
  • I didn’t know where to ask questions. It would work best for me to do it in zoom chat as that’s the application that I’m watching in..

    +
      +
    • Sorry for that, just to figure out why: Did you join a bit late?

      +
        +
      • No. Perhaps I just missed that or it was too quick for me or something?

        +
          +
        • Ok, sorry. Will try to make this more clear in next session.

        • +
        +
      • +
      • Perhaps also because there were so many things going on and jumping around. For me, the zoom chat is the constant (and obvious) place to ask questions while watching a shared screen, trying to find the right place in a moving collaborative document is difficult. It tears my attention into too many pieces. :+1:

      • +
      +
    • +
    +
  • +
  • Had a lot of content that assumed extant knowledge that I didn’t have. This wasn’t in the pre-requisites.

    +
      +
    • Do you have examples?

      +
        +
      • Yes! The code refinery templates and even just the way of doing that. I was expecting more on “when designing a lesson you should think about these steps” rather than this is how we do it and this is our tool for doing it. I guess I should have read the pre-workshop content better?

      • +
      • Ok, thank you for your feedback. You are right that we actually had some content that for sure would have been easier to follow for people with background knowledge about a certain topic.

      • +
      • “If you are in CodeRefinery TTT, you probably know what version control is and why it is important.” - extant knowledge, why not just add a sentence or two?

        +
          +
        • Please can you update in preparation for the next workshops so that I can decide whether or not they will be right for me?

          +
            +
          • Yes, we will think more thoroughly about this and send the info in the next email going out Wed/Thu

            +
              +
            • Thank you!

            • +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • Lots of the content was relevant to code refinery but not the wider topic (e.g. it was how to design a code refinery lesson and not how to design a lesson as stated in the session title)

    +
      +
    • We thought of the content of showing one way of doing things, ie “what we have learned”, if you have suggestions on how we could make that more clear on the event page, please let us know :)

      +
        +
      • “in a code refinery lesson” in the lesson/workshop description?

      • +
      +
    • +
    +
  • +
  • When you have pre-written “thank you for your active participation” it feels fake!

    +
      +
    • He, that is true, did not think about that. Thank you for the feedback. I would not have added it if Radovan and Richard would not have provided good feedback from circling the rooms.

    • +
    +
  • +
  • I found it vague and disorganised and difficult to follow. It felt like the instructors were presenting the content for the first time and didn’t know what to do next.

    +
      +
    • Thank you for your feedback. This is not the first time we have this training, but it is the first time in this constellation/way. The way of teaching may also sometimes make it seem new to instructors.

    • +
    +
  • +
  • I really liked the active exchange with other participants, but I also would have enjoyed a bit more technical content in the presentations. In a sense it felt less like a ‘training’ and more like a get-together :+1:.

    +
      +
    • Thank you for your feedback. We thought the name “workshop” would combine the training and exchange nature of this event. But maybe it didn’t do so enough? Do you have suggestions on how to clarify it on the event page?

      +
        +
      • Well, the ‘train the trainer’ title created the anticipation of being trained ;) don’t get me wrong, I liked the exchange, but I felt that the training aspect fell a little short. imho the workshop would benefit from a little more (instructional) content that is presented in a more structured way by the instructors (as opposed to ‘crowd-sourced knowledge’ that is collated in a loose collection of questions, notes and links)

      • +
      • Other than that, you could add another section on the main page, sth like ‘Workshop structure: we aim for a mix of modular presentations and work in small groups. The latter will be done in breakout rooms - be prepared to switch on your camera and have a fruitful exchange with fellow participants!’

        +
          +
        • Thank you for the suggestions, will add something like this :tools:

          +
            +
          • +

            Added : https://github.com/coderefinery/train-the-trainer/commit/03308595436e636b3bb37ed9d1f0dee39eeccd0f

            +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • My understanding (so far) of what (unlike the competition) CodeRefinery DOES NOT seek to exemplify - +https://images.ctfassets.net/rxqefefl3t5b/2k45BFtw4sBMlBfjr1OZ90/5c6ecd3628a43b0cdc79815f665e224a/Screenshot_2023-05-02_at_09.35.23.png?fl=progressive&q=80

  • +
  • My understanding of what (unlike the competition) today’s session of CodeRefinery DID exemplify - Definition of ‘Workshop’ from the Oxford dictionary of the English language “a period of discussion and practical work on a particular subject, in which a group of people share their knowledge and experience”

  • +
  • In my experience, even for the most seasoned Programmer coding, by its very nature, is nothing trivial, this being a simple straightforward fact just like there is no such thing as an egg which is a cube. I mean there is a reason why not just about everybody is a poet either. But, other minds have pointed this out without having to first explain why the universe is what it is in a way that could be understood without effort … https://i.pinimg.com/originals/7b/7e/c4/7b7ec4b91d2cf9d8e1b064678d205467.jpg

  • +
  • The inclusive environment feels very welcoming. Keep up the good work!

  • +
+

Thank you all for your feedback! Highly appreciated!

+
+
+
+

Day 2 : Session 2 (20.08.24)- Tools and techniques adopted in CodeRefinery workshops

+
+

:calendar: Schedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 9.25

About CodeRefinery workshops

10.15 - 10.25

8.15 - 8.25

9.25 - 9.55

Collaborative notes and interaction

10.25 - 10.55

8.25 - 8.55

9.55 - 10.10

Break

10.55 - 11.10

8.55 - 9.10

10.10 - 10.45

Workshop overview, roles, onboarding

11.10 - 11.45

9.10 - 9.45

10.45 - 11.05

Sound

11.45 - 12.05

9.45 - 10.05

11.05 - 11.20

Break

12.05 - 12.20

10.05 - 10.20

11.20 - 11.50

How to prepare a quality screen-share

12.20 - 12.50

10.20 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+

:icecream: Icebreaker

+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :-)

  • +
  • https://media.istockphoto.com/id/148421550/vector/bored-emoticon.jpg?s=612x612&w=0&k=20&c=uo5KBTqdJZbBQb_Xldhzuovx5t08fHfGR7dw7TCk90I=

  • +
  • :saluting_face:

  • +
  • :sleepy:

  • +
  • :coffee:

  • +
  • :umbrella:

  • +
  • :cocktail: :coffee:

  • +
  • :seedling:

  • +
  • :tired_face:

  • +
  • :sun_with_face:

  • +
  • 🥴 (:woozy_face: not converted?)

  • +
  • :coffee:

  • +
  • :sunflower: :book:

  • +
  • :satisfied:

  • +
  • :coffee:

  • +
  • :coffee:

  • +
  • 🥱:tired_face:

  • +
  • :bread: - I am baking bread today so I have been kneading dough while listening!

  • +
+
+
+
Introduction in breakoutrooms
+

Name / Affiliation / Location

+
+
+
Teaching
+
    +
  • Do you teach and organize teaching alone or with others? What would you prefer and why?

    +
      +
    • Coming together is a beginning; keeping together is progress; working together is success. – Edward Everett Hale

    • +
    • These days always with others. Alone is easier to prepare but almost always is harder during it.

    • +
    • Teaching with very diverse partners, it can be challenging to find a common language with people very different than you.

    • +
    • I teach alone, in the future there will be more collaboration with multiple team members. Both approaches have their pros and cons.

    • +
    • Both has its own distinct advantages

    • +
    • Most of my teaching is on my own, as a freelancer its more expensive to work with colleagues than to deliever a course on my own.

    • +
    • Teaching together, learns from each other, feedbacks to improve

    • +
    • Not formally taught yet, only given presentations actually .

    • +
    • collective teaching would benefit the teachers with collaborative curriculumn and experiences sharing.

    • +
    +
  • +
  • If applicable, have you seen any challenges when teaching together and how to overcome them?

    +
      +
    • It actually requires preparation,

    • +
    • Is it about teaching or about inspiring ? Discover the answer and get inspired …

    • +
    • It’s like being in a band: you might be great at improvising and your band-partners might be great at improvising too, but a bit of rehearsing makes even the impro gig much better

    • +
    • Need to plan before session, difficult if people don’t ‘plan’ in the same way, e.g. with the same time frame.

    • +
    • Heterogeneity in learners make it impossible to get the same result from everyone.

      +
        +
      • In fact, the same applies to teachers :D

      • +
      +
    • +
    • Teaching together requires to have similar opinions on how to teach. I share vews only with ~40% of my colleagues I think.

    • +
    +
  • +
  • No Teaching experience but it is good to give the outline of the lessons beforehand and learning goals.

  • +
+
+
+
+
+

:question: Questions

+
+
General / Practicalities
+
    +
  • What is this document for?

    +
      +
    • Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts)

    • +
    +
  • +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms?

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    • BR 1 : The Zoom chat does not work for the breakout room so we should take note of that. No webcam/mic = expect silence.

      +
        +
      • Thanks for notifying! This was not intended. Turned the chat back on.

      • +
      +
    • +
    +
  • +
+
+
+
+
+

Episode 1: CodeRefinery

+

Materials: https://coderefinery.github.io/train-the-trainer/coderefinery-intro/

+
    +
  • (questions continue here)

  • +
  • Is there the plan to build capacity / be paid to deliever courses?

    +
      +
    • We’ve discussed it but right now we don’t have many people who could accept money to do this (and maybe shouldn’t, because of their jobs). But, we would encourage others to use our materials as “independents” to deliver paid courses

    • +
    • One idea we have had is that paid courses could be delivered through the DRA (link below), who we know. Basically, DRA could find instructors and handle the money transfers (If someone wanted a paid course, we could help find someone to do it through DRA or independently)

    • +
    • :smile:

    • +
    +
  • +
  • Have you come across DRA, https://digital-research.academy/, Heidi Seibold, Joyce Kao who are doing similar work? I can connect you if you like.

    +
      +
    • Yes we have been discussing about possible future collaborations and are already sending possible clients their way (we, as a project cannot take money) :+1:

      +
        +
      • Excellent! :-D :smile:

      • +
      +
    • +
    +
  • +
  • .

  • +
+
+
+

Episode 2: Collaborative Notes

+

Materials: https://coderefinery.github.io/train-the-trainer/collaborative-notes/

+
    +
  • So anyone can type anonymously?

    +
      +
    • Yes, as long as you do not log in, you are Guest XXX

    • +
    • And at least in our hedgedoc case you cannot log in so you will always be anonymous. You can do [name=xxx], to add your name to a comment

    • +
    +
  • +
  • Test of +1

    +
      +
    • +1 :+1: :+1:

    • +
    • :-1: a test

    • +
    +
  • +
  • You are hosting your own version of HedgeDoc, and Hackmd.io is a similar (free) option. What are the limitations of the free hackmd.io? Should each center install their own HedgeDoc instance?

    +
      +
    • It seems the free version of HackMD has gotten worse lately. It works still well enough with a few people editing at the same time.

    • +
    +
  • +
  • Have there every been problems with the anonymity and CoC?

    +
      +
    • We haven’t had any issues so far.

    • +
    • With a different anonymous tool in a bachelor course, we had issues with anonymous participants (participants were posting slurs and unsafe links). The course organiser decided to stop allowing anonymous tools.

    • +
    +
  • +
  • Why not google documents?

    +
      +
    • Google documents are actually setting a hard limit for simultaneous writing, no more than 100 concucurrent editors. I am unsure if microsoft onedrive word documents would allow more users writing at the same time.

    • +
    +
  • +
  • What’s the most people you have every had on HackMD / Hedgedoc?

    +
      +
    • I believe about 200 active participants?

    • +
    +
  • +
  • What are your thoughts on using the build-in Zoom Q&A?

    +
      +
    • We haven’t tried this, in part because the way we do streaming now (you’ll see in session 4), participants aren’t in Zoom so don’t have access to that. The doc-format works pretty well though, when we keep it in this limited “write at end” format.

    • +
    +
  • +
  • How do you see what has changed? e.g. if leave the session at the end, can I come back tomorrow and see X has been added? e.g. a diff for this maybe?

    +
      +
    • In the menu up right there is revision, it does show the document and changes at different time step :+1: Thanks!

    • +
    • We recommend people only write at the bottom (and since we answer things live), so as a first level approximation you find where you were and read below that. Think of it more like chat than a full document. (Yes, we do revise questions at the end)

    • +
    +
  • +
  • How about flinga boards or similar tools?

    +
      +
    • My take is that the simplicity of a simple text document wins over free-form in-person-workshop-like tools.

    • +
    • There’s miro, can be a bit confusing though

    • +
    +
  • +
  • How does this work with small groups, e.g. 10-15 people?

    +
      +
    • Good question: it can be hard if people aren’t rigorous about it, people start only using chat/voice. So there seems to be some lower bound in size but we haven’t tested this much

    • +
    • And if the instructors never screenshare it to show what goes on it, then seems to be less used.

    • +
    • And if there aren’t other people to read/answer it during the session (perhaps less likely in a small course), it seems to be less used.

    • +
    +
  • +
+
+

Breakoutrooms until xx:55

+

Exercise/discussion: https://coderefinery.github.io/train-the-trainer/collaborative-notes/#exercise

+
+
    +
  • Breakout room 1:

    +
      +
    • Use of etherpad for collaborative discussion.

    • +
    • Use of slido for polling and quizzing.

    • +
    • Presemo as a slido alternative (https://www.aalto.fi/en/services/presemo-a-fully-web-based-classroom-participation-system)

    • +
    • Use of text based approach for questions rather than live can be helpful if there is a language barrier issue.

    • +
    +
      +
    • A good teaching session which had many questions coming spontaneously to the teacher is a non-entity of sorts. If the overall flow of feedback / questions increases it could indicate that the session will not prove to be a helpful experience. A signal that generates noise is, well, noise, if calling a spade a spade signals anything. Note that the ‘overall’ bit and the ‘to the teacher’ aspect are important. Both the best and the worst teaching session have two things in common: a teacher, and the fact that NO Materials of any kind are used, ie speech is the only channel of communication via a common language. The only difference is that it is not the same teacher, at least not in the same session at the same time.

    • +
    +

    Another less mentioned, but perhaps more relevant indicator of a great session is the simple fact that at the end of the session EVERYONE feels empowered, NOT tired. This is not an easy to quantify thing, but screams out the quality of the experience loud. More often then not, such sessions differ little from each other, apart from in terms of the theme / topic and the participant mix. It ends up being the ‘keep your cake and eat it too,’ of sorts, not quite the far less amusing post-bombardment devastation scenario in the wake of a take it or leave it go at anything.

    +
      +
    • profanity in collaborative documents where people can add content anonymously could be a problem (happens very rarely, fortunately and somewhat surprisingly)

    • +
    +
  • +
  • Breakout Room 2:

    +
      +
    • Good experiences with Zoom polls

    • +
    • Handling questions in hybrid setups: all participants (on-site and online) ask questions in written form

    • +
    • Collaborative notes can be challenging when conducting a course alone (without teaching assistants) :+1:

    • +
    • Providing a method to ask questions anonymously can make asking easier for shy participants

    • +
    • Questions can give valuable feedback on how the course is going

    • +
    • Online collaborative whiteboarding platforms such as Miro

      +
        +
      • Large monitors are useful for this not to have to drag a “periscope” around

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • good experience with whatsapp chat for questions. since most learners have the app already and one thing less to install and set up

      +
        +
      • reply to question is a way to handle multiple questions at the same time but it works well for smaller groups

      • +
      +
    • +
    • experience with collaborative docs in in-person workshops: voice questions might “win” over the document

    • +
    • “seeding” questions may help to not have an empty document

    • +
    • it can help somebody to start and create a structure which helps others to see and follow

    • +
    • we discussed the Carpentries sticky notes system (red sticky note: signal tech issues and use for feedback, green sticky note: signal that exercise worked and for positive feedback)

      +
        +
      • Nice summary of sticky notes system: https://teachtogether.tech/en/#s:classroom-sticky-notes :+1:

      • +
      +
    • +
    • What is the success rate of in-person workshops after COVID? Discussion: Teachers prefer in person and learners prefer remote or recorded to spool back and relearn.

    • +
    +
  • +
  • Room 5

    +
      +
    • Good experience with Collaborative tools as HackMD and HedgeDoc while teaching with no bad feedback

      +
        +
      • When used with smaller groups works best as one-way, like sharing links with students and so on

      • +
      • Needs to be done as a team, quite difficult if teaching alone

      • +
      • Most useful when online/hybrid

      • +
      +
    • +
    • Anonymisity is important for transparent feedback and no biasis in classrooms

    • +
    • Not very collaborative but useful to share history or jupyter notebooks live https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush

    • +
    • Used Flinga before that seems like Figma and also onsite teaching using sticky notes

      +
        +
      • There’s miro.com but can be a bit confusing, more for brainstorming than for teaching

      • +
      +
    • +
    • Using quizzes apps like Kahoot is beneficial while teaching to have more engaging students

    • +
    • +
    +
  • +
  • Room 6

    +
      +
    • teaching teenagers (in presence) but using shared pad becomes quickly very chaotic, so only usable for short moments when answering very precise questions

      +
        +
      • Yeah, I can imagine. For CR we try to keep it in this very limited format (all questions bullet points, only add to the end) and I think that helps.

      • +
      +
    • +
    • using shared notepad for small workshop (5-10 people) to explore common thematic (mainly technical) to keep a shared notes and condense aftwerward (and publish on wiki to archive)

    • +
    • Difference between teaching in person and online. Some people prefer in-person and sometimes you have no option but to organise it online.

    • +
    • There are sometimes cultural differences and learners feel shy to ask / question the knowledge of the Teacher, so shared notes are a good way to safely ask questions.

    • +
    +
  • +
+

Questions continue:

+
    +
  • Have we demonstrated how we do polls in HedgeDoc? Add your vote by adding an o

    +
      +
    • yes: oooo (in session 1)

    • +
    • no:

    • +
    • :smile:

    • +
    • not sure: o

    • +
    +
  • +
+
+
+

Episode 3: One workshop, many perspectives

+

Materials: https://coderefinery.github.io/train-the-trainer/overview/ +Next CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/

+
+

Exercise until xx:39

+

https://coderefinery.github.io/train-the-trainer/overview/#discussion

+
+
    +
  • Room 1

    +
      +
    • Send pre-workshop email with pre-requisite instructions on what should be set-up beforehand.

      +
        +
      • But, also mention that if help is needed for set-up, we will be ready before the session officially starts.

      • +
      +
    • +
    • Discussion on whether we push to work in a pre-ready environment (e.g. Binder, Colab) or in their own environment.

    • +
    • Lots of help needed both before and after.

    • +
    • Installations: as much as we can provide ready made environments for the learners, maybe installations will be something that the learners will face sooner or later. Maybe one should teach more about installations?

    • +
    • My only cherished role in a teaching-learning session is the that of one who is living the moment as if there were no tomorrow. What cuts all ways really is that “By failing to prepare, you are preparing to fail.” ― Benjamin Franklin. A helpful motto: “When one teaches, two learn.” — Robert Heinlein. The best experience cannot be given, it can only be allowed to flow its way, so get out of its way.

    • +
    +
  • +
  • Room 2

    +
      +
    • Frequently, a single person fills all the roles for a single or multi-day workshop

    • +
    • Collaboration with different centers/ universities can be challenging

    • +
    • Preparing participants: it’s essential for the instructor to go through the demos and be sure that they will work (no unpleasant surprises live). This can be extended to advance-prep for participants.

    • +
    • Best experience is to hear (live or in feedback notes) some positive things directed at you :)

    • +
    • Fully prepared environments (eg self-hosted JupyterHub) can make preparation for participants easy

    • +
    +
  • +
  • Room 3

    +
      +
    • Some students have problems with setuping the environment. Maybe having a step by step instructions could help. But some students don’t want to “start” the course before hand.

    • +
    • Preparing the environemnt before hand ensures everyone is onboard from day 1. The same thing happend in CSC training sessions and another session Peng attended.

    • +
    • Had experience in attending as teacher and student in previous workshops

    • +
    +
  • +
  • Room 4

    +
      +
    • knowing the background of the audience is helpful

      +
        +
      • Try and ask in advance of the background of the audience. Do a poll at the start of the workshop. In person one can do it interactive.

      • +
      +
    • +
    • among co-instructors: discuss topics and flow

    • +
    • if more people are involved, it can help changing roles from time to time to see different perspectives

    • +
    • preparation is key

    • +
    • Circulate instructions beforehand

      +
        +
      • Do a poll before session: Have you installed (QGIS) successfully?

      • +
      • Push hard to do this in the welcome email

      • +
      +
    • +
    • communicate clearly to the participants

    • +
    • +
    +
  • +
  • Room 5

    +
      +
    • We’ve all taken most roles

    • +
    • How to prepare in advance?

      +
        +
      • Meet and discuss once or twice

      • +
      • Make a pre-survey to check for interest and background

      • +
      • Going through the materials

      • +
      • Checking the toolkit (zoom)

      • +
      • Agree on the reponsibilities and back-up plans (bit of scenarios planning)

      • +
      +
    • +
    • How to prepare trainings in advance?

      +
        +
      • Collect resources and prepare the workshop plan

      • +
      • Having the material readily available online ans sharing it

      • +
      • Making a pre-survey

      • +
      +
    • +
    • What was the best workshop experience for you as learner, helper or instructor? What made it great?

      +
        +
      • learner

        +
          +
        • Engaging and practical workshop with more exercices and follow-up theoretical part explanations

        • +
        +
      • +
      • helper

        +
          +
        • When the instructor is well prepared and as helper ther’s only typos to fix and interesting questions to answer

        • +
        • Assist the instructor, coordinate the collaborative notes, and make sure that the time is respected

        • +
        +
      • +
      • instructor

        +
          +
        • I have a colleague whom I’ve ran the same workshop a few times already, goes quite smoothly now and we’ve made a few changes. Hard to reach that point with new colleagues but getting there

        • +
        • Students/participants were engaging with the material and many good feedback collected even some of them asked for the next workshop

        • +
        +
      • +
      +
    • +
    +
  • +
  • Room 6

    +
      +
    • What has made a great experience for you as a learner/helper/instructor?

    • +
    • Common ground between learners & teachers

      +
    • +
    • Motivation

      +
        +
      • Teaching is much more enjoyable when the learners want to be there

      • +
      • I spend a lot of time at the start of a workshop making sure learners feel that the content is possible for them to understand and master

      • +
      +
    • +
    +
  • +
+

Poll: I have joined a CodeRefinery workshop before: (add an o for your answer)

+
    +
  • yes (within last 2 years): ooooooo

  • +
  • yes (longer time ago): oo

  • +
  • no: oooooooo

  • +
  • +
+

(questions would continue below:)

+
    +
  • What is the motivation / advantages of streaming workshop versus using zoom?

    +
      +
    • We’ll cover this more in week 4, but roughly: zoom became unmanageable and essentially quiet once things got big. Streaming allowed “one to many” communication with no limit, and collab notes allowed better interaction anyway. By separating the rooms, it was more pleasant to teach. Videos could be released immediately since there was no risk of privacy of participants. There could still be in-person/online small groups who have “watching parties.”

    • +
    +
  • +
  • What are the blue red and green font colors here, does it symbolify anything or just a convention HedgeDoc uses?

    +
      +
    • Visual separation of formatting, mostly. (It helps to quickly realize you’ve missed/ mistyped a control Markdown symbol etc.)

    • +
    • Yeah, it’s bascically “code highlighting” for markdown. No special meaning but quite convenient for us.

    • +
    +
  • +
  • Is this next workshop only for team leads or also open for helpers and coordinators?

    +
      +
    • You mean the next session of this workshop or the upcoming “CodeRefinery workshop”(this one: https://coderefinery.github.io/2024-09-10-workshop/)?

      +
        +
      • The upcoming workshop coordinators are alredy working, but can be joined if you are interested

      • +
      • As helper roles we currently only have “collaborative notes helper”, which is all about helping to answer questions in the collaborative notes

      • +
      • We do have some co-teaching slots open :)

      • +
      • If interested: join the discussion in our chat: https://coderefinery.zulipchat.com/#narrow/stream/316508-coderefinery-tools-workshop/topic/Fall.202024.20CodeRefinery.20workshop

      • +
      +
    • +
    +
  • +
  • Can a person have multiple roles in a workshop as a helper and a teacher?

    +
      +
    • Yes, many teachers also contribute to the rest of the workshop by answering questions in collaborative notes. :+1:

    • +
    • Some teachers also host a local classroom in week one and do their teaching in week two of the workshop

    • +
    • Roles that do not go well together are broadcaster/director/host and instructor (goes well until there is a problem; co-teaching solves that partly)

    • +
    +
  • +
+
+
+

Episode 4: Sound

+

https://coderefinery.github.io/train-the-trainer/sound/

+
    +
  • To me, Richard is a bit quieter than the other two :+1: :+1: :+1:

    +
      +
    • to elaborate: I think that the audio coming from him is missing some mids

    • +
    • Do you have any links about this kind of evaluation and adjustment?

    • +
    +
  • +
  • Do you suggest / recommend a specific headset(s) with mounted microphone?

    +
      +
    • in our experience headsets with a microphone will almost always be better than a separate microphone sitting on the desk or in the monitor

    • +
    • +
    +
  • +
  • Speakers have different tones of voice and speaking styles, is there a recommendation or experience from CR workshops for how this is adjusted and catered to environemnts for listeners?

    +
      +
    • Yeah, people’s voices are different and we haven’t gone as far as voice training or improving.

    • +
    +
  • +
  • How to change the volume for speakers? Tried Zoom settings and system settings and didn’t help.

    +
      +
    • From linux I can use different pulsemixers pavucontrol, pulsemixer to set the gain to above 100%. I’m not sure the equivalent on other OSs but

    • +
    +
  • +
+
+
+

Exercise until xx:10 +https://coderefinery.github.io/train-the-trainer/sound/#exercises

+
+
    +
  • room 1

    +
      +
    • Practically, no typical headset is designed or can capture the technical purity of human voice within its natural environment. But one needs to understand the polar pattern of the (specific) microphone or how much of the signal will be picked up by the microphone from different directions, a sine qua non when it comes to mitigating unwanted sound sources to bleed into the signal.

    • +
    +
  • +
+

For best results, keep the right direction & distance to your (directional) mic. Usually, that’s between 15-30 cm to get get a natural sound. A microphone records everything it can, also silence, so check the headphone output BEFORE adjusting the gain, in some specific cases aim for a dry sound, ie the influence of the room or how audible the room is on the recording ! Finally, adjust the mix between dry and room sound, or change the frequency response in tandem using a compressor to reduce the dynamic range of a signal for a more consistent listening experience = the quietest parts of your signal will appear louder by reducing the loudest parts.

+

It is all about one thing and one thing only - love your voice, let people fall in love with the acoustic quality of your charm. So remember: GIGO, it matters!

+
    +
  • Room 3

    +
      +
    • Had different headsets and we could see the difference (bluetooth low quality)

    • +
    • How to change the volume?

      +
        +
      • It’s surprisingly hard to get more control than the basic slider you see in the apps! You need to look.

      • +
      +
    • +
    +
  • +
  • room 4

    +
      +
    • headset is probably better listening experience but they can be uncomfortable to wear during long meeting days :+1:

      +
        +
      • Yeah. Luckily only instructors

      • +
      • Therefore breaks are non-negotiable

      • +
      +
    • +
    • loud keyboard can be an issue

    • +
    • if one has a silent room that does not echo, it can be ok to teach without headset

    • +
    • on Linux I am using pulsemixer to adjust levels and pavucontrol to change outputs/sources

    • +
    • mic modes on mac

    • +
    • check default microphone for zoom.

    • +
    +
  • +
  • room 5

    +
      +
    • Most tricks help tuning yourself but hard to do it as a group. Perhaps doing a short recording.

      +
        +
      • Yeah. Some independent recording/playing aronud, but also asking for advice. I would do small group/one-on-one things.

      • +
      +
    • +
    • Background noises cancellation tools or wise choice of quiet environments

    • +
    • Audio check with colleagues or through the app with the audience saying numbers for example

    • +
    • Zoom or Teams have sound checks but work different in the app than the browser. They also work different across Operating systems

    • +
    • Some sound issues might be related to network speed or stability, also to RAM available. Worthwhile to try and control those as well

    • +
    • Make it welcoming for the audience to give you feedback on the audio and other settings, give reminders

    • +
    +
  • +
+
+
+

Episode 5: How to prepare a quality screen-share

+

Materials: https://coderefinery.github.io/train-the-trainer/screenshare/

+
    +
  • If your Zoom does not support “share portion of screen”, sharing a tab and resizing it to portrait for yourself is a possible workaround (this at least works when joining the call from Chromium browser)

    +
      +
    • Another workaround is to use an editor/IDE that displays multiple panels in one window and can show a web page, code files and terminal session +10

    • +
    +
  • +
  • Is ‘share a portion of your screen’ where you draw a box in Zoom to share a section?

    +
      +
    • yes :+1:

    • +
    +
  • +
  • When using zsh, one can run something like this in a terminal

    +
    tail -n $NLASTCOMMANDS -f ~/.zsh_history | sed 's/^.............../LAST COMMAND:/g'
    +
    +
    +

    (I place this in a window under the main terminal, I use i3)

    +
  • +
  • I am a bit confused on what platform you are putting this code?

    +
      +
    • Radovan is using Linux with (I think) the “i3 window manager”. It can be quite involved and there is lots of personal customization here.

    • +
    +
  • +
  • When teaching with a custom prompt, is it worth starting with the default (that your learners will see) and explicitly mentioning “I change these things to make it clearer when teaching”

    +
      +
    • One should always comment on what may be different. Thing is “default” may look different for many people :+1:

    • +
    • “I am not going to teach you how to customise your prompt, but here’s an online tutorial, be prepared to lose several days of your life…” :laughing:

    • +
    +
  • +
  • Now I can’t see the last line in the terminal

    +
      +
    • Yep, that’s a problem. It can be good to keep a buffer on the bottom of the screen.

    • +
    • If you move your mouse outside the Zoom window, the controls should go away. But still a good note.

      +
        +
      • My mouse was on another screen.

      • +
      • Ok, thanks.

      • +
      +
    • +
    • I think one can also make the zoom bars not auto-hide (then it won’t display under), but that is annoying also since it wastes space.

    • +
    +
  • +
  • Does anybody still use shellshare? Does it work?

    +
      +
    • We in CR haven’t used it much but we have seen it.

    • +
    +
  • +
  • Does the stacking of the screens work on windows?

    +
      +
    • Don’t know unfortunately

    • +
    +
  • +
+
+

Exercises (done together) +https://coderefinery.github.io/train-the-trainer/screenshare/#exercises

+

Write your cool tips and ideas below. +Stay after xx:00, to

+
+
    +
  • To be safe, I have created on my computer an account that I use only for teaching, so I do not need to do any manual set up

  • +
  • share history or jupyter notebooks live (5-10 secs refresh rate) into a git repo. Share the link with the learners so they can catch up https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush

  • +
+
+
+
+
+

Wrapup

+
    +
  • Next session Tuesday August 27 9 CEST: About teaching & cool things we all would like to share

  • +
  • All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • Cool gems session: If you want to share something, please edit your registration and fill it in there (link to modify in registration confirmation); or e-mail to support@coderefinery.org

  • +
  • If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14:00 (Europe/Stockholm time)

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • Sound and screen share optimization as well as relevant tools and good practices for online instruction. “While you may be unable to control your users’ mindset, you can anticipate it, and make sure that your user experience caters to it.” - Jonathan Cherki

  • +
  • Nice opportunity to (re)think about my online teaching setup :+1: :+1: :+1:

  • +
  • Other ways to display command history :+1:

  • +
  • Did not know that bluetooth gear had so much latency! :+1:

  • +
  • A good reminder about headsets with microphones

  • +
  • Nice and friendly teaching. Thank you!

  • +
  • Screen share with command history and terminal customisation

  • +
  • Really useful tips on sound and screen sharing :+1:

  • +
  • Nice experience share

  • +
  • very useful and practical tips!

  • +
  • Easy to follow along and filled with useful tips on sound, video etc.

  • +
  • +
+

What one thing would you improve about this session?

+
    +
  • Just digging to find something: I have read some of the things you have talked about here already in some blog posts, so perhaps these sessions are not as shokingly full of new content as I imagined (but actually sharing experiences is something I can’t do by reading a blog post)

    +
      +
    • Perhaps: could you link some blog posts or other sources for what you have discussed so far? If it makes sense. Not sure.

    • +
    +
  • +
  • Talking about interface optimization approaches, which applies to sound as much as to visuals or any other aspect either for that matter, it might offer a perspective to bear in mind the concept of introducing asymptotic complexity increment. The latter would mean the goal is measuring how fast the effort of engaging, on one or more of the three parallel levels of interaction, must change to reach higher levels of partial certainty on the correctness of the implementation of the method in question, in this case the pedagogical paradigm. For the former, lower is better I guess, or in this case, in the intended sense, slower is faster. Let us consider an abstract example: People liked using the search engine Google (a Google session to put it in a fancy way) in the early days because it was as simple as it could get, a literally featureless entry point with no bells and whistles. That was the level of its visible complexity, or rather Google set a bar as low as it one could have, and then any higher point of VISIBLE complexity that was to be introduced, such a move would only be on the path of an asymptotic curve curving towards the set bar, never reaching it, as far as the entry point is concerned. We still see the same level of complexity when we fire up google and we never feel distracted to start with, except for the rather forgivable nuisance of the GDPR conformity pop-up notice which appears only AFTER the first move has been made, and thankfully it works plain and simple from there on (unless one starts feeling lucky, pun intended). Now, think about Youtube … the user experience complexity is a totally different matter, the same company today (unfortunately) yet one now has a steadily worsening engagement experience. Good learning sessions tend to be more of the Google search engine experience and a far cry from the current Youtube trend I would opine. Or, to sum it up and keep it sweet and simple, it helps to identify the limits of human-human and human-technology interaction, within the framework of any applicable technology-technology interaction and joy is the result of respecting those limits. Wishful thinking ?

  • +
  • Bring the cat back!

    +
      +
    • I wish it came, but it’s been resting all morning! I don’t bother it or stage apperances…

    • +
    +
  • +
  • Maybe having a digest/ summary of previous iterations of this session might be interesting. I feel a lot of experiences have been exchanged and a lot of techniques/ tools have been mentioned. Spending some time in compiling this into a selected list and adding it as content to the course itself might be worthwhile.

    +
      +
    • Good idea! We will write a blog post about this workshop and will include a summary of all discussions there :)

    • +
    +
  • +
  • Possibly have some command line examples from Windows rather than (just) *nix? I will look at the screenshots after the session. :+1: :+1:

    +
      +
    • Also, a thought if you do do breakout sessions with this work, do one for Unix, one for Windows, one for Mac as an option.

    • +
    +
  • +
  • I could not follow the part Radovan showed codes (Radovan is using Linux with (I think) the “i3 window manager”.)

  • +
  • ..

  • +
+

Any other comments?

+
    +
  • Looking forward to the topics of following sessions.

  • +
  • Looking forward to the next sessions!

  • +
  • Thank you!

  • +
  • Relax, nothing else matters, live a life and have fun ! If you obey all the rules you may end up missing all the fun. ‘The best way to predict your future is to create it.’ - Abraham Lincoln :+1:

  • +
+
+
+

Day 3 : sessiion 3 (27.08.24) - “About teaching and cool things we all would like to share”

+
+

:calendar: Schedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 9.45

Computational thinking

10.15 - 10.45

8.15 - 8.45

9.45 - 10.00

Break

10.25 - 11.00

8.25 - 9.00

10.00 - 10.30

Teaching philosophies

11.00 - 11.30

9.00 - 9.30

10.30 - 11.00

Co-teaching

11.30 - 12.00

9.30 - 10.00

11.00 - 11.15

Break

12.00 - 12.15

10.00 - 10.15

11.15 - 11.50

Sharing teaching gems (voluntary)

12.15 - 12.50

10.15 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+

:icecream: Icebreaker

+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • +
  • :sleeping:

  • +
  • :coffee:+2

  • +
  • :robot:

  • +
  • Still little sleeppy :)

  • +
  • 🥴 (:woozy_face: still not converted 🤷‍♂️)

  • +
  • Our planet could be a cube. It has six sides to it. It must be a cube. A cube it is, this Blue Planet … just wondering …

  • +
  • 🦾

  • +
  • :sweat_smile:

  • +
  • computer says no :-) some network trouble

  • +
  • running late, and participating from a :train2:

  • +
+
+
+
Introduction in breakoutrooms
+

Name / Affiliation / Location

+
+
+
Best classroom experiences
+

As a learner or teacher; what was the best workshop/lesson/seminar you have attended? What made the experience great?

+
    +
  • Room 1

    +
      +
    • First summer HPC streamed workshop (as a teacher). Somehow the first felt the best

    • +
    • CSC HPC summer workshop

    • +
    • story telling teaching approach

    • +
    +
  • +
  • Room 2

    +
      +
    • NVIDIA DLI Course on Deep Learning

      +
        +
      • very enthusiastic instructor

      • +
      • intuitive and very accessible way of showing technical details and fostering deeper understanding

      • +
      • a lot of hands-on material and smaller coding exercises

      • +
      +
    • +
    • Anything as long as its interactive and somehow enjoyable from both teacher and learner sides

    • +
    +
  • +
  • Room 4:

    +
      +
    • EPCC MPI Distributed training workshop.

      +
        +
      • Lots of hand on coding / experience gained.

      • +
      • Very interactive instructor who also discussed ideas for more personalised cases of distributed computing.

      • +
      +
    • +
    • Coderefinery RSE course

      +
        +
      • relevance of topic to my current work.

      • +
      • Dynamic / friendly / positive teaching style.

      • +
      • Modular Code Development; very instructive

      • +
      +
    • +
    • Some CSC courses / LinkedIn learning courses

      +
        +
      • up to date materials and topics.

      • +
      • Good way to merge theory with practicalities without making learner feel bored (Example: Jonathan Reichental)

      • +
      • Challenging information to learn more and research about the topic

      • +
      • Trainers are the experts in the field

      • +
      +
    • +
    +
  • +
+
+

Episode on teaching gems

+

If you want to share or demo something about tools and techniques you have found helpful in your teaching, please add your name/initials and rough topic below for smooth transition.

+
+

Note: It does not have to be your tool or your idea, this episode is meant to share experiences and discover new things. You also do not need any slides or materials, a story will do fine :) +Length of the stories will be depending on interest, but be prepared to fit it into 3 min (shortest possible).

+
+ +
+
+
+
+
+
+

:question: Questions

+
+

General / Practicalities

+
    +
  • What is this document for?

    +
      +
    • Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts)

    • +
    +
  • +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms?

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    +
  • +
+
+
+
+

Episode 1 : Computational thinking

+

Materials: https://coderefinery.github.io/train-the-trainer/computational-thinking/ (Link to slides in the middle of material)

+
+
Questions to audience
+

How might breaking down a complex problem into smaller parts change your approach to problem-solving in your current projects?

+
    +
  • Avoids cognitive overload

  • +
  • I used to give an example about this in workshops of cutting long tree into pieces from top to avoid that it falls and destroy a house bloc.

  • +
  • Easier to start on something small

  • +
  • Each individual part is familiar and can take existing solutions.

  • +
  • Only focus on the new things

  • +
  • One can lose oversight of where is supposed to be getting to due to problems with summation of biases introduced during the solving of the parts.

  • +
  • .

  • +
+

Can you think of a research project where identifying patterns in your data led to new insights or breakthroughs?

+
    +
  • Multi-targeted drug design where you need to identify both chemical and biological pathways/patterns

  • +
  • Distilling complex physics problems into simpler 1D statistics is very often done.

  • +
  • I used to do bioinformatics, pretty much everything in biology is about patterns in strings of charachters (DNA, proteins). Finding those patterns and using them is the way to go

  • +
  • Pattern recognition DOES NOT lead to new insight, it is new insight which allows for the recognition of a ‘pattern’, the latter being an allocation of possible bias.

  • +
  • +
  • ..

  • +
+

What challenges do you face when trying to simplify complex concepts in your field, and how do you decide which details to focus on?

+
    +
  • Absence of a terminology / jargon to describe a new idea. :+1:

  • +
  • Similar to above, when teaching often students know what they want to achive, but don’t have the termonology to express it, so working through what they want is helpful, after teaching them some termonology.

  • +
  • Whatever is most useful to the learner first?

  • +
  • I work with researchers in different fields. I don’t always fully understand their domain knowledge but I can take the basiscs or generalities and get code that works for them

  • +
  • A very practical problem is trying to resist going for a coffee in the midst of taking a shot at a complex concept, in the hope that the true details are to be found in the coffee.

  • +
  • not all information is easy to find or a lot of conflicting information or even sometimes imformation explosion

  • +
+

How do you determine the priority of tasks when designing algorithms for your academic projects, and what criteria do you use to ensure that the most critical tasks are addressed first?

+
    +
  • Working chronologically when going through a problem - start at the beginning.

  • +
  • What gives the more insight with the least effort can be a nice start

  • +
  • Talk to colleagues and Subject matter experts to understand various perspective to decide and prioritize.

  • +
  • Logic will get you from A to B. Imagination will take you everywhere. - Albert Einstein.

  • +
  • ..

  • +
+
+
+
Questions from the audience
+
    +
  • About the 4 core concepts, is this based on the model of how human brain works and perceives vision / abstract ideas?

  • +
  • I don’t know if it’s based on how the brain works, but it’s related to creating a framework for solving programming programs that has been extrapolated to solve any other problem as well.

  • +
  • Devil’s advocate question: cooking (by recipe) actually employs all four principles outlined here and has done so since before the advent of computers. Why then is this concept presented as “computational”?

    +
      +
    • Random aside, this is an interesting connection to our “cooking metaphor to HPC”

    • +
    +
  • +
  • Devil’s answer to the Devil’s advocate: Great question, cooking, as far as the act happens in the Devil’s kitchen, does not employ numerical algorithms. The Devil introduced the computer precisely to make man lose apetite for that what is cooked in the Devil’s kitchen to be served to all. Only then can the Devil eat the cake and keep it too …

    +
      +
    • Well, an algorithm without numbers is still an algorithm, i.e. a set of rules :)

    • +
    +
  • +
  • Are there other names for this technique? I may have missed something crucial, but it strikes me as ‘logical thinking’ in a way.

    +
      +
    • Yes, you could also just see it as problem solving. Most people know how to do it and if you’ve worked with programming, you’ve probably applied it. It can be the case that it’s very obvious to some, but not to others.

    • +
    +
  • +
  • Any chance we can ge a link to the slides?

    +
      +
    • They are in the course material: https://coderefinery.github.io/train-the-trainer/computational-thinking/ :thumbs_up:

    • +
    +
  • +
+
+
+
Exercise questions to discuss
+
    +
  1. Conceptually would the strategies provided by computational thinking help you in completing tasks more efficiently?

  2. +
+
    +
  • Room 1:

    +
      +
    • divide and conquer technique

    • +
    • We discussed what happens if you don’t use these, since they are so natural

    • +
    +
  • +
  • Room 2:

    +
      +
    • in some cases yes, if the task is not too small

    • +
    • not sure if more efficiently but it does help at least getting strted

    • +
    • Computational thinking is an extension of what others have called solutionism: the belief that any given problem can be solved by the application of computation. Whatever the practical or social problem we face, there is an app for it. - James Bridle

    • +
    +
  • +
  • Room 3:

    +
      +
    • Helps in starting the task.

    • +
    • For many it is the normal way to do problem solving. Also in Agile & Scrum methodlogies.

    • +
    +
  • +
  • Room 4:

    +
      +
    • Yes, it helped me during my scientific research to manage multiple projects and research publications simultaneously.

    • +
    • +
    +
  • +
+
    +
  1. Do you think that the effectiveness of computational thinking depends on the person’s personality type?

  2. +
+
    +
  • Room 1:

    +
      +
    • yes, we agree it’s quite different. But good vision and motivation this can be effective

    • +
    +
  • +
  • Room 2:

    +
      +
    • yes, laying out all the steps necessary to achieve an overall goal can be very daunting; some people are not good at/ comfortable with following fine-grained instructions

    • +
    • once the problem is broken down, different personalities might choose different ways to tackle the parts

    • +
    • The degree to which something, that is a result of what one means by ‘Computational Thinking,’ is successful in producing a desired result, that is success, cannot be a function of personality.

    • +
    +
  • +
  • Room 3:

    +
      +
    • Yes. Different people have different ways to communicate.

    • +
    • Online tools vs pen and paper

    • +
    +
  • +
  • Room 4:

    +
      +
    • We are all agree that it depends on the personality type but it could be learned and trained

    • +
    +
  • +
+
    +
  1. Would this type of thinking be an option for you to integrate into your current workflow?

  2. +
+
    +
  • Room 1:

    +
      +
    • Yes; we didn’t know the name explicitly; but we use it

    • +
    • It’s quite important for

    • +
    +
  • +
  • Room 2:

    +
      +
    • I’m already doing it implicitly :smile: :+1: :+1:

    • +
    • Writing a program is like writing a song, its all about the tune, lyrics are merely the necessary nuisance a coder needs to put up with. The latter can, if so written, result in a lot of noise.

    • +
    +
  • +
  • Room 3:

    +
      +
    • Easy if you are working alone. But different team may have their own ways of working (inertia). One way would be then to gradually show the rest of the team its effectiveness.

    • +
    • https://teamtopologies.com/key-concepts

    • +
    +
  • +
  • Room 4:

    +
      +
    • We are using it in our daily life so it’s already an option for us, only the terminologies are a bit new.

    • +
    +
  • +
+
+
+
+

Episode 2 : Teaching philosophies

+

Materials: https://coderefinery.github.io/train-the-trainer/teaching-philosophies/

+

Questions to discuss:

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+

Breakout Room exercise

+
    +
  • Room1

    +
      +
    • Motivation

      +
        +
      • For best practices in teaching, learning from each other, collaboration

      • +
      +
    • +
    • Learning applied tech is like an apprecentiship: there is theory, but real learning happens by co-working with others.

    • +
    • Worse is better: teach what can be used more quickly and it can be improved later

    • +
    • +
    • I think there are two bits of teaching - teach the basics and terminology so people know what they want to know, and then teaching how to find out how to do things like Richard said - how to find answers yourself.

    • +
    • Using Jupyter notebooks - good for learning a technique, but not for learning the basics.

    • +
    • Possibly command line usage has a branding problem - “programming other programs”?

    • +
    • the skills we learn in CR training are expected to stay , it is not exam oriented

    • +
    +
  • +
  • Room 2

    +
      +
    • State objectives clearly and repeat them a few times

    • +
    • Try to keep it informal, interactive, flexible

    • +
    • Helps when having practical tasks in mind for the materials taught

    • +
    • Leave some reasoning to the learner, not always giving full answers

      +
        +
      • How to deal with frustration though: try some personal approaches, more clues…

      • +
      +
    • +
    • The mediocre teacher tells. The good teacher explains. The superior teacher demonstrates. The great teacher inspires. — William Arthur Ward

    • +
    • Teaching kids to count is fine, but teaching them what counts is best. –Bob Talbert

    • +
    +
  • +
  • Room 4

    +
      +
    • Question 1: What is your motivation for taking this training?

      +
        +
      • Currently do instruction, wanting to improve as an instructor and helper when conducting software carpentries.

      • +
      • Planning to start some side hustles providing online courses and why not joining the CR in the near future

      • +
      +
    • +
    • Question 2: How structured or informal are your own teaching needs?

      +
        +
      • More recently, follow software carpentries, but look into what aspects can be tailored to keep to different time slots.

      • +
      • I used to be more informal in the past, repetetive practice sessions. Would like to be more structured given the teaching tools.

      • +
      • I’ve done life-coaching and some teaching but I feel i’m both of them

      • +
      +
    • +
    • Question 3: What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

      +
        +
      • Smaller size, and more targetted.

      • +
      • Collaborative tools and targeted audience working with small groups

      • +
      • Academic probably focuses on an audience with a more focused/narrow background, while this style encompasses a wider audience.

      • +
      • Academic teaching keeps theory and practical lab sessions very separate, whereas carpentries combine both.

      • +
      +
    • +
    • Question 4: What other skills need to be taught, but academic teaching isn’t the right setting?

      +
        +
      • Public speaking, collaborative meeting skills

      • +
      • Industrial cases and related work skills

      • +
      +
    • +
    +
  • +
+
+
+

Episode 3: Co-teaching

+

Materials: https://coderefinery.github.io/train-the-trainer/co-teaching/

+
    +
  • In general: Co-teaching is a beast with at least two personalities each of which

    +
      +
    • demand higher preparation requirements

    • +
    • face remarkable complexity in terms of coteacher coordination

    • +
    • in the virtual component face shortcomings related to the technical equipment and the failure of the human factor

    • +
    +
  • +
+
    +
  • Co-teaching requires the framework of co-operative learning. Team teaching does not by default translate into parallel learning, and vice versa.

  • +
+
    +
  • Re: CodeRefinery in-person beginnings – I agree with the “didn’t work so well in-person”, I’m not sure if it’s that we weren’t as ready for it, or that the different characteristics made it not work so much

  • +
  • How do the downsides compare to a single instructor monologuing?

    +
      +
    • That’s a great question! The main difference is that a single instructor can teach himself to be good (i.e. not just boring monologuing) alone, while for teams of 2+ to work well, everyone needs to be baseline-competent. So the effort to avoid downsides gets reduced if (and only if) all team members share it.

    • +
    +
  • +
+
+

Exercise/Discussion: https://coderefinery.github.io/train-the-trainer/co-teaching/#exercise

+

Questions:

+
    +
  • Have you already tried this or similar model in your teaching?

  • +
  • Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best?

  • +
  • Have you tried or seen a different model for two instructors to present? Please share with us how it works.

  • +
+
+
    +
  • room 1

    +
      +
    • We have tendend to do presenter/interviewer more

    • +
    • challenges are co-teaching with different personalities

    • +
    +
  • +
  • room 2

    +
      +
    • Main challenge: finding enough personell :smile:

    • +
    • It’s not always possible/feasible to have colleagues co-teaching

    • +
    • A combination of both, but presenter and interviewer could be difficult to plan an to follow

    • +
    • Guide and demo-giver with technical / non-technical roles could be nice

      +
        +
      • How to plan the guide and demo-giver

        +
          +
        • First guide, then demo

        • +
        • Demo, then guide describes

        • +
        +
      • +
      +
    • +
    • Alternative model: main presenter + ‘technical expert’

      +
        +
      • main presenter introduces concepts from a birdseye view and passes on to the technical expert for additional details, experiences and answers to questions from the audience

      • +
      +
    • +
    • We frequently do a classical division: on person in presenting, one or more are answering questions in the chat; there is rarely any interaction between them however

    • +
    +
  • +
+
    +
  • As has been pointed out by Paolo Freire, in general, ‘education is suffering from narration sickness’ … ‘The outstanding characteristic of this narrative education, then, is the sonority of words, not their transforming power’. Perhaps one approach could be to rephrase the question after having the answer: It is not apriori about the model implemented, it is about whether that what was implemented was judged aposteriori to have succeeded in becoming, or at least could pretend to have done so, the intended context matched model implementation it probably was computed to be.

  • +
+
    +
  • room 4

    +
      +
    • the co-teaching approach does not seem to be widely practiced

    • +
    • it can be interesting to see “mistakes” which are less likely to happen in solo-teaching?

    • +
    • co-teaching can be nicer for audience but maybe more stress/anxiety for instructors to prepare? more stress in terms of not knowing all the questions in advance. less stress worrying about forgetting something.

    • +
    +
  • +
+
+
+

Teaching gems

+

(scroll up to find the green box “Episode on teaching gems”)

+

What’s your favorite way of teaching? Any nice tools you use?

+

Has anyone found a nice online tool to draw?

+
    +
  • I love this tool suite https://excalideck.com/

    +
      +
    • For drawing https://excalidraw.com/

    • +
    +
  • +
  • I have seen Miro …

  • +
  • I think the Code Refineries use something for their graphics that looks a bit ‘cartoony’ - but I cannot remember what it is called!

    +
      +
    • Drawn on remarkable and then coloured and tidied up in Inkscape. :+1:

    • +
    +
  • +
  • I am a big fan of remarkable. I think sharing option is fairly good. Unfortunately bit expensive tool.

    +
      +
    • true, for me it was worth it already for the pdf annotation for research papers, cannot read on computer screen

    • +
    +
  • +
  • https://webwhiteboard.com/

  • +
  • https://www.youtube.com/watch?v=4-l8MY5kYGc

  • +
  • Figma and Kahoot are useful as well

  • +
+

Screenkey: Screenkey for showing keyboard shortcuts

+
    +
  • Is there a Windows version people can recommend?

    +
      +
    • I found this list of alternative for windows users like me: https://alternativeto.net/software/screenkey/ :+1:

    • +
    +
  • +
  • I sometimes use the on-screen keyboard already provided by the OS :+1:

  • +
+
+
+
+

Wrapup

+
    +
  • Next session Tuesday September 3rd 9 CEST: About teaching & cool things we all would like to share

  • +
  • All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14 CEST

  • +
  • Preparations for next week will be sent out by e-mail

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • The co-teaching lesson and experiences from others

  • +
  • Discussions were quite good, had a nice group

  • +
  • Breakout rooms and collaborative tools

  • +
  • Computational thinking and co-teaching are interesting ideas! I have seen it before, but never knew or even recognized it was a method.

  • +
  • Thanks for group discussions working with my chat only interaction! :smile:

  • +
  • ..

  • +
+

What one thing would you improve about this session?

+
    +
  • Minor point - it would be useful to have the teaching gmes box at the bottom of the document rather than the top - tricky to scroll between! In the end I opened two windows which was easier.

    +
      +
    • Thanks, yes agree. Also had that problem, but did not want to move it in between.

    • +
    +
  • +
  • The meaning of teaching “philosophy” wasn’t very clear, felt more like teaching “styles”

    +
      +
    • Thank you, we will take that into consideration

    • +
    +
  • +
  • Some prepared slides to present for an intro about the topics

    +
      +
    • You mean in addition to the materials? To use in the beginning of each session?

    • +
    +
  • +
  • The instructor views segment could be named as additional material, if it was not meant to be discussed within the course.

    +
      +
    • Thank you, we will take that into consideration

    • +
    +
  • +
+

Any other comments?

+
    +
  • Keeping it short and sweet: If at first you don’t succeed in teaching, try to explain it like you’re talking to a room full of cats. Caveat: In a room full of computational thinkers maybe if you tell students that the brain is a computational device that is forbidden, they might get excited and start using it.

  • +
+
+
+

Day4: Session 4 (3.09.24) - Streaming and video editing

+
+

:calendar: Schedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 10.00

Why we stream & Behind the scenes

10.15 - 11.00

8.15 - 9.00

10.00 - 10.15

Break

11.00 - 11.15

9.00 - 9.15

10.15 - 10.35

Video Editing

11.15 - 11.35

9.15 - 9.35

10.35 - 10.55

Exercise: Video Editing

11.35 - 11.55

9.35 - 9.55

10.55 - 11.10

Break

11.55 - 12.10

9.55 - 10.10

11.10 - 11.30

Open Broadcaster Software(OBS) introduction

12.10 - 12.30

10.10 - 10.30

11:30 - 11:50

OBS setup & what next

12.30 - 12.50

10.30 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+

:icecream: Icebreaker

+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :coffee: +

  • +
  • :runner:

  • +
  • :tired_face: Tired!

  • +
  • :nerd_face:

  • +
  • +
  • :cloud: :tea:

  • +
+
+
+
Introduction in breakoutrooms
+
    +
  • Name / Affiliation / Location

  • +
+

What’s the most number of people you have taught to?

+
    +
  • 20 at a time, with 1 asleep, 2 fidgiting with some silly device and the rest were… well… staring at their good luck… straight ahead it was of course, right before them.

  • +
  • ~35

  • +
  • ~80 in a lecture in a previous (lecturer) role, 26 in a training course setting

  • +
  • ~30

  • +
  • ~50 in training spaces and more than 100 for public audience talk

  • +
  • 35 (software carpentry)

  • +
  • CodeRefinery answer: The biggest ones are maybe 200-300 people. “small” for a stream is ~100 people.

  • +
+

What’s the most number of people you have taught with?

+
    +
  • 5 or so

  • +
  • 2 or 3 in total

  • +
  • 3, as in three, none of them smiling. I wish I could figure out why… it was such fun really…

  • +
  • 7

  • +
  • 2 or 3

  • +
  • 3 (helpers, not really co-teaching)

  • +
  • CodeRefinery answer: our biggest workshops are something like 10-20 people helping out in many different roles.

  • +
+

How can you divide teaching into separate independent tasks?

+
    +
  • By content blocks, having roles like main and assistant…

  • +
  • Having responsibility for different sections of the course.

  • +
  • Wow, now thats what we call a question… bravo… indeed, how does one separate sleeping and snoring into separate independent tasks…

  • +
  • Course, exercices, resources, tools and forms.

  • +
  • Different people teach different topics

  • +
  • CodeRefinery answer: the big logical blocks are instructors, in-person and breakout room helpers, and Notes-questions answers.

  • +
+

What’s the most interesting or useful thing you’ve learned from an online workshop, and how have you applied it/planning to apply in your life or work

+
    +
  • Having breaks every hour or so

  • +
  • New approach to screensharing, using the ‘portrait’ approach

  • +
  • Manage breathing: reduce stress and use silence to let the audience grasp what you’re saying

  • +
  • Well, the most interesting or useful thing I’ve learned from online workshops is how not to conduct a workshop, or at least some elements of the same, and I have applied this understanding by engaging in the global effort to discover more about how not to conduct a workshop, or at least some elements of the same, with the motto: That’s one small step for a man, one giant leap for mankind..

  • +
+
+
+
+

:question: Questions

+
+
+

Why we stream

+
    +
  • If during streaming there is no interaction between the teacher and the audience, why don’t we just record the lectures and stream them? So one can do a better job, perhaps?

    +
      +
    • Streaming it making it a “thing” that’s a group experience. It feels good to be a part of it, so we hope that encourages people to actually attend. All the mass Q&A is fun, and the audience helps to make it easier to present. Still, this is a good question.

    • +
    • I really appriciate it being “a thing”. If it was just recorded, I would say I would watch it tomorrow, and then I never would.

      +
        +
      • But then you can just fake it, and still have all the breakout rooms and collaborative document and so on. I appreciate the value of having a proper “event”.

        +
          +
        • I think I follow you, but if you pre-recorded the talking bits, then the presentors couldn’t change what they do based on the feedback in the shared document.

          +
            +
          • true, but I assumed that the teachers were too busy to actually do that. The more (less )division of labor between the teachers and the helpers (or collaborative document editors), the more (less) sense it makes to pre-record - IMHO

          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • What interaction options do ‘streamers’ use, e.g. on Twitch/YouTube (not Code Refinary)?

    +
      +
    • I’m besides chat and things that happen in chat, I’m not sure. The Notes-doc is definitely unique to us.

    • +
    +
  • +
  • Streaming is a kind of exercise for the movie star type. If you cannot be one, act like one, pretend, fool the listener into thinking you are one, take their brains and emotions under control. And if they don’t leave the session with tears of love for learning running down their chubby cheeks you know who to kick for doing a job just that bit worse than it should have been necessary.

  • +
  • Have you kept track of streming stats? like how many people logged in and stayed troughout, how many interacted?

    +
      +
    • Yes please, it would be good to see the stats

    • +
    • Here is stats repo

    • +
    • Thanks, I get a 404 error, is it private?

    • +
    • No, I don’t think so. https://github.com/coderefinery/workshop-stats

    • +
    • Still get 404. Does it work for anyone else?

      +
        +
      • Yeah I think it’s private. We need to fix this…

      • +
      +
    • +
    +
  • +
  • How big is small (10-15), medium (~30-40)?

    +
      +
    • I would say below 50 is small.

    • +
    +
  • +
  • Have you considered scaling to more events instead of to a larger audience? I mean, this seems the opposite of scaling, but this kind of content would be more useful the more often is it taught (“I need to learn GIT/Python/* in December!”)

    +
      +
    • We would, but right now we simply don’t have enough time and people to do more small events. But yes, “scheduling conflict” is a big problem - the best we can do right now is written material+videos to follow up on (and hope it’s interesting enough)

    • +
    • Python for Scientific Computing 5-7/November/2024

      +
        +
      • This was just an example. I mean, if I am a PHD student that needs to start working on a topic on Month X which happens to be inconveniently placed in the year, I will not benefit as much from having a workshop at Month X+3

        +
          +
        • The materials are open and the videos are publically available on YouTube channel

          +
            +
          • What’s the ratio of people watching videos afterwards vs people attending the event? That ratio can give an idea of the popularity of the two possible approaches.

          • +
          +
        • +
        +
      • +
      +
    • +
    • The more you scale up the less interactive the course / workshop will need to be. It then becomes a question of priorities, and if teaching is a lower priority then learning than I guess there really should be no prizes for guessing which approach should reign the airwaves.

    • +
    +
  • +
  • I guess outside Europe / Africa, time zones could be a problem?

    +
      +
    • yes, that is true

    • +
    • +
    +
  • +
  • Sorry, I might have missed this: have you been rehearsing and/or doing dry runs?

    +
      +
    • With instructors I like to try to do a dry run. I often don’t do a live broadcast dry run these days since I’m confidente enough, but when you are just starting, it’s a good idea.

    • +
    +
  • +
  • Do you always use Zoom for the ‘presenter end’ or have you tried other things? Teams? Jitsi? etc.?

    +
      +
    • we use mostly zoom

    • +
    • It was first pioneered using Jitsi. You can probably use others, too.

    • +
    +
  • +
  • A comment: for deRSE24 we have been using the GWDG streaming service and OBS, it worked quite well (with a 20s delay or so)

    +
      +
    • Cool! Yes, there is plenty of livestreaming options. Twitch+our OBS config gives us 2-3s of latency (which is low enough for live Notes interaction). You might be able to tune this if needed.

    • +
    +
  • +
+
+
+

Behind the stream

+
    +
  • Does OBS take a lot of RAM or CPU? what are the specs on your machine?

    +
      +
    • Richard have a relatively powerful computer with 8 AMD CPUs.

    • +
    • 4 CPUs are relatively enough for a good OBS setup, most important is a stable internet connection (ideally wired).

    • +
    • An extra monitor is recommended for the setup

    • +
    • See the hardware notesrecommendation here

    • +
    +
  • +
  • Do you do a screenshare from Zoom -> OBS or OBS -> Zoom?

    +
      +
    • Instructors share to Zoom, OBS captures Zoom, OBS sends to the world.

    • +
    • When I am using OBS sfor a single-person presentation recording, I go the other way: OBS captures my desktop/camera, OBS generates the preview window, and then Zoom captures and broadcasts the preview window.

    • +
    +
  • +
+
+
+

Video editing

+
+
Poll
+
    +
  • Have you tried video editing? Add ano as answer below

    +
      +
    • yes: ooooo

    • +
    • no :

    • +
    • Video editing makes all the difference. I have never known a way to avoid this sacred of steps, so to speak. In short, no recording can ever be production ready by default in the books of the wiser among the streamers. In fact, during the editing one can considerably refine and improve the learning experience in great ways. But then one would need to invest both time and effort.

    • +
    +
  • +
  • If yes Which are the tools you use?

    +
      +
    • Windows Movie Maker / ClipChamp

    • +
    • (raw stream from Zoom)

    • +
    • I think it was shotcut - I did only basic trimming

    • +
    • Kdenlive

    • +
    • Clipchamp, OpenShot, Sony Vegas

    • +
    • also ffmpeg from command line to cut beginning and end

    • +
    +
  • +
+
+
+
Questions
+
    +
  • What is Whisper?

    +
      +
    • Open-source model from OpenAI that converts speech to text transcripts.

    • +
    • this one? https://openai.com/index/whisper/

    • +
    • curious if anyone has tried it with languages other than english

    • +
    • I heard that one of my spanish colleague try it with another software. I don’t remember the tool. But with AI bloom there are many licensed tools that can do it with fifferent language

    • +
    +
  • +
  • What do you use to crop the videos?

    +
      +
    • I see now, ffmpeg

    • +
    +
  • +
  • how to merge multiple parts in one? I asked because you edited only the icebreaker part?

    +
      +
    • you can manage it in input part, see ffmpeg-editlist readme.

    • +
    +
  • +
  • Do you generate custom thumbnails for the video?

    +
      +
    • no, because of the time, but its good to have. If we had a volunteer to manage that, then we should!

    • +
    +
  • +
  • Does anyone recommend any other (GUI) tools that work well? ffmpeg is very new to me!

    +
      +
    • if you want a basic trimming and editing , you can use Quicktime player/imovies on mac

    • +
    • Clipchamp as the Microsoft video editor

    • +
    • Thanks :smile:

    • +
    +
  • +
  • How do subtitles get uploaded to YouTube?

    +
      +
    • You upload the video and subtitles as part of upload.

    • +
    • :+1:

    • +
    +
  • +
  • How does codewhisperer compare against youtube’s automatically generated subtitles?

    +
      +
    • by experience, whisper was better couple of years ago. We haven’t compared it recently

    • +
    • I guess and advantage is that you can edit whisper subtitles in case something is odd or whatever, probs cannot do that in YouTube

    • +
    +
  • +
+
+
+
+

Open Broadcaster Software (OBS) introduction & setup

+
    +
  • Are the profiles public?

    +
      +
    • Yes, you can see it here

    • +
    +
  • +
  • Does it work in Linux+Wayland?

    +
      +
    • I think everything we do with OBS would.

    • +
    +
  • +
+
+
+
+

Wrapup

+ +
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • ffmpeg seems great, will give a try for fun!

  • +
  • great to see everything in practice!

  • +
  • Very insightful to see what happens behind the scenes.

  • +
+

What one thing would you improve about this session?

+
    +
  • Some more interactivity would’ve been nice but since most the group preferred demo instead of exercise perhaps it’s only a personal opinion

  • +
  • It would have been good to share the OBS profiles repo beforehand in the setup email - so I could have had it to hand. (https://github.com/coderefinery/obs-config)

    +
      +
    • +1 good idea, we should do this next time

    • +
    +
  • +
  • Perhaps a simpler starter OBS setup?

    +
      +
    • Good idea… I should have, but basically ran out of time to prepare.

    • +
    +
  • +
+

Any other comments?

+
    +
  • Cool to see the switch from RSE to trainer to AV guy, impressive!

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/objects.inv b/branch/cff/objects.inv new file mode 100644 index 0000000..cba69ae Binary files /dev/null and b/branch/cff/objects.inv differ diff --git a/branch/cff/obs-config/index.html b/branch/cff/obs-config/index.html new file mode 100644 index 0000000..f8717f9 --- /dev/null +++ b/branch/cff/obs-config/index.html @@ -0,0 +1,276 @@ + + + + + + + Open Broadcaster Software (OBS) setup — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Open Broadcaster Software (OBS) setup

+
+

Objectives

+
    +
  • See how to configure OBS using the pre-made CodeRefinery scene +collections

  • +
  • Modify the collections to suit your needs.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: ?? min

  • +
  • Hands-on: ?? min

  • +
  • Q&A: ?? min

  • +
+
+ +

In this lesson, we’ll see how to configure OBS from scratch for your +purposes. We’ll do this by deleting the instructor’s configuration +and trying to recreate it

+

This section is short, since it has never been done before: we’ll just +give it a short and update the lesson later.

+
+

CodeRefinery OBS configs

+
    +
  • CodeRefinery configs are shared in a repository: +https://github.com/coderefinery/obs-config

  • +
  • These can be imported to pre-configure some things

  • +
  • There are two types of configs:

    +
      +
    • Profiles

      +
        +
      • Servers, resolutions, audio, video, etc.

      • +
      +
    • +
    • Scene collections

      +
        +
      • The graphical layouts.

      • +
      +
    • +
    +
  • +
+
+
+

Installing the OBS config

+
    +
  • Clone the git repository.

  • +
  • Import the profile and scene collections under their respective +menus.

  • +
+
+
+

Initial setup

+
    +
  • Click through each menu and change anything that is needed

  • +
  • Set the streaming server

  • +
+
+

The instructor will go through the setup.

+
    +
  • Reset configuration: mv .config/obs-studio/ .config/obs-studio-old/

  • +
  • Import profiles/TeachingStreamingv3/

  • +
  • Import scenes/TeachingStreamingZoomv3.json

  • +
+
+
+
+

Set up the remote control

+
    +
  • Create a Python environment and install it: pip install https://github.com/coderefinery/obs-cr/archive/refs/heads/master.zip

  • +
  • Run it: python obs_cr/control.py localhost:4445 TOKEN --broadcaster

  • +
  • There are more options but let’s not cover them yet… and leave +this for a hands-on session.

  • +
+
+
+

Setup before each course

+
    +
  • Re-confirm audio

  • +
  • Re-confirm each scene

  • +
  • Test everything

  • +
  • rkdarst has a rather long +checklist, +but each individual step is short.

  • +
+
+
+

Q&A

+

We’ll answer audience questions.

+
+

Keypoints

+
    +
  • Most of our configuration has been OBS may seem complicated, but it’s a graphical application and most +pieces make sense once you know how it works.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/obs/index.html b/branch/cff/obs/index.html new file mode 100644 index 0000000..205a80a --- /dev/null +++ b/branch/cff/obs/index.html @@ -0,0 +1,259 @@ + + + + + + + Open Broadcaster Software (OBS) introduction — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Open Broadcaster Software (OBS) introduction

+
+

Objectives

+
    +
  • Understand that OBS is a video mixer.

  • +
  • Understand the basic controls and features of OBS.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 15 min

  • +
  • Q&A 5 min

  • +
+
+ +

In this episode, you’ll get more familiar with the OBS portion of the +streaming setup. You’ll see how it’s used, but not yet how to +configure it from scratch. You’ll learn how to be a “director”.

+
+

What is OBS?

+
    +
  • Formally “OBS Studio”

  • +
  • Most commonly known as a livestreaming application.

  • +
  • Open source, free.

  • +
  • Cross-platform, easy to use screencasting and streaming application.

  • +
  • Real-time video mixer.

  • +
+
+
+

OBS user interface

+
    +
  • We’ll click through each view.

  • +
  • What does each view do?

  • +
  • Let’s click through the buttons.

  • +
  • Let’s see the important config options.

  • +
+
+
+

OBS during a course

+
    +
  • What management is needed.

  • +
  • The control panel.

  • +
  • Audio.

  • +
  • Adjusting windows and so on.

  • +
+
+
+

Hardware requirements

+
    +
  • Reasonably powerful broadcast computer

    +
      +
    • CodeRefinerys streaming computer is 8 CPU AMD, 64GB memory

    • +
    • That is way overkill: a powerful laptop can probably do this.

    • +
    +
  • +
  • Large second monitor for laying out the windows you capture

  • +
  • Stable internet connection (wired preferable)

    +
      +
    • CodeRefinery’s broadcast is the slowest purchasable: 100 Mbit down / +25Mbit up

    • +
    +
  • +
+
+
+

Q&A

+

We’ll answer audience questions.

+
+
+

See also

+ +
+

Keypoints

+
    +
  • OBS may seem complicated, but it’s a graphical application and most +pieces make sense once you know how it works.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/overview/index.html b/branch/cff/overview/index.html new file mode 100644 index 0000000..c63b95c --- /dev/null +++ b/branch/cff/overview/index.html @@ -0,0 +1,418 @@ + + + + + + + A workshop seen from different perspectives — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

A workshop seen from different perspectives

+
+

Objectives

+
    +
  • Understand the general structure of CodeRefinery workshops and why it is the way it is

  • +
  • Get to know the different roles of a workshop and which ones are the most essential ones

  • +
  • Understand the importance of installation instructions and how they contribute to learners success

  • +
  • Understand the importance of onboarding and a welcoming community for volunteers in a workshop

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 15 min

  • +
  • Roles journeys can be shortened to looking only at instructor role.

  • +
+
+
+

Note

+

This episode focuses on the large scale streamed workshop setup. Some of the features can also be applied to smaller scale workshops though.

+
+
+

Discussion

+
+

Discussion

+

In breakoutrooms: choose one or two questions to talk about your own experiences; summary in collaborative notes:

+
    +
  • What kind of roles have you been in yourself regarding workshops?

  • +
  • How were you prepared for your role?

  • +
  • What are the things you would like to know before a workshop?

  • +
  • How are you preparing your participants for your trainings?

  • +
  • What was the best workshop experience for you as learner, helper or instructor? What made it great?

  • +
+
+
+
+

One workshop - many parts

+
+../_images/CR_workshop_setup.png +
+

Image showing the different phases of a CodeRefinery workshop described below. Also showing that while there is only two people teaching, many people work behind the scenes.

+
+
+
+

Before the workshop

+
    +
  • During winter/summer: “Someone” takes the coordinator role for the next workshop

  • +
  • Coordinator fills other roles:

    +
      +
    • Coordinator: collects necessary lesson updates, supports other coordinators

    • +
    • Registration coordinator: Sets up web page, starts and manages registration

    • +
    • Instructor coordinator: Finds instructors and onboards them

    • +
    • Advertising coordinator: Prepares advertizement texts and finds people to distribute them

    • +
    • Team coordinator: Gathers local organizers/teams

    • +
    • Bring your own code session coordinator: If available, offer BYOC session after main workshop

    • +
    +
  • +
  • Instructor: Onboarding with (instructor-) coordinator and previous instructor of lesson; update of lesson materials (urgent issues and personal touches)

  • +
  • Local organizer/Team lead: Group onboarding ~ week/or two before workshop

  • +
  • Learner: Gets installation instructions, invited to installation help session, workshop info from event page and summary via e-mail

  • +
  • Collaborative notes manager sets up the notes document

  • +
+
+

Note

+

Onboarding manuals

+
    +
  • Outline of what will happen during the workshop

  • +
  • Discussion of different strategies to handle the exercise sessions

  • +
  • Lowering the barrier to ask for support by meeting some organizers

  • +
  • Q&A

  • +
+
+
+

Note

+

Installation instructions

+
    +
  • Instructions for all operating systems

  • +
  • Goal: Learners leave the workshop and are ready to apply the learned tools and techniques to their own work

  • +
  • Support session for installation challenges

  • +
+
+
+
+

During the workshop

+
+../_images/BYOC.png +
+

Image showing the different ways learners can do the exercises. No matter which way they choose, they always watch the stream and interact with instructors and organizers via collaborative notes. Individual learners do the exercises alone, people in online or local classrooms in addition get to discuss with their peers.

+
+
+
    +
  • Everyone watches stream

  • +
  • Co-instructors +- Present content +- Answer questions in collaborative notes

  • +
  • Collaborative notes manager

    +
      +
    • Keeps the collaborative notes clean

    • +
    • Helps answering questions

    • +
    • Adds sections

    • +
    • Archives the document after each day

    • +
    +
  • +
  • Learners do exercises individually or in team

  • +
  • Local organizer / Team lead

    +
      +
    • Guides learners through exercises

    • +
    • Facilitates discussion

    • +
    +
  • +
  • (Registration-) coordinator sends out e-mails to participants after each day (summary + preparation)

  • +
  • Director/Broadcaster manages the streaming (see session 4)

  • +
+
+
+

After the workshop

+
    +
  • Coordinator collects lessons learned based on experience and feedback and turns them into issues

  • +
  • Coordinator organizes debriefing week after the workshop, where anyone can join to give feedback

  • +
  • “Someone” sends out post-workshop survey half a year after workshop

  • +
  • Coordinator organizes “Bring your own code” sessions

  • +
  • Broadcaster prepares and shares recording (see session 4)

  • +
+
+

Note

+

Bring your own code sessions

+

We want to support learners to apply what they have learned in the workshop to their own work by offering one/two sessions where they can drop in, and discuss challenges with CodeRefinery instructors and helpers.

+
+../_images/welcome.png +
+

Image showing a classroom learning about git leading to a discussion between student and teacher to start a welcoming environment for asking for help.

+
+
+
+
+
+
+

This sounds like a lot of people and time investment!

+
    +
  • Many roles can be combined or adjusted as needed

  • +
  • Some roles can be taken on by multiple people

  • +
+

So how many people are needed for this kind of workshop?

+
    +
  • Recommended minimum: 2-3 people

  • +
  • Optimum: ~ 4-5 people +The more people you involve, the more time goes into coordination work.

  • +
+
+
+

How did we get to this setup?

+
    +
  • Collaborative in-person workshops since 2016 around the Nordics

  • +
  • Moved online in 2020

  • +
  • Started with “traditional zoom” workshops, breakoutrooms, volunteer helpers

  • +
  • Thought about scaling and ease of joining -> current setup (More about this in session 4)

  • +
  • Continuous development

  • +
+

We also still do smaller scale local workshops, if instructors are available. +You can offer your own CodeRefinery workshop by inviting other CodeRefinery instructors. +You can also reuse single lessons and integrate them into your own teaching.

+
+
+

Workshop roles and their journeys

+
+

Individual learner journey

+
    +
  • Registration

  • +
  • Installation

  • +
  • (if appicable: Invited to local meetup)

  • +
  • Workshop

    +
      +
    • Watch stream

    • +
    • Q&A in notes

    • +
    • Exercises alone or in team

    • +
    • Daily feedback

    • +
    +
  • +
  • Debrief/ Feedback session

  • +
  • Post workshop survey

  • +
+
+
+

Instructor journey

+
    +
  • Indicate interest in CodeRefinery chat

  • +
  • Onboarding

  • +
  • Lesson material updates

  • +
  • Teaching

  • +
  • (if wished: supports answering questions in notes)

  • +
  • Debrief

  • +
+
+
+

Team lead / Local host journey

+
    +
  • Registration

  • +
  • (if applicable: run own registration)

  • +
  • Onboarding

  • +
  • Workshop

    +
      +
    • Watch stream

    • +
    • Facilitate exercises/discussions

    • +
    • Daily feedback

    • +
    +
  • +
  • Debrief / feedback / survey

  • +
+
+
+

Other roles

+

Director and broadcaster roles will be discussed in Session 4. +For more in-depth descriptions and other roles (host, instructor, registration coordinator, etc), see also our CodeRefinery manuals.

+
+
+
+

Different roles as stepping stones for community involvement

+
+../_images/steps.png +
+

Image showing a person jumping from step to step following learner, helper, expert helper, co-instructor, co-organizer.

+
+
+

There is no “one way” to get involved. Do what feels right. +Interested in teaching with us? Let us know and we can discuss what is a suitable path for you!

+
+

Keypoints

+
    +
  • CodeRefinery workshops are a collaborative effort with many different roles

  • +
  • Onboarding the different roles is one key aspect of our workshops

  • +
  • Everyone has their own path

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/screenshare/index.html b/branch/cff/screenshare/index.html new file mode 100644 index 0000000..a16afec --- /dev/null +++ b/branch/cff/screenshare/index.html @@ -0,0 +1,565 @@ + + + + + + + How to prepare a quality screen-share — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

How to prepare a quality screen-share

+
+

Objectives

+
    +
  • Discuss the importance of a well planned screen-share.

  • +
  • Learn how to prepare and how to test your screen-share setup.

  • +
  • Know about typical pitfalls and habits to avoid.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 15 min

  • +
  • Exercises: 15 min

  • +
+
+
+

Share portrait layout instead of sharing entire screen when teaching online

+
    +
  • Many learners will have a smaller screen than you.

  • +
  • You should plan for learners with only one small screen.

  • +
  • A learner will need to focus on both your screen share and their +work.

  • +
  • Share a portrait/vertical half of your screen (840 × 1080 is our standard and your +maximum).

  • +
  • Zoom provides a “Share a part of screen” that is good for this.

    +
      +
    • Our latest streaming setup (day 4) can take the portrait part for +you so you can share landscape.

    • +
    • Zoom + Linux + Wayland display manager doesn’t have “Share a +portion of the screen”

      +
        +
      • You can share a single window portrait.

      • +
      • Or you can start your desktop session in “X11” or “Xorg” legacy +mode.

      • +
      • Or possibly other workarounds (does anyone know other solutions?)

      • +
      +
    • +
    +
  • +
+
+../_images/landscape.png +
+

A FullHD 1920x1080 screen shared. Learners have to make this really small if +they want to have something else open.

+
+
+
+../_images/portrait.png +
+

Portrait layout. Allows learners to have something else open in the other half.

+
+
+

Motivation for portrait layout:

+
    +
  • This makes it easier for you to look at some other notes or to coordinate +with other instructors at the same time +without distracting with too much information.

  • +
  • This makes it possible for participants to have something else open in the +other screen half: terminal or browser or notebook.

  • +
+
+

Instructor perspective

+
+../_images/instructor.png +
+

I1: +This is how it can look for the instructor. Zoom is sharing a portion of the left +side, the right side is free for following notes, chat, etc.

+
+
+
+
+

Learner perspective

+

Here are three examples of how it can look for the learner.

+
+../_images/learner-large.png +
+

L1: +Learner with a large screen, Zoom in dual-monitor mode so that the instructor +pictures are not shown. Screen-share is on the left side, collaborative notes +at bottom left, terminal and web browser on the right.

+
+
+
+../_images/learner-normal.png +
+

L2: +A learner with a single large screen (Zoom in “single monitor mode”). +Instructor screen share at right, learner stuff at left.

+
+
+
+../_images/learner-small.png +
+

L3: +A learner with a particularly small screen. Instructor screen-share at left, +your windows at right.

+
+
+
+
+
+

Share the history of your commands

+

Even if you type slowly it is almost impossible to follow every command. We +all get distracted or want to read up on something or while following a command +fails on the learner laptop while instructor gets no error.

+

Add pauses and share the commands that you have typed so that one can catch up.

+

Below are some examples (some more successful than others) of sharing history +of commands.

+
+../_images/history-portrait.png +
+

H1: +A vertical screen layout shared. Note the extra shell history at the top. The +web browser is at the bottom, because the Zoom toolbar can cover the bottom +bit.

+
+
+
+../_images/history-rsh.png +
+

H2: +This isn’t a screen-share from CodeRefinery, but may be instructive. Note the +horizontal layout and shell history at the bottom right.

+
+
+
+../_images/history-landscape-dark.png +
+

H3: +Similar to above, but dark. Includes contents on the right.

+
+
+
+../_images/history-portrait-light.png +
+

H4: +Jupyter + terminal, including the fish shell and the terminal history.

+
+
+
+../_images/history-portrait-dark.png +
+

H5: +Lesson + terminal, tmux plus terminal history and dark background.

+
+
+
+../_images/portrait.png +
+

H6: +HPC Kickstart course. Note the colors contrast of the windows and colors of +the prompt and text. The history is smaller and doesn’t take up primary +working space. The working directory is in the window title bar.

+
+
+
+https://raw.githubusercontent.com/bast/history-window/main/demo.gif +
+

H7: +Show command history “picture-in-picture”, in the same terminal window.

+
+
+
+
+

How to configure history sharing

+

You need to find a way to show the recent commands you have entered, so that +learners can see the recent commands. Below are many solutions. Try them out +and see what works for you.

+
    +
  • prompt-log: +It adds a interesting idea that the command you enter is in color and also +provides terminal history before the command returns.

  • +
  • Simple: The simple way is PROMPT_COMMAND="history -a" and then +tail -f -n0 ~/.bash_history, but this doesn’t capture ssh, +sub-shells, and only shows the command after it is completed.

  • +
  • Better yet still simple: Many Software Carpentry instructors use +this script, +which sets the prompt, splits the terminal window using tmux and displays command history +in the upper panel. Requirement: tmux

  • +
  • Better (bash): This prints the output before the command is run, +instead of after. Tail with tail -f ~/demos.out.

    +
    BASH_LOG=~/demos.out
    +bash_log_commands () {
    +    # https://superuser.com/questions/175799
    +    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    +    [[ "$PROMPT_COMMAND" =~ "$BASH_COMMAND" ]] && return # don't cause a preexec for $PROMPT_COMMAND
    +    local this_command=`HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"`;
    +    echo "$this_command" >> "$BASH_LOG"
    +}
    +trap 'bash_log_commands' DEBUG
    +
    +
    +
  • +
  • Better (zsh): This works like above, with zsh. Tail with tail -f ~/demos.out.

    +
    preexec() { echo $1 >> ~/demos.out }
    +
    +
    +
  • +
  • Better (fish): This works like above, but for fish. Tail with +tail -f ~/demos.out.

    +
    function cmd_log --on-event fish_preexec ; echo "$argv" >> ~/demos.out  ; end
    +
    +
    +
  • +
  • Better (tmuxp): This will save some typing. +TmuxP is a Python program (pip install tmuxp) that gives you programmable tmux sessions. One configuration that +works (in this case for fish shell):

    +
    session_name: demo
    +windows:
    +  - window_name: demo
    +    layout: main-horizontal
    +    options:
    +      main-pane-height: 7
    +    panes:
    +      - shell_command:
    +          - touch /tmp/demo.history
    +          - tail -f /tmp/demo.history
    +      - shell_command:
    +          - function cmd_log --on-event fish_preexec ; echo "$argv" >> /tmp/demo.history  ; end
    +
    +
    +
  • +
  • Windows PowerShell: In Windows Terminal, +a split can be made by pressing CTRL+SHIFT+=. Then, in one of the splits, the following +PowerShell command will start tracking the shell history:

    +
    Get-Content (Get-PSReadlineOption).HistorySavePath -Wait
    +
    +
    +

    Unfortunately, this only shows commands after they have been executed.

    +
  • +
  • Tavatar: shell history mirroring teaching tool can copy recent history to a remote server.

  • +
  • history-window: Show command +history “picture-in-picture” when teaching command line. Requires Bash.

  • +
+
+
+

Font, colors, and prompt

+
+

Terminal color schemes

+
    +
  • Dark text on light background, not dark theme. Research and our +experience says that dark-text-on-light is better in some cases and +similar in others.

  • +
  • You might want to make the background light grey, to avoid +over-saturating people’s eyes and provide some contrast to the pure +white web browser. (this was an accessibility recommendation when +looking for ideal color schemes)

  • +
  • Do you have any yellows or reds in your prompt or program outputs? +Adjust colors if possible.

  • +
+
+
+

Font size

+
    +
  • Font should be large (a separate history terminal can have a smaller +font).

  • +
  • Be prepared to resize the terminal and font as needed. Find out +the keyboard shortcuts to do this since you will need it.

  • +
+
+
+

Prompt

+

At the beginning of the workshop your goal is to have a shell +as easy to follow as possible and as close to what learners will +see on their screens:

+
    +
  • Your prompt should be minimal: few distractions, and not take up many +columns of text.

  • +
  • prompt-log does +this for you.

  • +
  • The minimum to do is is export PS1='\$ '.

  • +
  • Blank line between entries: export PS1='\n\$ '.

  • +
  • Have a space after the $ or % or whatever prompt character you +use.

  • +
  • Strongly consider the Bash shell. This is what most new people will +use, and Bash will be less confusing to them.

  • +
  • Eliminate menu bars and any other decoration that uses valuable +screen space.

  • +
  • Add colors only if it simplifies the reading of the prompt.

  • +
+

Later in the workshop or in more advanced lessons:

+
    +
  • Using other shells and being more adventurous is OK - learners will +know what is essential to the terminal and what is extra for your +environment.

  • +
+

Try to find a good balance between:

+
    +
  • Showing a simple setup and showing a more realistic setup.

  • +
  • Showing a consistent setup among all instructors and showing a +variety of setups.

  • +
+
+
+
+

Habits we need to un-learn

+
    +
  • Do not clear the terminal. Un-learn CTRL-L or clear if possible. +More people will wonder what +just got lost than are helped by seeing a blank screen. Push +ENTER a few times instead to add some white space.

  • +
  • Do not rapidly switch between windows or navigate quickly between multiple +terminals, browser tabs, etc. This is useful during your own work when nobody +is watching, but it is very hard to follow for learners.

  • +
  • Avoid using aliases or shortcuts that are not part of the +standard setup. Learners probably don’t have them, and they will fail +if they try to follow your typing. Consider even to rename corresponding +files (.bashrc, .gitconfig, .ssh/config, .ssh/authorized_keys, .conda/*).

  • +
  • Be careful about using tab completion or reverse history search if these +haven’t been introduced yet.

  • +
+
+
+

Desktop environment and browser

+
    +
  • Try to remove window title bars if they take up lots of space +without adding value to the learner.

  • +
  • Can you easily resize your windows for adjusting during teaching?

  • +
  • Does your web browser have a way to reduce its menu bars and other +decoration size?

    +
      +
    • Firefox-based browsers: go to about:config and set +layout.css.devPixelsPerPx to a value slightly smaller than one, +like 0.75. Be careful you don’t set it too small or large since +it might be hard to recover! When you set it to something smaller +than 1, all window decorations become smaller, and you compensate +by zooming in on the website more (you can set the default zoom to +be greater than 100% to compensate). Overall, you get more +information and less distraction.

    • +
    +
  • +
+
+
+

How to switch between teaching setup and work setup?

+
    +
  • Make a dedicated “demos” profile in your terminal emulator, if +relevant. Or use a different terminal emulator just for demos.

  • +
  • Same idea for the browser: Consider using a different browser profile for +teaching/demos.

  • +
  • Another idea is to containerize the setup for teaching. +We might demonstrate this during the Sharing teaching gems session later.

  • +
+
+
+

Keypoints

+
    +
  • Share portrait layout instead of sharing entire screen

  • +
  • Adjust your prompt to make commands easy to read

  • +
  • Readability and beauty is important: adjust your setup for your audience

  • +
  • Share the history of your commands

  • +
  • Get set up a few days in advance and get feedback from someone else. +Feedback and time to improve is very important to make things clear and accessible. +10 minutes before the session starts is typically too late.

  • +
+
+
+
+

Exercises

+
+

Evaluate screen captures (20 min)

+

Evaluate screenshots on this page. Discuss the trade-offs of each one. Which +one do you prefer? Which are useful in each situation?

+

Please take notes in the collaborative document.

+
+
+

Set up your own environment (20 min)

+

Set up your screen to teach something. Get some feedback from another learner +or your exercise group.

+
+
+
+

Other resources

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/search/index.html b/branch/cff/search/index.html new file mode 100644 index 0000000..7c5bc18 --- /dev/null +++ b/branch/cff/search/index.html @@ -0,0 +1,184 @@ + + + + + + Search — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/branch/cff/searchindex.js b/branch/cff/searchindex.js new file mode 100644 index 0000000..bc5ad39 --- /dev/null +++ b/branch/cff/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {":calendar: Schedule": [[10, "calendar-schedule"], [10, "id1"], [10, "id9"], [10, "id17"]], ":icecream: Icebreaker": [[10, "icecream-icebreaker"], [10, "id2"], [10, "id10"], [10, "id18"]], ":question: Questions": [[10, "question-questions"], [10, "id5"], [10, "id13"], [10, "id21"]], "A workshop seen from different perspectives": [[13, null]], "About teaching": [[10, "about-teaching"]], "About the CodeRefinery project and CodeRefinery workshops in general": [[1, null]], "Accepting the smallest contribution": [[9, "discussion-0"]], "After the workshop": [[13, "after-the-workshop"]], "All CodeRefinery lessons are on GitHub": [[8, "discussion-0"]], "Alternatives": [[17, "alternatives"]], "Are there any downsides?": [[0, "are-there-any-downsides"]], "Asking questions": [[2, "asking-questions"]], "Asking questions before the workshop": [[5, "asking-questions-before-the-workshop"]], "August/September 2024": [[10, "august-september-2024"]], "August/September 2024 CodeRefinery train the trainer workshop": [[7, null]], "Balancing and dynamic adjustment": [[16, "balancing-and-dynamic-adjustment"]], "Basic controls": [[2, "basic-controls"]], "Before the workshop": [[2, "before-the-workshop"], [13, "before-the-workshop"]], "Behind the stream": [[10, "behind-the-stream"], [17, null]], "Benefits and disadvantages": [[21, "benefits-and-disadvantages"]], "Best classroom experiences": [[10, "best-classroom-experiences"]], "Better approach": [[8, "better-approach"]], "Bj\u00f8rn Lindi": [[19, "exercise-1"]], "Breakout Room exercise": [[10, "breakout-room-exercise"]], "Carpentries audience": [[1, "carpentries-audience"]], "Challenges related to defining our target audience": [[1, "discussion-1"]], "Check-in": [[10, "check-in"], [10, "id3"], [10, "id11"], [10, "id19"]], "Co-teaching": [[0, null], [0, null]], "Co-teaching and team teaching benefits": [[0, "co-teaching-and-team-teaching-benefits"]], "CodeRefinery OBS configs": [[12, "coderefinery-obs-configs"]], "CodeRefinery audience": [[1, "coderefinery-audience"]], "CodeRefinery control panel": [[17, "coderefinery-control-panel"]], "CodeRefinery lesson template": [[9, "coderefinery-lesson-template"]], "CodeRefinery teaching philosophies": [[19, null]], "Collaborative Document Manager": [[2, "collaborative-document-manager"]], "Collaborative document format example": [[2, "collaborative-document-format-example"]], "Collaborative document mechanics and controls": [[2, "collaborative-document-mechanics-and-controls"]], "Collaborative notes": [[2, null]], "Collaborative notes archives from workshops": [[10, null]], "Collecting feedback as we teach": [[5, "collecting-feedback-as-we-teach"]], "Community": [[1, "community"]], "Competent practitioners": [[1, null]], "Computational thinking": [[3, null]], "Creating new teaching material": [[8, "creating-new-teaching-material"]], "Day 2 : Session 2 (20.08.24)- Tools and techniques adopted in CodeRefinery workshops": [[10, "day-2-session-2-20-08-24-tools-and-techniques-adopted-in-coderefinery-workshops"]], "Day 3 : sessiion 3 (27.08.24) - \u201cAbout teaching and cool things we all would like to share\u201d": [[10, "day-3-sessiion-3-27-08-24-about-teaching-and-cool-things-we-all-would-like-to-share"]], "Day1: Session 1 (13.08.24) - About lesson design, deployment and iterative improvement": [[10, "day1-session-1-13-08-24-about-lesson-design-deployment-and-iterative-improvement"]], "Day4: Session 4 (3.09.24) - Streaming and video editing": [[10, "day4-session-4-3-09-24-streaming-and-video-editing"]], "Desktop environment and browser": [[14, "desktop-environment-and-browser"]], "Different roles as stepping stones for community involvement": [[13, "different-roles-as-stepping-stones-for-community-involvement"]], "Discuss how to collaborate and handle questions (15 min)": [[2, "exercise-0"]], "Discuss the models of team teaching (10 min)": [[0, "exercise-0"]], "Discussion": [[13, "discussion"], [13, "discussion-0"]], "Discussion: how to distribute this?": [[20, null]], "Discussion: what makes a video easy to edit?": [[20, null]], "Don\u2019t get overwhelmed": [[2, "don-t-get-overwhelmed"]], "During the workshop": [[13, "during-the-workshop"]], "Editing-1: Get your sample video": [[20, "exercise-1"]], "Editing-2: Run Whisper to generate raw subtitles and test video.": [[20, "exercise-0"]], "Editing-3: Create the basic editlist.yaml file": [[20, "exercise-2"]], "Editing-4: Run ffmpeg-editlist": [[20, "exercise-3"]], "Editing-5: Add more features": [[20, "exercise-4"]], "Editing-6: Subtitles": [[20, "exercise-5"], [20, "exercise-6"]], "Editing-7: Generate the final output file.": [[20, "exercise-7"]], "Episode 1 : Computational thinking": [[10, "episode-1-computational-thinking"]], "Episode 1: CodeRefinery": [[10, "episode-1-coderefinery"]], "Episode 1: Lesson design and development": [[10, "episode-1-lesson-design-and-development"]], "Episode 2 : Teaching philosophies": [[10, "episode-2-teaching-philosophies"]], "Episode 2: Collaborative Notes": [[10, "episode-2-collaborative-notes"]], "Episode 2: Lessons with version control": [[10, "episode-2-lessons-with-version-control"]], "Episode 3: Co-teaching": [[10, "episode-3-co-teaching"]], "Episode 3: How we collect feedback and measure impact": [[10, "episode-3-how-we-collect-feedback-and-measure-impact"]], "Episode 3: One workshop, many perspectives": [[10, "episode-3-one-workshop-many-perspectives"]], "Episode 4: Sound": [[10, "episode-4-sound"]], "Episode 5: How to prepare a quality screen-share": [[10, "episode-5-how-to-prepare-a-quality-screen-share"]], "Evaluate screen captures (20 min)": [[14, "exercise-0"]], "Example 1": [[5, "example-1"]], "Example 2": [[5, "example-2"]], "Example 3": [[5, "example-3"]], "Example 4": [[5, "example-4"]], "Exercise": [[0, "exercise"], [2, "exercise"]], "Exercise A": [[20, "exercise-a"]], "Exercise B": [[20, "exercise-b"]], "Exercise questions to discuss": [[10, "exercise-questions-to-discuss"]], "Exercise: Discussion about learning objectives and exercise design": [[8, "exercise-discussion-about-learning-objectives-and-exercise-design"]], "Exercise: Group discussion (10 min)": [[5, "exercise-group-discussion-10-min"]], "Exercise: How do you design your teaching material?": [[8, "exercise-how-do-you-design-your-teaching-material"]], "Exercises": [[9, "exercises"], [14, "exercises"], [16, "exercises"], [20, "exercises"]], "Feedback about todays session": [[10, "feedback-about-todays-session"], [10, "id8"], [10, "id16"], [10, "id23"]], "Feedback template": [[2, "feedback-template"]], "Font size": [[14, "font-size"]], "Font, colors, and prompt": [[14, "font-colors-and-prompt"]], "Future prospects (briefly)": [[21, "future-prospects-briefly"]], "General / Practicalities": [[10, "general-practicalities"], [10, "id6"], [10, "id14"]], "General Collaborative Document practices": [[2, "general-collaborative-document-practices"]], "Getting it set up": [[17, "getting-it-set-up"]], "Goals": [[1, "goals"]], "Great resources": [[8, "great-resources"]], "Group discussion using the collaborative notes": [[5, "exercise-0"]], "Guide and demo-giver": [[0, "guide-and-demo-giver"]], "Habits we need to un-learn": [[14, "habits-we-need-to-un-learn"]], "Hardware requirements": [[11, "hardware-requirements"]], "History": [[1, "discussion-0"], [21, "history"]], "How did we get to this setup?": [[13, "how-did-we-get-to-this-setup"]], "How scenes are controlled": [[17, "how-scenes-are-controlled"]], "How this relates to streaming": [[20, "how-this-relates-to-streaming"]], "How to configure history sharing": [[14, "how-to-configure-history-sharing"]], "How to prepare a quality screen-share": [[14, null]], "How to switch between teaching setup and work setup?": [[14, "how-to-switch-between-teaching-setup-and-work-setup"]], "How we collect feedback and measure impact": [[5, null]], "How we do it": [[20, "how-we-do-it"]], "Ice-breaker in groups (20 minutes)": [[19, "exercise-0"]], "Icebreaker questions": [[21, "icebreaker-questions"]], "Improving existing lessons": [[8, "improving-existing-lessons"]], "Individual learner journey": [[13, "individual-learner-journey"]], "Initial setup": [[12, "initial-setup"]], "Installing the OBS config": [[12, "installing-the-obs-config"]], "Instructor guide": [[6, null]], "Instructor journey": [[13, "instructor-journey"]], "Instructor note": [[0, "instructor-note-0"], [2, "instructor-note-0"], [3, "instructor-note-0"], [4, "instructor-note-0"], [5, "instructor-note-0"], [8, "instructor-note-0"], [9, "instructor-note-0"], [11, "instructor-note-0"], [12, "instructor-note-0"], [13, "instructor-note-0"], [14, "instructor-note-0"], [16, "instructor-note-0"], [17, "instructor-note-0"], [18, "instructor-note-0"], [19, "instructor-note-0"], [20, "instructor-note-0"], [21, "instructor-note-0"]], "Instructor perspective": [[14, "instructor-perspective"]], "Instructor views": [[19, "instructor-views"]], "Instructors go through the building and contributing process": [[9, "demo-0"]], "Introduction": [[2, "introduction"], [19, "introduction"]], "Introduction in breakoutrooms": [[10, "id4"], [10, "id12"], [10, "id20"]], "Introduction in breakoutrooms.": [[10, "introduction-in-breakoutrooms"]], "Keypoints": [[0, "keypoints-0"], [2, "keypoints-0"], [3, "keypoints-0"], [9, "keypoints-0"], [11, "keypoints-0"], [12, "keypoints-0"], [13, "keypoints-0"], [14, "keypoints-0"], [16, "keypoints-0"], [17, "keypoints-0"], [18, "keypoints-0"], [19, "keypoints-0"], [20, "keypoints-0"], [21, "keypoints-0"]], "Keypoints: CodeRefinery": [[1, "keypoints-0"]], "Learner perspective": [[14, "learner-perspective"]], "Lesson design and development": [[8, null]], "Lesson-VCS-1: Present and discuss your own lesson formats": [[9, "exercise-0"]], "Lesson-VCS-2: Tour a CodeRefinery or Carpentries lesson on Github": [[9, "exercise-1"]], "Lesson-VCS-3: Modify a CodeRefinery example lesson on Github": [[9, "exercise-2"]], "Lesson-VCS-4: Clone and build a CodeRefinery lesson locally": [[9, "exercise-3"]], "Lesson-VCS-5: (advanced) Create your own lesson using the CodeRefinery format": [[9, "exercise-4"]], "Lessons learned": [[5, "lessons-learned"]], "Lessons with version control": [[9, null]], "Most things to edit (everyone)": [[2, "most-things-to-edit-everyone"]], "Novices": [[1, null]], "OBS during a course": [[11, "obs-during-a-course"]], "OBS user interface": [[11, "obs-user-interface"]], "Objectives": [[0, "objectives-0"], [1, "objectives-0"], [2, "objectives-0"], [3, "objectives-0"], [4, "objectives-0"], [5, "objectives-0"], [8, "objectives-0"], [9, "objectives-0"], [11, "objectives-0"], [12, "objectives-0"], [13, "objectives-0"], [14, "objectives-0"], [16, "objectives-0"], [17, "objectives-0"], [18, "objectives-0"], [19, "objectives-0"], [20, "objectives-0"], [21, "objectives-0"]], "One workshop - many parts": [[13, "one-workshop-many-parts"]], "Open Broadcaster Software (OBS) introduction": [[11, null]], "Open Broadcaster Software (OBS) introduction & setup": [[10, "open-broadcaster-software-obs-introduction-setup"]], "Open Broadcaster Software (OBS) setup": [[12, null]], "Other resources": [[14, "other-resources"]], "Other roles": [[13, "other-roles"]], "Overview": [[0, "overview"]], "Poll": [[10, "poll"]], "Posting the collaborative document to the website": [[2, "posting-the-collaborative-document-to-the-website"]], "Presenter and interviewer": [[0, "presenter-and-interviewer"]], "Primary articles": [[20, "primary-articles"]], "Privacy": [[2, "privacy"]], "Prompt": [[14, "prompt"]], "Q&A": [[11, "q-a"], [12, "q-a"], [17, "q-a"], [21, "q-a"]], "Questions": [[10, "questions"]], "Questions from the audience": [[10, "questions-from-the-audience"]], "Questions to audience": [[10, "questions-to-audience"]], "Radovan Bast": [[19, "exercise-2"]], "Recommendations": [[16, "recommendations"]], "Resources": [[7, null]], "Richard Darst": [[19, "exercise-4"]], "Sabry Razick": [[19, "exercise-3"]], "See also": [[11, "see-also"], [18, "see-also"], [20, "see-also"]], "Session 1": [[7, null]], "Session 2": [[7, null]], "Session 3": [[7, null]], "Session 4": [[7, null]], "Session 4 intro": [[15, null]], "Set up the remote control": [[12, "set-up-the-remote-control"]], "Set up your own environment (20 min)": [[14, "exercise-1"]], "Setup before each course": [[12, "setup-before-each-course"]], "Share portrait layout instead of sharing entire screen when teaching online": [[14, "share-portrait-layout-instead-of-sharing-entire-screen-when-teaching-online"]], "Share the history of your commands": [[14, "share-the-history-of-your-commands"]], "Sharing teaching gems": [[4, null]], "Solution": [[20, "solution-0"], [20, "solution-1"], [20, "solution-2"], [20, "solution-3"], [20, "solution-4"], [20, "solution-5"]], "Sound": [[16, null]], "Sound-1: Evaluate sound quality": [[16, "exercise-0"]], "Sound-2: Adjust volume up and down": [[16, "exercise-1"]], "Sound-3: Do a balance check": [[16, "exercise-2"]], "Speak up when there are problems": [[16, "speak-up-when-there-are-problems"]], "Sphinx": [[9, "sphinx"]], "Stepas Toliautas": [[19, "exercise-5"]], "Summary": [[0, "summary"], [9, "summary"], [16, "summary"], [19, "summary"], [20, "summary"]], "Take time designing your survey": [[5, "take-time-designing-your-survey"]], "Target audience": [[1, "target-audience"], [6, "target-audience"]], "Teaching": [[10, "teaching"]], "Teaching gems": [[10, "teaching-gems"]], "Team lead / Local host journey": [[13, "team-lead-local-host-journey"]], "Team teaching models": [[0, "team-teaching-models"]], "Team teaching specifics": [[0, "team-teaching-specifics"]], "Terminal color schemes": [[14, "terminal-color-schemes"]], "The importance of audio": [[16, "the-importance-of-audio"]], "The instructor will go through the setup.": [[12, "demo-0"]], "The process of designing a lesson \u201cbackwards\u201d": [[8, "the-process-of-designing-a-lesson-backwards"]], "This sounds like a lot of people and time investment!": [[13, "this-sounds-like-a-lot-of-people-and-time-investment"]], "Timing": [[6, "timing"]], "Tips for good sound quality": [[16, "tips-for-good-sound-quality"]], "Tour of lesson templates options": [[9, "tour-of-lesson-templates-options"]], "Train the trainer workshop": [[7, null]], "Trying to measure impact with longer-term surveys": [[5, "trying-to-measure-impact-with-longer-term-surveys"]], "Typical problems": [[8, "typical-problems"]], "Use case: our lessons": [[8, "use-case-our-lessons"]], "Use ffmpeg-editlist to edit this sample video": [[20, "exercise-8"]], "Video editing": [[10, "video-editing"], [20, null]], "Video recordings": [[19, "prerequisites-0"]], "We collect notes using a shared document (5 min)": [[8, "exercise-0"]], "We work in groups but use the shared document as result (20 min)": [[8, "exercise-1"]], "What can go wrong": [[17, "what-can-go-wrong"]], "What is OBS?": [[11, "what-is-obs"]], "What is streaming and recording?": [[21, "what-is-streaming-and-recording"]], "What\u2019s next?": [[18, null]], "Who does what": [[17, "who-does-what"]], "Why version control?": [[9, "why-version-control"]], "Why we stream": [[10, "why-we-stream"], [21, null]], "Window layouts": [[17, "window-layouts"]], "Workshop roles and their journeys": [[13, "workshop-roles-and-their-journeys"]], "Wrapup": [[10, "wrapup"], [10, "id7"], [10, "id15"], [10, "id22"]]}, "docnames": ["co-teaching", "coderefinery-intro", "collaborative-notes", "computational-thinking", "cool-gems", "feedback-and-impact", "guide", "index", "lesson-development", "lessons-with-git", "notes-archive", "obs", "obs-config", "overview", "screenshare", "session-4-intro", "sound", "streaming", "streaming-whats-next", "teaching-philosophies", "video-editing", "why-we-stream"], "envversion": {"sphinx": 62, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["co-teaching.md", "coderefinery-intro.md", "collaborative-notes.md", "computational-thinking.md", "cool-gems.md", "feedback-and-impact.md", "guide.md", "index.md", "lesson-development.md", "lessons-with-git.md", "notes-archive.md", "obs.md", "obs-config.md", "overview.md", "screenshare.md", "session-4-intro.md", "sound.md", "streaming.md", "streaming-whats-next.md", "teaching-philosophies.md", "video-editing.md", "why-we-stream.md"], "indexentries": {}, "objects": {}, "objnames": {}, "objtypes": {}, "terms": {"": [0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 19, 20], "0": [10, 14, 21], "00": [10, 20], "01": 2, "02": 10, "02_at_09": 10, "03": [5, 20], "03308595436e636b3bb37ed9d1f0dee39eeccd0f": 10, "04": 20, "05": [10, 20], "07": 20, "08": 5, "1": [2, 6, 14, 21], "10": [2, 3, 6, 10, 14, 16, 17, 19, 20, 21], "100": [10, 11, 14, 16, 21], "1080": 14, "11": [10, 20], "12": [5, 10, 20], "128": 10, "13": 7, "13292363": 5, "13th": 7, "14": 10, "148421550": 10, "15": [0, 6, 10, 11, 13, 14, 20], "16": 20, "17": 10, "175799": 14, "180": 19, "18640868": 10, "19": 10, "1920x1080": 14, "1d": 10, "2": [2, 6, 8, 13], "20": [2, 3, 5, 6, 7, 9, 13, 17, 20], "200": 10, "2014": [1, 8], "2015": [1, 8], "2016": [1, 8, 13], "2017": 8, "2019": 8, "2020": 13, "202024": 10, "2021": 5, "2022": [1, 8], "2023": 20, "2024": [5, 8, 15], "2025": 1, "20coderefineri": 10, "20workshop": 10, "21": 10, "23": 10, "24": 20, "25": [6, 9, 10, 20], "25mbit": 11, "26": 10, "2671576": 5, "2671578": 5, "27": 7, "2k45bftw4sbmlbfjr1oz90": 10, "3": [1, 2, 4, 6, 8, 13, 21], "30": [6, 10], "300": [10, 16], "31": 20, "316508": 10, "35": [4, 6, 8, 10, 20], "37": 20, "39": 10, "3rd": [7, 10], "4": [2, 3, 6, 13, 14], "40": 10, "404": 10, "43": 20, "4445": 12, "45": [2, 6, 10, 19, 20], "5": [0, 2, 5, 11, 13, 16, 18, 21], "50": [10, 20], "500m": 16, "5281": 5, "55": 10, "5c6ecd3628a43b0cdc79815f665e224a": 10, "6": 10, "612x612": 10, "64gb": 11, "7": [10, 14], "75": 14, "7b": 10, "7b7ec4b91d2cf9d8e1b064678d205467": 10, "7e": 10, "7nhx": 19, "8": [10, 11], "80": 10, "840": 14, "9": [10, 14], "90": 8, "9781119861690": 10, "A": [1, 2, 7, 8, 10, 14, 18, 19], "And": [2, 10, 16, 19, 20], "As": [2, 8, 10, 15, 16, 20], "At": [2, 14], "BY": 8, "Be": [2, 10, 14, 16, 20], "Being": 10, "But": [2, 8, 10, 16, 19], "By": [1, 10, 20], "For": [0, 1, 2, 8, 9, 10, 13, 19, 20, 21], "If": [2, 7, 8, 9, 10, 13, 15, 16, 19, 20], "In": [0, 1, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21], "It": [0, 1, 2, 8, 9, 10, 14, 15, 16, 17, 19, 20], "NO": 10, "NOT": 10, "No": [5, 10, 13, 20, 21], "Not": [0, 5, 8, 10, 17], "One": [0, 1, 2, 5, 14, 16, 17], "Or": [2, 9, 10, 14], "That": [10, 11, 19], "The": [0, 1, 2, 5, 7, 9, 10, 11, 13, 14, 15, 17, 19, 20, 21], "Then": [10, 14], "There": [1, 2, 9, 10, 12, 13, 15, 17, 20, 21], "These": [10, 12, 15, 16, 18, 20, 21], "To": [10, 20], "Will": 10, "With": [10, 16, 19], "_build": 9, "_cobn": 20, "aaa": 16, "aalto": [10, 20], "aaltoscicomp": 20, "aau": 10, "abl": [2, 8, 10, 16, 19, 20], "about": [0, 2, 5, 6, 7, 9, 11, 13, 14, 15, 17, 18, 19, 20, 21], "abov": [2, 5, 10, 14, 20], "abraham": 10, "absenc": 10, "absolut": 10, "abstract": [3, 10], "academ": [1, 10, 19], "academi": 10, "accept": [1, 10], "access": [8, 10, 14, 20], "accid": 20, "accident": 0, "accomd": 10, "accompani": 8, "accomplish": [2, 10], "account": [2, 9, 10], "accur": 20, "achiev": [5, 10, 16, 19], "achiv": 10, "acoust": [10, 16], "acquiesc": [5, 10], "across": 10, "act": 10, "action": [5, 10], "activ": [0, 1, 8, 10, 15], "actual": [0, 1, 5, 8, 10, 19, 20, 21], "ad": [2, 10, 14], "adapt": [0, 10], "add": [0, 2, 5, 9, 10, 13, 14], "addit": [0, 10, 13, 16, 19], "address": [1, 10], "adjust": [0, 2, 10, 11, 13, 14, 17, 20], "adopt": 7, "advanc": [0, 2, 10, 14], "advantag": [8, 10], "advent": 10, "adventur": 14, "advertis": 13, "advertiz": 13, "advic": 10, "advoc": [8, 10, 20], "affili": 10, "africa": 10, "after": [2, 5, 9, 10, 14, 16, 19, 20], "afternoon": 8, "afterward": [2, 10, 19], "aftwerward": 10, "against": 10, "agil": [10, 19], "ago": [10, 19], "agre": [0, 2, 10], "ah": 10, "aha": 19, "ahead": 10, "ai": 10, "aim": [1, 7, 10, 19], "airwav": 10, "al": 10, "albert": 10, "algorithm": [3, 10], "alias": 14, "align": 20, "all": [0, 1, 2, 5, 7, 9, 13, 14, 16, 17, 19, 20, 21], "alloc": 10, "allow": [0, 2, 8, 9, 10, 14, 19, 20, 21], "almost": [10, 14, 19], "alon": [2, 10, 13], "along": [2, 10, 19, 20], "alreadi": [0, 1, 5, 8, 10, 19], "alredi": 10, "also": [0, 1, 2, 7, 8, 9, 10, 13, 14, 15, 16, 17, 19], "altern": [0, 2, 9, 10], "alternativeto": 10, "although": 10, "alwai": [1, 2, 8, 10, 13, 19], "am": [8, 10, 16, 19], "amazingli": 8, "ambassador": 1, "ambros": 10, "amd": [10, 11], "among": [10, 14, 16], "amount": [2, 10], "amus": 10, "an": [0, 1, 2, 5, 7, 8, 10, 14, 15, 16, 17, 19, 20], "analogi": 10, "analysi": 10, "analyz": 8, "ani": [1, 2, 5, 7, 10, 14, 16, 19, 20], "annoi": 10, "annot": 10, "anomali": 15, "anonym": [5, 10], "anonymis": 10, "anoth": [0, 8, 10, 14], "answer": [2, 5, 8, 10, 11, 12, 13, 19], "anticip": [0, 10], "anwser": 2, "anxieti": 10, "anybodi": [5, 10], "anymor": 19, "anyon": [2, 10, 13, 14, 20], "anyth": [2, 5, 9, 10, 12, 17, 20, 21], "anywai": 10, "anywher": 9, "apart": 10, "apetit": 10, "api": 9, "aposteriori": 10, "app": 10, "appear": [10, 19, 20], "apper": 10, "appic": 13, "appli": [0, 1, 8, 10, 13, 20], "applic": [0, 10, 11, 12, 13, 17, 19], "apprecentiship": 10, "appreci": [10, 19], "apprici": 10, "approach": [0, 1, 10, 19], "appropri": 10, "approxim": 10, "apriori": 10, "ar": [1, 2, 5, 7, 9, 10, 12, 13, 14, 15, 19, 20, 21], "archiv": [2, 7, 12, 13], "area": [0, 1, 10, 20], "aren": [2, 10, 16, 20], "argument": 10, "argv": 14, "aronud": 10, "around": [10, 13], "arrang": 2, "art": 10, "arthur": 10, "articl": 10, "artifact": 16, "asc": 20, "asid": 10, "ask": [0, 8, 9, 10, 13, 15, 16, 19], "asleep": 10, "aspect": [10, 13], "assess": [0, 8], "assign": 10, "assist": 10, "assum": [1, 2, 5, 9, 10], "assur": 10, "asymptot": 10, "async": 21, "attempt": 9, "attend": [5, 8, 10, 20], "attent": [0, 10], "audibl": 10, "audienc": [0, 5, 7, 8, 11, 12, 14, 16, 17, 19, 20, 21], "audio": [7, 10, 11, 12, 15, 20], "aug": 7, "authorized_kei": 14, "auto": 10, "autom": 8, "automat": [2, 10], "av": 10, "avail": [0, 3, 5, 9, 10, 13, 16, 19, 20], "avm": 10, "avoid": [1, 2, 5, 10, 14, 19], "awai": [2, 10, 16, 17], "awar": [1, 10, 19], "awkward": 0, "b": 10, "bachelor": 10, "back": [2, 8, 10, 19, 20], "background": [8, 10, 14, 16, 19], "backup": [2, 18], "backward": 10, "bad": [10, 16], "bake": 10, "balanc": [2, 5, 14], "band": 10, "bandwidth": 16, "bar": [10, 14], "barrier": [10, 13], "bascic": 10, "base": [1, 8, 9, 10, 13, 14, 17, 20], "baselin": 10, "bash": 14, "bash_command": 14, "bash_histori": 14, "bash_log": 14, "bash_log_command": 14, "bashrc": 14, "basic": [0, 8, 9, 10, 11, 15, 16, 19], "basisc": 10, "bast": 7, "bbb": 16, "beamer": 10, "bear": 10, "beast": 10, "beat": 16, "beauti": 14, "becam": 10, "becaus": [1, 5, 10, 14, 16, 19, 20], "becom": [0, 5, 7, 8, 10, 14, 19, 20], "been": [5, 8, 9, 10, 12, 13, 14, 16, 18, 19, 20], "befor": [1, 8, 10, 14, 19, 20], "beforehand": 10, "beggin": 10, "begin": [5, 10, 14, 19, 20], "beginn": 7, "behind": [2, 5, 6, 7, 13], "being": [0, 10, 14, 19], "belief": 10, "believ": 10, "bell": 10, "below": [0, 2, 5, 7, 9, 10, 13, 14, 16, 19, 20], "benefici": [1, 10, 19], "benefit": [9, 10, 20], "benjamin": 10, "besid": 10, "best": [0, 1, 13, 19], "better": [5, 10, 14, 19], "between": [0, 2, 7, 9, 10, 13, 19], "beyond": [1, 2, 16], "bia": [5, 10], "bias": 10, "biasi": 10, "big": [0, 8, 10, 21], "bigger": 5, "biggest": 10, "bill": 10, "bin": 10, "binari": 19, "binder": 10, "bioinformat": 10, "biolog": 10, "biologi": 10, "birdsey": 10, "bit": [10, 14, 16, 17, 19], "bj\u00f8rn": 7, "bl": 10, "black": [10, 20], "blackbox": 10, "blank": [2, 8, 14], "bleed": 10, "blob": [10, 19], "bloc": 10, "block": [8, 10, 19], "blog": [5, 8, 10], "bloom": [8, 10], "blow": 10, "blue": 10, "bluetooth": [10, 16], "blurb": 10, "board": 10, "bob": 10, "bomb": 10, "bombard": 10, "book": [8, 9, 10], "bookshop": 10, "bore": [10, 15], "bot": 10, "both": [10, 14, 19], "bother": 10, "bottom": [2, 5, 10, 14], "bound": 10, "box": [9, 10], "br": 10, "brain": 10, "brainstorm": [8, 10], "branch": [8, 10], "brand": 10, "bravo": 10, "bread": 10, "break": [2, 6, 10, 16, 17, 19, 20], "breaker": 10, "breakfast": 10, "breakout": [0, 2, 20], "breakoutroom": [7, 13, 19], "breakthrough": 10, "breath": 10, "bridl": 10, "bring": [2, 8, 10, 13, 16], "broad": 10, "broadcast": [7, 13, 17], "broaden": 19, "broken": 10, "browser": [10, 19], "bst": 10, "budget": 20, "buffer": 10, "build": [1, 10], "built": [9, 10], "bullet": [2, 10, 19], "busi": [10, 19], "button": [10, 11], "byoc": 13, "c": 10, "c4": 10, "cake": 10, "calcul": 10, "call": [10, 16, 17], "came": [10, 16], "camera": [7, 10, 19], "can": [0, 1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 19, 20, 21], "cancel": [10, 16], "cannot": 10, "canon": 10, "capac": 10, "capic": 10, "captur": [5, 10, 11, 15], "care": [1, 14], "carpentri": [8, 10, 14, 19], "cartooni": 10, "case": [0, 1, 2, 10, 14, 19], "cat": 10, "catch": [0, 10, 14, 20], "cater": 10, "caus": 14, "caveat": 10, "cc": 8, "cell": 10, "center": 10, "centric": 19, "certain": [10, 17, 19, 21], "certainti": 10, "certif": 10, "cest": 10, "challeng": [10, 13], "chanc": [7, 10], "chang": [0, 2, 5, 8, 9, 10, 12, 17, 19], "channel": [1, 10], "chao": 0, "chaotic": [0, 10], "chapter": 20, "characht": 10, "charact": 14, "characterist": 10, "charg": 7, "charm": 10, "chat": [1, 2, 10, 13, 14, 16], "chatgpt": 10, "cheat": 10, "check": [2, 5, 19, 20], "checklist": [10, 12], "cheek": 10, "chemic": 10, "cherish": 10, "cherki": 10, "choic": [8, 10, 20], "choos": [8, 10, 13], "chose": 10, "chromium": 10, "chronolog": 10, "chubbi": 10, "chunk": 20, "cicero": [9, 10], "circl": 10, "circul": 10, "citabl": [5, 8], "clarifi": 10, "clariti": 16, "class": 19, "classic": [0, 10], "classroom": [0, 8, 13], "clean": [10, 13], "cleanli": 20, "clear": [0, 10, 14, 19, 20], "clearer": 10, "clearli": [10, 20], "cli": 10, "click": [9, 11, 12], "client": 10, "clipchamp": 10, "clock": 10, "clone": 12, "close": [2, 5, 7, 8, 14, 16], "closer": [0, 8], "cloud": 10, "clue": 10, "clutter": 10, "cm": 10, "cmd_log": 14, "co": [1, 6, 7, 13, 19], "coach": 10, "coc": 10, "cocktail": 10, "code": [1, 5, 8, 9, 10, 13, 20], "codeberg": 10, "coder": 10, "coderefineri": [0, 2, 5, 6, 11, 13, 14, 20, 21], "codewhisper": 10, "coffe": 10, "cognit": 10, "cohort": 10, "colab": 10, "collab": 10, "collabor": [0, 1, 6, 7, 8, 13, 14, 19], "collat": 10, "colleagu": [5, 8, 10], "collect": [6, 7, 12, 13, 19, 20], "color": [9, 10], "colour": 10, "column": 14, "com": [5, 8, 9, 10, 12, 14, 19, 20], "combin": [10, 13, 19, 20], "come": [2, 8, 10, 18, 19, 20], "comfort": 10, "command": [8, 9, 10, 20], "comment": [0, 1, 2, 5, 10], "commit": [9, 10], "common": [0, 1, 10, 19], "commonli": [10, 11], "commun": [2, 10, 21], "comp_lin": 14, "compani": 10, "compar": 10, "compel": 10, "compens": [14, 21], "compet": 10, "competit": 10, "compil": 10, "complement": [0, 19], "complet": [2, 8, 10, 14], "complex": 10, "complic": [10, 11, 12, 19], "compon": 10, "comprehens": 15, "compressor": 10, "compromis": 19, "comput": [1, 6, 7, 8, 9, 11, 19, 20], "con": 10, "concept": [0, 10, 19], "conceptu": [1, 10], "concern": 10, "conclus": [2, 10], "concucurr": 10, "conda": [8, 14], "condens": 10, "condition_on_previous_text": 20, "conduct": 10, "conf": 10, "confer": 21, "confid": [1, 19], "confident": 10, "config": [10, 11, 14], "configur": [11, 12], "confirm": [10, 12], "conflict": 10, "conform": 10, "confus": [10, 14, 19], "connect": [10, 11, 17], "conquer": 10, "consciou": 19, "consid": [2, 5, 10, 14, 16, 19], "consider": 10, "consist": [2, 3, 7, 9, 10, 14], "constant": [0, 10], "constantli": 10, "constel": 10, "construct": [8, 10, 16], "consum": 21, "contact": [10, 15], "contain": [7, 8, 9, 20], "container": [10, 14], "content": [0, 7, 9, 10, 13, 14, 19, 20], "context": [0, 2, 10, 19], "continu": [1, 10, 13], "continuum": 0, "contrast": 14, "contribut": [10, 13], "contributor": 1, "control": [0, 1, 7, 8, 11, 16], "convei": 19, "conveni": 10, "convent": 10, "convers": [0, 2], "convert": [5, 8, 10], "cook": 10, "cool": [7, 8], "coordin": [0, 10, 13, 14, 17, 21], "copi": [9, 14, 20], "core": 10, "correct": [10, 19], "correspond": [10, 14], "coteach": 10, "could": [0, 2, 8, 10, 17, 19, 20], "couldn": 10, "count": [10, 16], "countri": 1, "coupl": 10, "courag": 10, "cours": [0, 1, 2, 4, 5, 8, 9, 10, 14, 16, 17, 18, 20, 21], "cover": [8, 10, 12, 14, 15], "covid": [10, 21], "cph": 10, "cpu": [8, 10, 11], "cr": [2, 9, 10, 12], "creat": [0, 2, 7, 10, 12, 19], "creator": 1, "criteria": 10, "critic": 10, "crop": 10, "cross": [9, 11], "crowd": 10, "crowdsourc": 20, "crown": 10, "crucial": 10, "cry": 10, "csc": 10, "css": [10, 14], "ctfasset": 10, "ctrl": 14, "cube": 10, "cuda": 20, "cultur": [10, 16], "curios": 19, "curiou": [7, 10], "current": [1, 8, 10, 13, 20], "curriculum": 8, "curriculumn": 10, "cursor": 20, "curv": 10, "custom": [9, 10, 17, 19], "customis": 10, "cut": [10, 20], "cycl": 10, "d": [10, 19], "dai": [2, 5, 8, 13, 14, 20, 21], "daili": [8, 10, 13], "danger": 2, "dark": 14, "darst": 7, "darstr1": 20, "data": [2, 5, 8, 10, 20], "dataset": 10, "date": 10, "daunt": 10, "day1": 20, "deactiv": 10, "dead": 20, "deal": [2, 10], "debrief": 13, "debug": [8, 14], "decaf": 10, "decemb": 10, "decid": [9, 10, 16], "decis": 10, "declar": 2, "decomposit": 3, "decor": 14, "dedic": [0, 2, 9, 14], "deep": [2, 10], "deeper": 10, "deepli": 2, "default": [10, 14], "defin": [0, 8, 10, 20], "definit": [10, 17, 20], "degre": [10, 19], "delai": [2, 10], "delet": 12, "deliev": 10, "deliv": 10, "deliveri": 0, "demand": [2, 10], "demo": [2, 9, 10, 14, 15, 19, 20], "demonstr": [4, 8, 10, 14, 16, 18, 20], "demystifi": 19, "denni": 10, "depend": [2, 8, 9, 10, 20], "deploy": 7, "depth": [10, 13], "deriv": 9, "derse24": 10, "describ": [1, 8, 10, 13, 17], "descript": [10, 13, 20], "design": [1, 3, 6, 7, 9], "desir": [10, 20], "desk": 10, "desktop": 10, "destroi": 10, "detail": [0, 2, 7, 10, 17], "detect": 19, "determin": 10, "dev": 10, "devast": 10, "develop": [1, 5, 6, 7, 13, 19], "deviat": [0, 19], "devic": [2, 10, 16, 20], "devil": 10, "devpixelsperpx": 14, "dhanya": 7, "diagram": 19, "dictionari": 10, "did": [5, 10, 16, 19], "didn": [10, 20], "diff": 10, "differ": [0, 1, 2, 7, 9, 10, 14, 15, 16, 18, 19, 21], "difficult": [1, 5, 10, 19], "difficulti": [1, 21], "dig": 10, "digest": 10, "digit": 10, "dipietro": 10, "dir": 10, "direct": [1, 2, 8, 9, 10, 16, 17], "directli": [9, 17, 20], "director": [0, 10, 11, 13, 17], "directori": [9, 10, 14, 20], "disadvantag": 9, "disagre": 10, "disciplin": [1, 10], "disclaim": 20, "discov": 10, "discret": 1, "discuss": [1, 4, 14, 16, 19, 21], "disorganis": 10, "disori": 0, "displai": [2, 9, 10, 14], "dissoci": 5, "distanc": 10, "distil": [10, 19], "distinct": [10, 21], "distract": [2, 10, 14], "distribut": [10, 13], "divers": [8, 10], "divid": 10, "divis": [0, 10], "dli": 10, "dmp": 10, "dna": 10, "do": [0, 1, 2, 5, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 21], "doc": [2, 9, 10], "document": [0, 1, 5, 9, 10, 13, 14, 19], "doe": [0, 1, 5, 10, 11, 14, 16, 20], "doesn": [2, 9, 10, 14, 16], "doi": 5, "domain": 10, "don": [0, 5, 8, 9, 10, 14, 16, 17, 19, 20, 21], "done": [2, 7, 10, 12, 17, 19, 20, 21], "doubli": 19, "dough": 10, "down": [2, 8, 10, 11], "download": [2, 10, 20], "downsid": [10, 21], "dra": 10, "draft": [8, 10], "drag": 10, "draw": 10, "drawn": 10, "driven": 1, "drop": [0, 10, 13], "drown": 10, "drug": 10, "dry": 10, "dual": 14, "duck": 16, "due": [0, 10, 16], "durat": 2, "dure": [0, 2, 5, 8, 10, 14, 16, 17, 19], "dynam": 10, "e": [0, 1, 10, 13, 14, 17, 20], "each": [0, 2, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20], "ean": 10, "earli": [5, 8, 10], "earlier": [1, 5, 8, 10], "eas": 13, "easi": [2, 8, 9, 10, 11, 14, 19], "easier": [2, 5, 8, 9, 10, 14], "easiest": 10, "easili": [1, 2, 9, 10, 14, 19], "eat": 10, "echo": [10, 14], "edit": [6, 7, 9, 21], "editlist": 10, "editor": [2, 10, 20], "educ": [0, 8, 10], "edward": 10, "eest": 10, "effect": [5, 8, 10], "effici": 10, "effort": [10, 13, 19], "eg": [1, 10], "egg": 10, "eight": 10, "einstein": 10, "either": [0, 4, 9, 10, 16], "elabor": 10, "element": 10, "elimin": 14, "els": [2, 5, 8, 9, 10, 14, 16, 17, 20], "email": 10, "embrac": 19, "emoji": 10, "emot": 10, "emoticon": 10, "emphas": [9, 19], "emphasi": [8, 21], "emploi": 10, "empow": 10, "empti": [8, 10], "emul": 14, "en": [10, 20], "enabl": [2, 10], "encod": 20, "encompass": 10, "encourag": [4, 8, 10, 19], "end": [0, 2, 8, 10, 14, 16, 17, 19, 20], "energi": 2, "engag": [0, 7, 8, 10, 19, 21], "engin": 10, "english": 10, "enhanc": [7, 10], "enjoi": 10, "enjoy": [10, 16], "enough": [1, 8, 10, 20], "ensur": [0, 2, 10, 16], "enter": 14, "enthusiast": 10, "entiti": 10, "entri": [10, 14], "enviro": 10, "environ": [2, 8, 9, 10, 12, 13, 19, 20], "environemnt": 10, "epcc": 10, "episod": [2, 8, 11, 12, 13, 17, 19, 20], "epsisod": 10, "epub": 9, "equal": [2, 10, 20], "equip": [10, 16], "equival": 10, "erambl": 10, "error": [5, 10, 14, 19], "especi": [0, 10, 19, 20], "essenc": 19, "essenti": [8, 10, 13, 14], "est": 10, "estim": 10, "et": 10, "etc": [1, 2, 6, 7, 9, 10, 12, 13, 14, 16, 17, 20, 21], "etern": 5, "etherpad": 10, "europ": 10, "evalu": [8, 10], "even": [0, 2, 9, 10, 14, 16, 19, 20, 21], "event": [10, 13, 14, 16, 21], "eventu": 10, "ever": [10, 16], "everett": 10, "everi": [0, 2, 7, 9, 10, 14], "everybodi": 10, "everyon": [6, 7, 9, 10, 13, 16, 20], "everyth": [0, 9, 10, 12, 19, 20], "everytim": 10, "everywher": 10, "evolv": 1, "ex": 10, "exam": 10, "exampl": [0, 1, 8, 10, 14, 16, 19, 20], "exc": 10, "excalideck": 10, "excalidraw": 10, "excel": 10, "except": 10, "excercis": 10, "excerpt": 20, "exchang": [7, 10], "excit": [10, 16], "execut": [9, 10, 14], "exemplifi": 10, "exercic": 10, "exercis": [1, 3, 6, 13, 19, 21], "exhaust": 10, "exist": [1, 9, 10], "expand": 10, "expect": [5, 8, 10, 20], "expens": [10, 16], "experi": [1, 2, 5, 7, 13, 14, 19], "experienc": [0, 8, 19], "expert": [1, 5, 10, 13, 19], "explain": [0, 1, 3, 10, 19], "explan": [10, 17, 20], "explicit": 19, "explicitli": 10, "explor": 10, "explos": 10, "export": 14, "expos": 8, "express": [8, 10], "extant": 10, "extend": [9, 10], "extens": [8, 9, 10], "extern": [16, 20], "extra": [9, 10, 14], "extrapol": 10, "extrem": 16, "ey": [2, 14], "f": [10, 14], "face": 10, "facilit": [7, 13], "fact": [10, 19], "factor": [10, 20], "fail": [10, 14], "failur": 10, "fair": 10, "fairli": 10, "faith": 10, "fake": 10, "fall": 10, "fals": 20, "familiar": [10, 11], "fan": 10, "fanci": 10, "far": [5, 10], "fashion": 19, "fast": [2, 5, 10, 19, 20, 21], "faster": 10, "favor": 1, "favorit": [8, 10], "feasibl": 10, "featur": [9, 10, 11, 13], "featureless": 10, "februari": 1, "feedback": [0, 1, 6, 7, 8, 13, 14, 15, 19], "feel": [0, 1, 10, 13, 19, 21], "fell": 10, "fellow": [7, 10], "felt": [10, 19], "few": [2, 5, 10, 14, 19, 20], "ffmpeg": 10, "fi": [10, 20], "fidgit": 10, "field": [5, 10], "fiffer": 10, "figma": 10, "figur": [2, 5, 8, 10, 15, 16, 17], "fil": 10, "file": [9, 10, 14], "filesystem": 10, "fill": [0, 8, 10, 13], "final": 10, "find": [1, 2, 9, 10, 13, 14, 19, 20], "findabl": [8, 10], "fine": [9, 10], "fire": 10, "firefox": 14, "first": [0, 1, 2, 5, 8, 10, 15, 16, 17, 20], "fish": 14, "fish_preexec": 14, "fit": [0, 9, 10], "fix": [2, 5, 9, 10, 16, 20], "fl": 10, "flat": 10, "flexibl": 10, "flinga": 10, "flood": 2, "flow": [0, 2, 9, 10], "flowchat": 20, "fly": 10, "focu": [0, 2, 10, 14, 17, 21], "focus": [0, 10, 13, 21], "folder": 10, "folk": 10, "follow": [1, 2, 5, 8, 9, 10, 13, 14, 20], "font": [9, 10], "fool": 10, "forbidden": 10, "forc": 0, "forev": 10, "forget": [10, 20], "forgiv": 10, "fork": [9, 10], "form": [0, 1, 2, 5, 8, 10, 20, 21], "formal": [10, 11], "format": [1, 8, 10], "former": 10, "formul": 5, "fortun": 10, "forward": [0, 10], "foster": 10, "found": [4, 10], "four": [7, 10, 19, 20], "fragment": 9, "frame": [10, 20], "framework": [3, 10], "franklin": 10, "free": [1, 5, 7, 9, 10, 11, 14, 21], "freelanc": 10, "freir": 10, "frequenc": 10, "frequent": 10, "friend": 19, "friendli": [7, 10], "from": [0, 1, 2, 4, 5, 7, 8, 9, 11, 12, 14, 17, 19, 20, 21], "fruit": [7, 10], "frustrat": 10, "full": [10, 16, 20, 21], "fullhd": 14, "fulli": [1, 10, 19], "fun": [10, 19], "function": [9, 10, 14], "fund": 1, "funder": 5, "fuse": 0, "futur": [1, 5, 6, 7, 10, 19, 20], "g": [0, 10, 17, 20], "gain": 10, "game": 16, "gap": 0, "garbag": 10, "garbl": 20, "gatekeep": 10, "gather": 13, "gave": 18, "gcjexwc8cf": 19, "gdpr": 10, "ge": 10, "gear": 10, "gem": [7, 14], "gener": [0, 6, 7, 8, 9, 13, 21], "geniu": 10, "gentl": 10, "get": [0, 1, 3, 5, 7, 8, 9, 10, 11, 14, 16, 19], "getzola": 10, "ghost": 10, "gi": 10, "giant": 10, "gig": 10, "gigo": 10, "git": [1, 8, 9, 10, 12, 13], "gitautopush": 10, "gitconfig": 14, "github": [2, 5, 10, 12, 14, 20], "gitlab": 8, "give": [1, 2, 5, 9, 10, 12, 13, 14, 19, 20, 21], "given": [1, 8, 10], "giver": 10, "global": 10, "gme": 10, "go": [0, 2, 8, 10, 14, 16, 19, 20], "goal": [2, 4, 5, 8, 10, 13, 14, 19], "goe": [2, 10, 13], "gone": 10, "good": [0, 1, 2, 5, 7, 8, 9, 10, 14, 19, 20, 21], "googl": [2, 10], "got": [1, 10, 14, 19, 21], "gotten": 10, "gpu": 10, "grade": 21, "gradual": 10, "grain": 10, "graphic": [10, 11, 12], "grasp": 10, "great": [7, 10, 13, 19], "greater": 14, "greatest": 19, "green": 10, "grei": 14, "grew": 1, "gritti": 19, "ground": [10, 19], "group": [0, 7, 10, 13, 14], "grow": 10, "guarante": 20, "guess": 10, "guest": 10, "gui": 10, "guid": [7, 8, 10, 13, 17, 19], "gwdg": 10, "h1": 14, "h2": 14, "h3": 14, "h4": 14, "h5": 14, "h6": 14, "h7": 14, "ha": [1, 5, 8, 9, 10, 12, 13, 16, 17, 19], "habit": 0, "hackathon": 10, "hackmd": [0, 2, 10, 20], "had": [5, 10, 19], "hale": 10, "half": [13, 14], "hand": [0, 1, 10, 12, 18], "handbook": 8, "handl": [10, 13], "happen": [2, 10, 13, 17, 20], "happend": 10, "happi": 10, "hard": [9, 10, 14, 16, 17, 19, 20, 21], "harder": [10, 21], "hardest": 10, "hardwar": [10, 19], "hashnod": 10, "hasn": 10, "have": [0, 1, 2, 5, 7, 8, 9, 10, 13, 14, 15, 16, 17, 18, 19, 20, 21], "haven": [8, 10, 14], "hc": 10, "he": 10, "head": [2, 10, 12, 17, 19], "headphon": [10, 16], "headset": [10, 16], "hear": [10, 16], "heard": [10, 16], "hedgedoc": [0, 2, 10], "heidi": 10, "height": 14, "heinlein": 10, "held": 0, "help": [0, 1, 2, 5, 8, 9, 10, 13, 14, 15, 16, 19, 20, 21], "helper": [2, 6, 7, 10, 13], "here": [0, 1, 2, 4, 8, 9, 10, 14, 19, 20, 21], "herford": 10, "heterogen": 10, "hide": 10, "high": [1, 8, 16, 20], "higher": 10, "highli": [2, 10], "highlight": [2, 8, 9, 10], "him": 10, "himself": 10, "hint": [2, 20], "histori": [9, 10], "historysavepath": 14, "histtimeformat": 14, "hole": 19, "home": [10, 19], "homepag": 10, "hope": 10, "hopefulli": [2, 8], "horizont": 14, "horribl": 2, "host": [1, 9, 10], "hostabl": 9, "hour": [2, 5, 10, 20, 21], "hous": 10, "hover": 20, "how": [0, 1, 3, 6, 7, 9, 11, 12, 16, 19, 21], "howev": [0, 1, 10], "hpc": [10, 14, 20, 21], "html": [9, 10], "http": [2, 5, 8, 9, 10, 12, 14, 19, 20], "huge": [10, 21], "human": 10, "humour": 19, "hustl": 10, "hybrid": 10, "hypothesi": 20, "i": [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20], "i1": 14, "i3": 10, "ic": 10, "icebreak": 2, "icon": 9, "icp": 10, "id": 10, "idcc": 10, "idcc24": 10, "idea": [1, 5, 8, 10, 14], "ideal": [10, 14], "identifi": [8, 10], "ie": 10, "imag": [1, 10, 13], "imagin": 10, "imbalanc": 16, "imform": 10, "imho": 10, "immedi": [2, 10, 19, 20], "imovi": 10, "impact": [6, 7], "imperfect": 8, "implement": 10, "implicitli": 10, "import": [0, 1, 2, 8, 9, 10, 11, 12, 13, 14, 19, 20], "imposs": [10, 14], "impress": 10, "impro": 10, "improv": [1, 2, 5, 7, 9, 14, 16, 20], "improvis": 10, "incent": 20, "inclin": 19, "includ": [0, 2, 10, 14, 19, 20], "inclus": 10, "inconveni": 10, "incorpor": 5, "increas": 10, "increment": 10, "inde": 10, "independ": [1, 10, 19], "index": 10, "indic": [2, 10, 13, 20], "individu": [0, 10, 12, 16, 17, 19], "industri": 10, "inertia": 10, "influenc": 10, "info": [2, 10, 13, 20], "inform": [1, 2, 7, 10, 14, 19, 20], "infrastructur": [1, 19], "infrequ": 21, "initi": [2, 8, 10, 20], "initial_prompt": 20, "inkscap": 10, "inlcud": 1, "inlin": 9, "inner": 10, "input": [9, 10, 16, 20], "insid": 10, "insight": 10, "inspir": [5, 9, 10], "instal": [0, 6, 9, 10, 13, 14, 20], "instanc": [0, 9, 10], "instant": [2, 21], "instead": [2, 5, 8, 9, 10, 19, 20], "institut": [1, 5], "instruct": [0, 2, 10, 13, 14, 20], "instructor": [1, 7, 10], "int": 10, "intak": 10, "integr": [10, 13], "intend": [10, 19], "intens": 2, "intent": 19, "interact": [0, 2, 6, 7, 9, 10, 13, 16, 19, 20, 21], "interest": [1, 6, 7, 8, 10, 13, 14, 19], "interfac": [9, 10], "intergr": 10, "intermedi": [1, 10], "intern": 15, "internet": [10, 11], "interoper": 10, "interpret": 2, "interrupt": [0, 2], "interview": 10, "intro": [6, 7, 9, 10, 20], "introduc": [10, 14], "introduct": [6, 7, 8, 12, 15, 20], "introductori": [2, 15], "intuit": 10, "invent": 20, "invert": 8, "invest": 10, "invit": 13, "involv": [1, 10], "io": [2, 5, 8, 9, 10, 14, 20], "iron": 10, "isn": [2, 10, 14, 16, 17, 19, 21], "isol": [8, 10], "issu": [1, 5, 8, 9, 10, 13, 16, 19], "istockphoto": 10, "item": [2, 5, 10], "iter": [1, 7], "its": [0, 1, 10, 14, 20], "itself": [0, 1, 5, 9, 10], "j": 10, "jame": 10, "jargon": [10, 19], "jarno": 7, "jekyl": 8, "jitsi": 10, "job": [10, 19], "joi": 10, "join": [0, 1, 2, 7, 10, 13], "jointli": 0, "joke": 10, "jonathan": 10, "journal": 10, "joyc": 10, "jpg": 10, "json": 12, "judg": [5, 10], "jump": [10, 13, 20], "jupyt": [1, 8, 9, 10, 14], "jupyterbook": 9, "jupyterhub": 10, "jupyterlab": 10, "just": [1, 2, 5, 7, 8, 9, 10, 12, 14, 15, 19, 20], "justifi": 10, "k": 10, "kahoot": 10, "kao": 10, "kb0068677": 10, "kdenliv": 10, "keep": [0, 1, 2, 10, 13, 17, 19], "kei": [1, 10, 13, 20], "keller": 10, "kept": 10, "keyboard": [10, 14], "kick": 10, "kickstart": [14, 20, 21], "kid": 10, "kind": [2, 10, 13, 15, 16], "kitchen": 10, "knead": 10, "knew": [8, 10], "know": [0, 1, 3, 5, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20], "knowledg": [9, 10, 19], "known": [1, 10, 11, 19], "kth": 1, "l": 14, "l1": 14, "l2": 14, "l3": 14, "l8my5kygc": 10, "la": 10, "lab": 10, "label": 10, "labor": [0, 10], "lai": [10, 11], "landscap": 14, "lang": [10, 20], "languag": [1, 8, 10, 19], "laptop": [11, 14], "larg": [2, 7, 10, 11, 13, 14, 19, 20], "larger": [0, 8, 10, 21], "largest": 21, "last": 10, "late": [10, 14, 20], "latenc": [10, 16], "later": [2, 5, 7, 8, 9, 10, 12, 14, 17, 20], "latest": [2, 10, 14, 19], "latex": [8, 9, 10], "latter": [7, 10], "laugh": 10, "layout": 12, "lead": [0, 5, 10, 20], "leader": 16, "lean": 10, "leap": 10, "learn": [0, 1, 7, 10, 11, 13, 17, 19, 20, 21], "learner": [0, 1, 2, 5, 8, 10, 19, 20], "least": 10, "leav": [2, 10, 12, 13, 20], "lectur": [0, 2, 10, 19], "led": 10, "left": [2, 14, 20], "legaci": 14, "length": 10, "less": [0, 10, 14, 16, 19, 21], "lesson": [0, 1, 2, 6, 7, 12, 13, 14, 15, 17, 18, 19, 20], "let": [1, 2, 10, 11, 12, 13, 16, 20], "level": [1, 2, 8, 9, 10], "licens": [8, 10], "life": [10, 15, 19], "lifecycl": 10, "light": [10, 14], "like": [0, 1, 2, 4, 7, 8, 9, 14, 16, 19, 20], "likert": 10, "limit": [9, 10, 16, 20, 21], "lincoln": 10, "lindi": 7, "line": [2, 8, 9, 10, 14, 20], "link": [2, 5, 7, 9, 10, 19], "linkedin": 10, "linux": [2, 8, 9, 10, 14, 20], "list": [8, 10, 19, 20], "listen": [10, 16, 19], "liter": [0, 10], "littl": 10, "live": [2, 8, 10, 19], "livestream": [10, 11, 20, 21], "ll": [9, 10, 11, 12, 17], "local": [0, 1, 8, 10, 14], "localhost": 12, "locat": [10, 16], "log": [10, 14], "logic": [2, 10], "login": 2, "logo": 9, "long": [2, 5, 9, 10, 12, 16, 19, 20, 21], "longer": [9, 10], "look": [0, 2, 8, 9, 10, 13, 14, 16, 17, 19, 20], "loop": 10, "loos": 10, "lose": [2, 10], "lost": [8, 10, 14, 20], "lot": [5, 7, 8, 10, 14, 15, 16, 17, 18, 19], "loud": [10, 16], "louder": [10, 16], "loudest": 10, "love": 10, "low": [10, 16], "lower": [10, 13, 16], "luck": 10, "lucki": 10, "luckili": 10, "lyric": 10, "m": [10, 19], "mac": 10, "machin": 10, "made": [9, 10, 12, 13, 14], "magic": 19, "mai": [0, 1, 2, 8, 10, 11, 12, 14, 15, 16, 19, 20], "mail": [10, 13], "main": [0, 1, 2, 3, 8, 10, 13, 14, 17, 19, 20], "mainli": 10, "maintain": [0, 1, 21], "major": [1, 5, 10], "make": [0, 1, 2, 5, 8, 9, 10, 11, 12, 14, 16, 19, 21], "maker": 10, "man": 10, "manag": [8, 9, 10, 11, 13, 14, 17], "mani": [0, 1, 9, 14, 15, 19, 21], "mankind": 10, "manual": [0, 8, 10, 11, 12, 13, 14, 20], "map": [10, 19], "markdown": [2, 8, 9, 10], "mass": [10, 21], "master": [10, 12], "match": [5, 10, 16], "materi": [0, 1, 2, 3, 5, 7, 9, 10, 13, 19], "materti": 10, "matter": [10, 13, 16], "max": 10, "maximum": 14, "mayb": [2, 8, 10], "mbit": 11, "md": 10, "mdbook": 10, "me": [10, 19], "mean": [10, 19, 20], "meant": 10, "measur": [6, 7], "mechan": 5, "media": 10, "mediocr": 10, "medium": [10, 16, 21], "meet": [1, 8, 10, 13, 16], "meetup": 13, "mega": 21, "member": 10, "memor": 19, "memori": [8, 10, 11], "mental": [2, 7], "mention": 10, "mentor": 15, "mentorship": 19, "menu": [10, 12, 14], "mere": 10, "merg": [8, 10], "messag": [8, 9, 10], "messi": 10, "met": 10, "meta": 2, "metaphor": 10, "method": [9, 10], "methodlogi": 10, "mic": 10, "michel": 10, "microphon": [10, 16], "microsoft": 10, "mid": 10, "middl": [5, 10], "midst": 10, "might": [0, 9, 10, 14, 16, 19, 20], "min": [3, 4, 6, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21], "mind": [0, 2, 10, 19], "mindset": 10, "mini": 10, "minim": [2, 9, 10, 14, 19, 20], "minimum": [13, 14], "minor": 10, "minut": [0, 2, 4, 8, 10, 14], "miro": 10, "mirror": 14, "misconcept": 8, "miss": [10, 16, 19, 20], "mistak": [8, 10, 19, 20], "mistyp": 10, "mitig": 10, "mix": [0, 7, 10], "mixer": 11, "mkv": 20, "mobil": 2, "mode": [2, 10, 14, 20], "model": 10, "modesti": 10, "modif": [8, 9], "modifi": [10, 12, 20], "modular": [1, 5, 7, 8, 10], "moment": [10, 19], "mondai": 10, "monei": 10, "monitor": [10, 11, 14], "monologu": 10, "month": 10, "more": [0, 1, 2, 5, 7, 8, 9, 10, 11, 12, 13, 14, 16, 19, 21], "morn": 10, "most": [0, 9, 10, 11, 12, 13, 14, 16, 19, 20, 21], "mostli": [0, 1, 10], "motiv": [1, 5, 10, 14, 19, 20], "motto": 10, "mount": [10, 16], "mous": [10, 20], "move": [0, 8, 10, 13, 20], "movement": 10, "movi": 10, "mpi": 10, "much": [0, 1, 2, 8, 9, 10, 14, 16, 19, 20, 21], "multi": [2, 10], "multipl": [0, 2, 8, 10, 13, 14], "must": [8, 10, 20], "mutual": 10, "mv": 12, "mwakok": 10, "my": [5, 8, 10, 19, 21], "mynam": 2, "myst": [9, 10], "myst_pars": 10, "mysteri": 19, "n": [2, 10, 14], "n0": 14, "n2ak": 20, "name": [2, 5, 10, 16, 20], "narr": 10, "narrat": 10, "narrow": 10, "natur": [0, 10, 19], "navig": [9, 14], "nbinder": 10, "nbviewer": 10, "necessari": [2, 10, 13, 19, 20], "need": [0, 1, 2, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 19, 20], "negoti": 10, "neic": 1, "nerd_fac": 10, "nerded_fac": 10, "nest": 2, "net": 10, "network": [1, 10], "neutral": 5, "never": [2, 10, 12, 19, 20], "new": [0, 2, 7, 9, 10, 14, 15, 17, 19, 20], "next": [2, 5, 6, 7, 8, 9, 10, 11, 13, 16, 19, 20], "nice": [2, 9, 10], "nicer": [10, 21], "nickbearman": 10, "night": 10, "nitti": 19, "nix": 10, "nlastcommand": 10, "nobodi": [10, 14], "nois": [10, 16], "non": [2, 8, 10, 16], "none": [5, 10], "nordic": [1, 13], "normal": [9, 10, 16, 21], "notabl": 16, "note": [6, 7, 15], "notebook": [1, 5, 8, 9, 10, 14], "notepad": 10, "notesrecommend": 10, "noth": [10, 14], "notic": [10, 16, 19, 20], "notif": 2, "notifi": 10, "notion": 19, "novemb": 10, "novic": [10, 19], "now": [0, 2, 5, 7, 8, 9, 10, 20, 21], "nuisanc": 10, "number": [0, 8, 10], "numer": 10, "nvidia": 10, "o": [5, 10, 20], "ob": [6, 7, 17, 20], "obei": 10, "object": [7, 10], "obs_cr": 12, "obviou": [2, 10, 20], "occasion": [0, 1, 10, 19], "octob": 1, "odd": 10, "odt": 10, "ofc": 10, "off": [0, 14, 19, 20], "offens": 19, "offer": [7, 8, 10, 13, 19], "offic": 10, "offici": 10, "often": [0, 1, 2, 10, 19], "ok": [10, 14, 20], "old": [10, 12], "older": [2, 20], "oliv": 10, "onboard": [0, 6, 10, 13], "onc": [10, 11, 12, 16, 19], "one": [0, 1, 2, 5, 8, 9, 10, 13, 14, 16, 19, 20, 21], "onedr": 10, "ones": [2, 7, 10, 13, 17], "onli": [0, 2, 7, 8, 9, 10, 13, 14, 15, 19, 20], "onlin": [0, 1, 2, 6, 7, 10, 13, 15, 19], "onsit": 10, "oo": 10, "ooo": [5, 10], "oooo": 10, "ooooo": 10, "oooooo": [5, 10], "ooooooo": 10, "oooooooo": 10, "ooooooooooooooooooo": 5, "op": 10, "open": [0, 1, 2, 7, 8, 9, 14, 19], "openai": 10, "openshot": 10, "oper": [9, 10, 13], "opin": 10, "opinion": [10, 16], "opportun": [1, 2, 10], "oppos": 10, "opposit": [10, 19], "optim": [10, 21], "optimum": 13, "option": [2, 5, 10, 11, 12, 14, 20], "order": [8, 10, 16], "org": [1, 5, 7, 8, 9, 10], "organ": [0, 1, 7, 8, 9, 10, 13], "organis": 10, "orient": 10, "origin": [10, 20], "oss": 10, "other": [0, 1, 2, 5, 7, 8, 9, 10, 16, 19, 20, 21], "otherwis": [10, 15, 20], "our": [0, 4, 5, 9, 10, 12, 13, 14, 15, 16, 17, 20, 21], "out": [1, 2, 5, 9, 10, 11, 13, 14, 15, 16, 17, 20], "outcom": [10, 19], "outlin": [10, 13, 15], "output": [9, 10, 14], "output_format": 20, "outro": [6, 10], "outsid": [7, 10, 20], "outstand": 10, "ov": 10, "over": [0, 5, 7, 8, 10, 14, 16, 19, 20], "overal": [8, 9, 10, 14, 20], "overarch": 8, "overcom": 10, "overhead": 10, "overkil": 11, "overload": [2, 10], "oversight": 10, "overview": [1, 6, 8, 10], "overwhelm": 19, "own": [1, 2, 8, 10, 13, 19, 21], "oxford": 10, "p": 10, "pace": [5, 10], "packag": 10, "pad": 10, "page": [2, 8, 9, 10, 13, 14, 16, 20], "paid": 10, "paint": 8, "pane": 14, "panel": [10, 11, 14], "panick": 16, "paolo": 10, "paper": [8, 10], "paradigm": 10, "parallel": [0, 8, 10, 20], "parser": 9, "parson": 8, "part": [0, 1, 2, 3, 6, 8, 10, 14, 16, 17, 18, 20, 21], "part1": 20, "parti": 10, "partial": 10, "particip": [2, 4, 5, 7, 8, 10, 13, 14, 19, 20], "particu": 10, "particular": [0, 10], "particularli": [5, 10, 14], "partli": 10, "partner": [7, 10], "pass": 10, "past": [8, 10, 20], "path": [10, 13, 20], "pathwai": 10, "pattern": [3, 10], "paus": [10, 14], "pavucontrol": 10, "pdf": [9, 10], "pedagog": 10, "peer": 13, "pen": 10, "pencil": 9, "peng": 10, "peopl": [1, 2, 8, 9, 10, 14, 16, 19, 20, 21], "per": [10, 20], "perceiv": 10, "perfect": [2, 8, 20], "perfectli": 19, "perform": [1, 8], "perhap": [10, 20], "period": [2, 10, 19], "periscop": 10, "perman": 10, "permiss": 2, "persist": 5, "person": [0, 2, 10, 13, 16, 17, 19, 21], "persona": [8, 10, 19], "personalis": 10, "personel": 10, "perspect": [7, 19], "phase": 13, "phd": 10, "philosohi": 6, "philosophi": [7, 9], "phrase": 19, "physic": 10, "pick": [8, 10, 16], "pickl": 10, "pickup": 16, "pictur": [0, 5, 8, 14], "pid": 10, "piec": [10, 11, 12], "pinimg": 10, "pioneer": 10, "pip": [10, 12, 14, 20], "pipe": 10, "pitfal": 14, "place": [2, 5, 9, 10, 19, 20, 21], "plai": 10, "plain": 10, "plan": [0, 1, 2, 5, 8, 10, 14, 18], "planet": 10, "platform": [10, 11, 17], "player": 10, "playlist": [19, 20], "pleas": [2, 5, 7, 8, 10, 14, 15, 16, 19], "pleasant": 10, "plenti": 10, "plplblyhczjaahf89p": 19, "plu": 14, "plug": 16, "plzlvms9rf3nmkr2jmglan4su3ojwtwmvw": 20, "png": 10, "poet": 10, "point": [2, 8, 9, 10, 17, 19, 20], "polar": 10, "polish": 10, "pop": 10, "popular": 10, "port": [1, 8], "portion": [10, 11, 14], "portrait": 10, "posit": 10, "possibl": [1, 2, 9, 10, 14, 16, 19, 21], "possibli": [0, 10, 14, 20], "post": [5, 7, 8, 10, 13], "potenti": [0, 16], "power": [10, 11], "powershel": 14, "pptx": 10, "pr": 2, "practic": [0, 1, 3, 7, 8, 15, 16, 18], "pre": [5, 10, 12], "precis": [10, 19], "predict": 10, "preexec": 14, "prefer": [2, 10, 11, 14], "premis": 10, "prep": 10, "prepar": [0, 7, 8, 13, 15, 16, 19], "prerequisit": [7, 9, 10, 20], "presemo": 10, "presenc": 10, "present": [1, 4, 7, 8, 10, 13, 19, 20, 21], "presentor": 10, "presist": 10, "press": [8, 14], "presum": 10, "pretend": 10, "pretti": [8, 9, 10, 16], "preview": [8, 9, 10], "previou": [0, 6, 7, 9, 10, 12, 13, 19, 20], "price": 16, "primari": 14, "principl": [0, 10, 20], "print": [10, 14], "prior": 1, "priorit": 10, "prioriti": [10, 20], "privaci": [10, 20, 21], "privat": [2, 10], "prize": 10, "pro": 10, "prob": 10, "probabl": [8, 9, 10, 11, 14, 16, 20, 21], "problem": [1, 2, 3, 5, 10, 19], "procedur": [0, 16], "process": [0, 10, 20], "procur": 16, "produc": [10, 20], "product": [10, 15, 19], "profan": 10, "profession": [16, 19], "profil": [8, 10, 12, 14], "program": [1, 8, 10, 14, 19], "programm": [10, 14], "progress": [2, 10], "project": [6, 7, 8, 9, 10], "prompt": [10, 20], "prompt_command": 14, "proper": [8, 10], "propos": [0, 1, 9, 10], "propsal": 9, "protein": 10, "prove": 10, "proven": 7, "provid": [1, 2, 5, 9, 10, 14, 20], "ps1": 14, "psreadlineopt": 14, "public": [2, 5, 9, 10], "publicli": [1, 10], "publish": [2, 5, 8, 10], "pull": [8, 9, 10, 19, 20], "pulsemix": 10, "pun": 10, "punctuat": 20, "purchas": 11, "pure": 14, "puriti": 10, "purpos": [9, 12], "push": [9, 10, 14], "pushpada": 7, "put": [2, 8, 10, 18], "py": [10, 12], "python": [8, 9, 10, 12, 14, 20], "pyyaml": 20, "q": [2, 10, 13, 18], "qgi": 10, "qua": 10, "qualifi": 1, "qualiti": [7, 8, 20], "quantifi": [5, 10], "quarto": 10, "question": [0, 1, 7, 8, 9, 11, 12, 13, 14, 15, 19], "quick": [2, 8, 10, 20], "quickli": [2, 10, 14, 16, 20], "quicktim": 10, "quiet": [10, 16], "quieter": 10, "quietest": 10, "quit": [2, 10, 19], "quiz": 10, "quizz": 10, "r": [9, 10], "rabbit": 19, "radovan": [7, 10], "rais": [1, 2, 19], "ram": 10, "ran": 10, "random": [8, 10], "rang": [10, 16], "rantaharju": 7, "rapid": 21, "rapidli": 14, "rare": [10, 19], "rate": 10, "rather": [2, 10, 12], "ratio": 10, "raw": 10, "rb": 10, "rd": 10, "re": [10, 12, 15, 16, 19, 20], "reach": [5, 10, 21], "read": [0, 2, 9, 10, 14, 19], "readabl": 14, "reader": 20, "readi": [7, 10, 13, 20], "readili": 10, "readm": 10, "readthedoc": [8, 10], "real": [2, 10, 11, 15, 19, 20], "realist": [10, 14], "realiti": 0, "realiz": [10, 16, 19], "realli": [2, 8, 10, 14], "reason": [2, 5, 8, 10, 11, 16], "recent": [9, 10, 14], "recip": 10, "recogn": 10, "recognit": [3, 10], "recommend": [2, 10, 13, 14, 18, 19, 21], "record": [8, 10, 13, 15, 20], "recov": [8, 14], "recreat": 12, "red": [10, 14], "redesign": 8, "reduc": [0, 2, 10, 14], "reencod": 20, "ref": 12, "refer": [2, 10], "referenc": 9, "refin": [10, 15], "refinari": 10, "refineri": 10, "reformul": 5, "refresh": 10, "regard": 13, "regist": 7, "registr": [5, 7, 10, 13, 21], "regular": [8, 10], "rehears": 10, "reichent": 10, "reign": 10, "rel": 10, "relat": [10, 19], "relationship": 10, "relax": 10, "relearn": 10, "releas": [8, 10, 20], "relev": [0, 8, 10, 14], "reli": 0, "remain": [2, 10], "remark": [0, 10], "remarkj": 10, "rememb": [8, 10, 20], "remind": [2, 10], "remot": [0, 10, 14, 17, 20, 21], "remov": [2, 5, 10, 14, 20], "renam": [10, 14], "render": 10, "repeat": [10, 19], "repetet": 10, "rephras": 10, "repli": 10, "repo": [9, 10], "repons": 10, "report": [5, 10], "repositori": [1, 8, 9, 10, 12], "repres": 10, "reproduc": [1, 5, 10], "request": [8, 9, 10, 19], "requir": [0, 2, 9, 10, 14, 16, 21], "requisit": 10, "research": [1, 5, 10, 14, 19, 21], "reset": 12, "resist": 10, "resiz": [10, 14], "resolut": 12, "resourc": [5, 10], "respect": [9, 10, 12, 16], "respond": 5, "respons": [0, 5, 10], "rest": [9, 10, 20], "restructur": 9, "result": [5, 10, 20], "resus": 10, "return": 14, "reupload": 10, "reus": [7, 8, 9, 10, 13, 15], "reusabl": [5, 10, 21], "reveal": 10, "revealj": 10, "revers": 14, "review": [10, 20, 21], "revis": [0, 10], "revisit": 1, "rewrit": [8, 10], "richard": [7, 10], "right": [2, 5, 10, 13, 14, 16, 19, 20], "rigor": [2, 10], "rise": [5, 10], "risk": [2, 5, 10, 20, 21], "ritchi": 10, "rkdarst": 12, "rmarkdown": [9, 10], "robert": 10, "robot": 10, "role": [0, 2, 6, 10, 17, 20], "room": [0, 2, 8, 16, 19, 20], "room1": 10, "room2": 10, "root": 2, "rough": [8, 10], "roughli": [9, 10], "rse": 10, "rst": [9, 10], "rubi": 8, "rule": 10, "run": [1, 5, 9, 10, 12, 13, 14], "runner": 10, "rush": 10, "rust": 10, "rxqefefl3t5b": 10, "sacr": 10, "safe": 10, "sai": [0, 2, 10, 14, 16, 20], "said": [2, 10, 20], "saluting_fac": 10, "samantha": [7, 10], "same": [0, 9, 10, 14, 16, 17, 19, 20], "sampl": [9, 10], "sandpap": 10, "satisfi": 10, "satur": 14, "save": [0, 5, 10, 14], "sc": 10, "scale": [5, 7, 10, 13, 21], "scan": 2, "scari": 17, "scenario": 10, "scene": [10, 12, 13], "schedul": 20, "scicomp": 20, "scicompintro": 20, "scienc": [10, 20], "scientif": [10, 20], "scip": 20, "scisoft": 8, "scope": [2, 10], "scratch": [11, 12], "scream": 10, "screen": [4, 7, 17, 20], "screencast": 11, "screenkei": 10, "screenshar": [2, 6, 7, 10], "screenshot": [10, 14], "screenshot_2023": 10, "script": [1, 10, 14, 19], "scroll": [10, 20], "scrum": 10, "search": [2, 10, 14], "season": 10, "sec": 10, "second": [10, 11, 20], "section": [1, 2, 10, 12, 13, 20], "secur": 2, "sed": [10, 14], "see": [0, 1, 2, 8, 9, 10, 12, 13, 14, 17, 19], "seed": 10, "seedl": 10, "seek": 10, "seem": [0, 1, 10, 11, 12, 16, 19], "seen": [0, 2, 5, 7, 10], "segment": [10, 20], "seibold": 10, "select": [2, 10], "self": [7, 8, 10, 19], "sell": 9, "seminar": 10, "send": [2, 9, 10, 13, 19], "sens": [1, 2, 10, 11, 12], "sensit": 19, "sent": 10, "sentenc": [10, 19, 20], "sep": 7, "separ": [8, 10, 14, 19, 20, 21], "sequenc": 20, "serial": 19, "serv": [0, 10], "server": [12, 14], "servic": [1, 10], "sese": 1, "session": [0, 1, 2, 6, 8, 12, 13, 14, 17, 19, 20], "session_nam": 14, "set": [9, 10, 13, 15, 16, 19, 20], "setup": [6, 7, 8, 11, 16], "sever": [8, 10, 16, 20, 21], "sfor": 10, "share": [2, 5, 6, 7, 9, 12, 13, 15, 17, 19, 20], "shareabl": 9, "sheet": 10, "shell": [8, 9, 10, 14], "shell_command": 14, "shellshar": 10, "shift": 14, "shokingli": 10, "short": [3, 4, 10, 12, 20], "shortcom": 10, "shortcut": [10, 14], "shorten": 13, "shortest": 10, "shot": [10, 21], "shotcut": 10, "should": [2, 5, 8, 9, 10, 14, 16, 19, 20], "shouldn": [2, 10, 16, 17], "show": [0, 1, 5, 8, 9, 10, 13, 14, 16, 18, 19], "shown": 14, "shy": 10, "sick": 10, "side": [10, 14], "sign": [10, 19], "signal": [8, 10, 19], "silenc": 10, "silent": 10, "silli": 10, "similar": [0, 2, 10, 14, 16, 19], "simpl": [8, 10, 14, 19, 20], "simpler": [8, 10], "simpli": [10, 19], "simplic": 10, "simplifi": [10, 14], "simul": [10, 20], "simultan": 10, "sinc": [2, 5, 10, 12, 13, 14, 15, 19, 20], "sine": 10, "singl": [0, 9, 10, 13, 14, 21], "sit": 10, "site": [2, 9, 10], "situat": [0, 14], "six": 10, "size": [10, 21], "skill": [0, 7, 10, 19], "skip": 19, "sleep": 10, "sleepi": 10, "sleeppi": 10, "slice": 20, "slide": [3, 8, 9, 10, 19], "slider": 10, "slido": 10, "slightli": [2, 10, 14], "slot": 10, "slow": [2, 5, 10, 20], "slower": 10, "slowest": 11, "slowli": 14, "slur": 10, "small": [2, 7, 8, 10, 14, 16, 21], "smaller": [10, 13, 14, 18], "smart": 10, "smc": 10, "smil": 10, "smile": 10, "smiley_cat": 10, "smooth": 10, "smoothli": 10, "smut": 7, "snippet": 9, "snore": 10, "so": [0, 1, 2, 5, 8, 9, 10, 11, 13, 14, 16, 17, 19, 20], "social": 10, "softer": 16, "softwar": [1, 5, 7, 9, 14, 16, 19, 21], "software_carpentri": 10, "solidifi": 8, "solo": [0, 10], "solut": [8, 10, 14, 19], "solution": 10, "solv": [1, 3, 10, 19], "some": [0, 2, 4, 5, 8, 9, 10, 12, 13, 14, 15, 16, 19, 20], "somebodi": [8, 10], "somehow": 10, "someon": [0, 2, 5, 8, 9, 10, 13, 14, 16, 17, 18, 19, 20], "someth": [1, 2, 4, 5, 8, 9, 10, 14, 16, 17, 19, 20], "sometim": [0, 5, 10, 19], "sometimes": 10, "somewhat": 10, "somewher": 10, "song": 10, "soni": 10, "sonor": 10, "soon": [2, 10, 16], "sooner": [2, 10, 19], "sorri": 10, "sort": 10, "soucr": 10, "sound": [0, 6, 7, 19], "sourc": [0, 5, 8, 9, 10, 11, 19], "space": [10, 14], "spade": 10, "spam": 10, "spanish": 10, "spark": 19, "spars": 10, "spatial": 10, "speak": [0, 10, 20], "speaker": 10, "spec": 10, "special": 10, "specif": [1, 8, 10, 19], "specifi": 16, "spectrum": 10, "speech": 10, "speed": [1, 5, 10], "spend": 10, "spent": 19, "sphinx": [8, 10], "spi": 10, "split": [2, 10, 14, 19, 20], "spontan": 10, "spool": 10, "spot": [9, 20], "spotter": 0, "spread": 1, "sprinkl": 8, "srt": 20, "ssh": 14, "stabil": 10, "stabl": [10, 11], "stack": 10, "staff": [2, 20], "stage": 10, "stai": [8, 10, 19, 21], "standard": [8, 9, 14], "star": 10, "stare": 10, "start": [1, 2, 8, 10, 13, 14, 16, 17, 19, 20], "starter": 10, "stat": 10, "state": 10, "statement": [2, 10], "static": 9, "statist": 10, "statu": [2, 10], "steadili": 10, "step": [1, 2, 8, 10, 12, 18, 20], "stepa": 7, "stephan": 7, "steve": 10, "sth": 10, "stick": 20, "sticki": 10, "still": [2, 8, 10, 13, 14], "stockholm": [1, 10], "stop": [10, 19, 20], "storag": 20, "stori": [10, 19], "straight": [9, 10, 17], "straightforward": [9, 10], "strategi": [8, 10, 13], "stream": [0, 6, 7, 11, 12, 13, 14, 15, 18], "streamer": 10, "streamyard": 17, "streme": 10, "strength": 0, "stress": [0, 10], "strike": 10, "string": 10, "strip": 2, "strong": [0, 9, 10], "strongli": [10, 14], "strted": 10, "structur": [0, 2, 7, 10, 13, 19], "struggl": 10, "stuck": 10, "student": [0, 10, 13], "studi": [10, 19], "studio": [11, 12], "stuff": [10, 14], "style": [0, 1, 10, 19], "sub": 14, "subject": [0, 10], "submit": [1, 9], "subtitl": 10, "subtleti": 0, "succe": 10, "succeed": 10, "success": [0, 5, 10, 13, 14, 19], "successfulli": 10, "suffer": [10, 16], "suffici": [1, 10, 19], "suggest": [5, 8, 10], "suit": [10, 12], "suitabl": 13, "sum": [10, 19], "summ": 8, "summari": [8, 10, 13], "summat": 10, "summer": [10, 13, 20], "sun_with_fac": 10, "sunflow": 10, "supercomput": 9, "superior": 10, "superus": 14, "support": [0, 1, 7, 9, 10, 13, 19], "suppos": 10, "sure": [2, 5, 10, 16, 20], "surpris": [10, 19], "surprisingli": 10, "survei": [10, 13], "swap": 16, "swcarpentri": 10, "sweat_smil": 10, "sweden": 5, "sweet": 10, "switch": [2, 7, 10], "symbol": 10, "symbolifi": 10, "sync": 9, "synergi": 0, "syntax": 2, "synthet": 20, "sysparm_articl": 10, "system": [9, 10, 13], "systemat": 16, "t": [0, 5, 8, 9, 10, 14, 16, 17, 19, 20, 21], "tab": [8, 9, 10, 14], "tabl": [10, 20], "tackl": 10, "tag": 2, "tail": [10, 14], "tailor": [0, 10], "take": [0, 2, 4, 9, 10, 13, 14, 16, 17, 19, 20], "taken": [10, 13], "talbert": 10, "talk": [0, 2, 8, 10, 13, 15, 18, 20, 21], "tandem": 10, "target": [7, 10], "task": [7, 10], "tast": 10, "taught": [0, 8, 10, 19, 21], "tavatar": 14, "taxonomi": 8, "tea": 10, "teach": [1, 2, 3, 6, 7, 9, 11, 12, 13, 15, 16, 17, 18, 20, 21], "teacher": [0, 10, 13, 19], "teachingstreamingv3": 12, "teachingstreamingzoomv3": 12, "teachtogeth": 10, "team": [9, 10, 16, 21], "teamtopologi": 10, "tear": 10, "tech": [8, 10, 14], "technic": [8, 10, 15], "techniqu": [5, 7, 13, 19], "technologi": [2, 8, 10, 19], "teenag": 10, "tell": [0, 10], "templat": [6, 8, 10], "ten": 8, "tend": [5, 10, 19], "tendend": 10, "term": [10, 17], "termin": 10, "terminologi": 10, "termonologi": 10, "test": [7, 8, 10, 12, 14, 16], "text": [2, 5, 9, 10, 13, 14, 20], "than": [2, 5, 8, 9, 10, 14, 16, 19, 20, 21], "thank": 10, "thankfulli": 10, "thats": 10, "thee": 15, "thei": [0, 1, 2, 4, 5, 8, 9, 10, 13, 14, 16, 17, 19, 20, 21], "them": [1, 2, 4, 5, 8, 9, 10, 12, 13, 14, 15, 16, 17, 19, 21], "themat": 10, "theme": [10, 14], "themselv": [10, 16], "theoret": [1, 10, 18], "theori": [3, 10, 11, 12, 18], "ther": 10, "therefor": [0, 5, 10], "thi": [0, 1, 2, 3, 8, 9, 10, 11, 12, 14, 15, 16, 17, 19, 21], "thing": [0, 5, 7, 8, 12, 13, 14, 15, 16, 17, 19, 20, 21], "think": [2, 5, 6, 7, 8, 9, 16], "thinker": 10, "this_command": 14, "thoroughli": 10, "those": [0, 2, 8, 10], "though": [2, 10, 13, 19], "thought": [8, 10, 13], "thread": 2, "three": [8, 10, 14, 16, 19, 20], "through": [0, 1, 2, 10, 11, 13, 19, 20], "throughout": 10, "throw": 0, "thrown": 19, "thu": [10, 20], "thumbnail": 10, "thumbs_up": 10, "thvmntbjg2y": 20, "tidi": 10, "tighter": 10, "time": [0, 2, 7, 8, 10, 11, 14, 16, 19, 20, 21], "timer": 10, "timestamp": 20, "tini": [9, 10], "tip": [5, 6, 8, 10], "tire": 10, "tired_fac": 10, "titl": [2, 10, 14, 20], "tmp": 14, "tmux": 14, "tmuxp": 14, "todai": [2, 5, 19], "togeth": [0, 8, 9, 10, 21], "token": 12, "toliauta": 7, "tomorrow": 10, "tone": 10, "tongu": 10, "too": [0, 1, 2, 5, 8, 10, 14, 16, 19, 20, 21], "took": 10, "tool": [1, 4, 6, 7, 8, 9, 13, 14, 16, 19, 20, 21], "toolbar": 14, "toolbox": 8, "toolkit": 10, "top": [2, 10, 14], "topic": [1, 6, 7, 8, 10, 19, 20, 21], "total": 10, "touch": [13, 14], "tough": 10, "tour": 17, "toward": [1, 8, 9, 10], "track": [0, 2, 5, 8, 10, 14], "traction": 10, "trade": 14, "tradit": [8, 10, 13, 19, 21], "traffic": 10, "train": [1, 8, 10, 13, 18, 19, 20, 21], "train2": 10, "trainer": 10, "transcript": [10, 20], "transfer": [8, 10], "transform": 10, "transit": [1, 10, 20], "translat": [10, 20], "transmiss": 19, "transpar": 10, "trap": 14, "travel": 21, "tree": 10, "trend": [8, 10], "tri": [0, 1, 5, 10, 16], "trick": [4, 5, 6, 8, 10, 16, 19], "tricki": 10, "trim": 10, "trivial": 10, "troubl": 10, "troughout": 10, "true": 10, "try": [0, 1, 2, 8, 9, 10, 12, 14, 19, 20], "ttt": [9, 10], "tuesdai": [7, 10], "tune": [9, 10], "turn": [10, 13, 16], "tutori": [10, 17, 19], "tweak": 10, "twice": 10, "twist": 19, "twitch": [10, 17, 21], "twitter": 10, "two": [0, 1, 2, 8, 10, 12, 13, 16, 19, 20], "txt": [9, 20], "type": [0, 8, 10, 12, 14, 16, 19], "typic": [1, 10, 14], "typo": [10, 19], "u": [1, 2, 5, 7, 9, 10, 13, 15, 16, 19, 20, 21], "uk": 10, "umbrella": 10, "unabl": 10, "unclear": [2, 19], "uncomfort": [10, 19], "under": [8, 10, 12], "underli": 10, "understand": [0, 1, 5, 8, 9, 10, 11, 13, 16, 19], "understood": 10, "unexpect": 0, "unexpectedli": 17, "unfortun": [10, 14], "uniqu": 10, "univers": [1, 10, 19], "unix": 10, "unknown": 10, "unless": 10, "unlik": 10, "unmanag": 10, "unnecessari": [1, 5], "unpleas": 10, "unprepar": 0, "unprepared": 0, "unproblemat": 10, "unprocess": 20, "unsaf": 10, "unspecifi": 5, "unsur": 10, "until": [1, 2, 5, 10], "unwant": 10, "uo5kbtqdjzbbqb_xldhzuovx5t08fhfgr7dw7tck90i": 10, "up": [0, 1, 2, 5, 8, 9, 10, 11, 13, 15, 19, 20], "upcom": 10, "updat": [2, 5, 10, 12, 13], "upload": 10, "upper": 14, "upstream": 9, "urgent": [13, 16], "url": [2, 10], "us": [0, 1, 2, 3, 4, 7, 10, 11, 12, 14, 15, 16, 18, 19, 21], "usabl": 10, "usag": [1, 8, 10], "usb": 16, "user": [10, 20], "usernam": 2, "usual": [1, 10, 16], "utc": 10, "v": [8, 10, 17, 20], "vagu": 10, "valid": 10, "valu": [10, 14, 19], "valuabl": [2, 5, 10, 14], "variabl": 10, "varieti": [10, 14], "variou": [0, 9, 10], "vastli": 10, "vc": 10, "ve": [10, 19, 21], "vector": 10, "vega": 10, "veri": [0, 1, 2, 4, 9, 10, 14, 16, 18, 19, 20], "versa": 10, "version": [1, 5, 7, 8, 19, 20], "versu": 10, "vertic": 14, "vew": 10, "via": [2, 8, 9, 10, 13], "vice": 10, "video": [6, 7, 11, 12, 15, 21], "vie": 10, "view": [2, 10, 11, 17], "viewpoint": [10, 19], "virtual": [9, 10, 20], "visibl": 10, "vision": 10, "visual": 10, "visualis": 10, "voic": [0, 2, 10, 16], "volum": [2, 10], "volunt": [10, 13], "voluntari": 10, "vote": 10, "w": 10, "wa": [1, 2, 8, 9, 10, 13, 14, 17, 19, 20], "wai": [0, 9, 10, 11, 13, 14, 18, 19, 20], "wait": [2, 14, 19], "wake": 10, "walk": 17, "wall": 2, "want": [0, 1, 8, 9, 10, 13, 14, 15, 18, 19, 20, 21], "war": 19, "ward": 10, "wasn": 10, "wast": 10, "watch": [0, 9, 10, 13, 14, 19, 20], "wayland": [10, 14], "we": [0, 1, 2, 4, 6, 7, 9, 11, 12, 15, 17, 18, 19], "wear": 10, "web": [2, 8, 9, 10, 13, 14], "webcam": 10, "webpag": [2, 20], "websit": [10, 14], "websocket": 17, "webwhiteboard": 10, "wed": 10, "week": [10, 13, 19], "weird": 15, "welcom": [10, 13, 20], "well": [0, 2, 10, 14, 15, 16, 19], "went": 10, "were": [2, 8, 10, 13, 16, 20], "weren": [10, 19], "what": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 13, 14, 15, 16, 19], "whatev": [9, 10, 14], "whatsapp": 10, "when": [0, 1, 2, 5, 8, 10, 17, 19, 20, 21], "whenev": [1, 7, 19], "where": [0, 1, 8, 9, 10, 13, 16, 19, 20], "wherea": 10, "wherev": 16, "whether": [0, 10, 19, 20], "which": [0, 1, 2, 8, 10, 11, 13, 14, 17, 19, 20], "while": [0, 2, 10, 13, 14, 19, 20], "whisper": 10, "whistl": 10, "white": 14, "whiteboard": 10, "who": [0, 1, 2, 5, 10, 16, 18, 20], "whole": 20, "whom": 10, "why": [2, 5, 6, 7, 13, 19], "wide": 10, "wider": 10, "wiki": 10, "william": 10, "win": 10, "window": [2, 10, 11, 14], "window_nam": 14, "winter": 13, "wire": [10, 11, 16, 19], "wireless": 16, "wise": 10, "wiser": 10, "wish": [1, 8, 10, 13], "within": [0, 2, 9, 10, 16, 20], "without": [0, 2, 8, 10, 14, 16, 21], "wittk": 7, "won": [2, 10, 16, 20, 21], "wonder": [10, 14, 19], "woozy_fac": 10, "word": [1, 5, 10, 16, 19, 20], "work": [0, 1, 7, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20], "workaround": [10, 14], "workbench": 10, "workbook": 10, "workflow": [1, 8, 9, 10, 20], "workload": 0, "workplac": 16, "workshop": [0, 6, 8, 14, 16, 17, 19, 20, 21], "world": [10, 19], "worri": [2, 10], "wors": 10, "worsen": 10, "worst": [10, 17], "worth": [10, 20, 21], "worthwhil": [10, 19], "would": [1, 2, 5, 7, 8, 9, 13, 19, 20, 21], "wouldn": 2, "wow": 10, "write": [0, 1, 2, 5, 7, 8, 9, 10], "writer": [8, 10], "written": 10, "wrong": [8, 10, 16], "www": [10, 19, 20], "x": [1, 8, 10, 19], "x11": 14, "xorg": 14, "xx": [2, 10], "xxx": [2, 10], "yawning_fac": 10, "ye": [0, 5, 10, 21], "yeah": 10, "year": [5, 10, 13], "yellow": 14, "yep": 10, "yet": [1, 8, 10, 11, 12, 14, 17, 20], "you": [0, 1, 2, 4, 5, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21], "your": [0, 1, 2, 7, 10, 12, 13, 16, 17, 19], "yournam": 2, "yourself": [2, 8, 9, 10, 13], "yourselv": 16, "youtub": [10, 17, 19, 20, 21], "zenodo": [5, 10], "zip": 12, "zm_kb": 10, "zola": 10, "zone": 10, "zoom": [7, 10, 13, 14, 17, 21], "zsh": [10, 14], "zsh_histori": 10, "zulip": [1, 10], "zulipchat": 10}, "titles": ["Co-teaching", "About the CodeRefinery project and CodeRefinery workshops in general", "Collaborative notes", "Computational thinking", "Sharing teaching gems", "How we collect feedback and measure impact", "Instructor guide", "Train the trainer workshop", "Lesson design and development", "Lessons with version control", "Collaborative notes archives from workshops", "Open Broadcaster Software (OBS) introduction", "Open Broadcaster Software (OBS) setup", "A workshop seen from different perspectives", "How to prepare a quality screen-share", "Session 4 intro", "Sound", "Behind the stream", "What\u2019s next?", "CodeRefinery teaching philosophies", "Video editing", "Why we stream"], "titleterms": {"": 18, "08": 10, "09": 10, "1": [5, 7, 9, 10, 16, 20], "10": [0, 5], "13": 10, "15": 2, "2": [5, 7, 9, 10, 16, 20], "20": [8, 10, 14, 19], "2024": [7, 10], "24": 10, "27": 10, "3": [5, 7, 9, 10, 16, 20], "4": [5, 7, 9, 10, 15, 20], "5": [8, 9, 10, 20], "6": 20, "7": 20, "A": [11, 12, 13, 17, 20, 21], "One": [10, 13], "The": [8, 12, 16], "about": [1, 8, 10], "accept": 9, "add": 20, "adjust": 16, "adopt": 10, "advanc": 9, "after": 13, "all": [8, 10], "also": [11, 18, 20], "altern": 17, "ani": 0, "approach": 8, "ar": [0, 8, 16, 17], "archiv": 10, "articl": 20, "ask": [2, 5], "audienc": [1, 6, 10], "audio": 16, "august": [7, 10], "b": 20, "backward": 8, "balanc": 16, "basic": [2, 20], "bast": 19, "befor": [2, 5, 12, 13], "behind": [10, 17], "benefit": [0, 21], "best": 10, "better": 8, "between": 14, "bj\u00f8rn": 19, "breaker": 19, "breakout": 10, "breakoutroom": 10, "briefli": 21, "broadcast": [10, 11, 12], "browser": 14, "build": 9, "calendar": 10, "can": 17, "captur": 14, "carpentri": [1, 9], "case": 8, "challeng": 1, "check": [10, 16], "classroom": 10, "clone": 9, "co": [0, 10], "coderefineri": [1, 7, 8, 9, 10, 12, 17, 19], "collabor": [2, 5, 10], "collect": [5, 8, 10], "color": 14, "command": 14, "commun": [1, 13], "compet": 1, "comput": [3, 10], "config": 12, "configur": 14, "contribut": 9, "control": [2, 9, 10, 12, 17], "cool": 10, "cours": [11, 12], "creat": [8, 9, 20], "dai": 10, "darst": 19, "day1": 10, "day4": 10, "defin": 1, "demo": 0, "deploy": 10, "design": [5, 8, 10], "desktop": 14, "develop": [8, 10], "did": 13, "differ": 13, "disadvantag": 21, "discuss": [0, 2, 5, 8, 9, 10, 13, 20], "distribut": 20, "do": [8, 16, 20], "document": [2, 8], "doe": 17, "don": 2, "down": 16, "downsid": 0, "dure": [11, 13], "dynam": 16, "each": 12, "easi": 20, "edit": [2, 10, 20], "editlist": 20, "entir": 14, "environ": 14, "episod": 10, "evalu": [14, 16], "everyon": 2, "exampl": [2, 5, 9], "exercis": [0, 2, 5, 8, 9, 10, 14, 16, 20], "exist": 8, "experi": 10, "featur": 20, "feedback": [2, 5, 10], "ffmpeg": 20, "file": 20, "final": 20, "font": 14, "format": [2, 9], "from": [10, 13], "futur": 21, "gem": [4, 10], "gener": [1, 2, 10, 20], "get": [2, 13, 17, 20], "github": [8, 9], "giver": 0, "go": [9, 12, 17], "goal": 1, "good": 16, "great": 8, "group": [5, 8, 19], "guid": [0, 6], "habit": 14, "handl": 2, "hardwar": 11, "histori": [1, 14, 21], "host": 13, "how": [2, 5, 8, 10, 13, 14, 17, 20], "i": [11, 21], "ic": 19, "icebreak": [10, 21], "icecream": 10, "impact": [5, 10], "import": 16, "improv": [8, 10], "individu": 13, "initi": 12, "instal": 12, "instead": 14, "instructor": [0, 2, 3, 4, 5, 6, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21], "interfac": 11, "interview": 0, "intro": 15, "introduct": [2, 10, 11, 19], "invest": 13, "involv": 13, "iter": 10, "journei": 13, "keypoint": [0, 1, 2, 3, 9, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21], "layout": [14, 17], "lead": 13, "learn": [5, 8, 14], "learner": [13, 14], "lesson": [5, 8, 9, 10], "like": [10, 13], "lindi": 19, "local": [9, 13], "longer": 5, "lot": 13, "make": 20, "manag": 2, "mani": [10, 13], "materi": 8, "measur": [5, 10], "mechan": 2, "min": [0, 2, 5, 8, 14], "minut": 19, "model": 0, "modifi": 9, "more": 20, "most": 2, "need": 14, "new": 8, "next": 18, "note": [0, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21], "novic": 1, "ob": [10, 11, 12], "object": [0, 1, 2, 3, 4, 5, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21], "onlin": 14, "open": [10, 11, 12], "option": 9, "other": [13, 14], "our": [1, 8], "output": 20, "overview": 0, "overwhelm": 2, "own": [9, 14], "panel": 17, "part": 13, "peopl": 13, "perspect": [10, 13, 14], "philosophi": [10, 19], "poll": 10, "portrait": 14, "post": 2, "practic": [2, 10], "practition": 1, "prepar": [10, 14], "present": [0, 9], "primari": 20, "privaci": 2, "problem": [8, 16], "process": [8, 9], "project": 1, "prompt": 14, "prospect": 21, "q": [11, 12, 17, 21], "qualiti": [10, 14, 16], "question": [2, 5, 10, 21], "radovan": 19, "raw": 20, "razick": 19, "recommend": 16, "record": [19, 21], "relat": [1, 20], "remot": 12, "requir": 11, "resourc": [7, 8, 14], "result": 8, "richard": 19, "role": 13, "room": 10, "run": 20, "sabri": 19, "sampl": 20, "scene": 17, "schedul": 10, "scheme": 14, "screen": [10, 14], "see": [11, 18, 20], "seen": 13, "septemb": [7, 10], "sessiion": 10, "session": [7, 10, 15], "set": [12, 14, 17], "setup": [10, 12, 13, 14], "share": [4, 8, 10, 14], "size": 14, "smallest": 9, "softwar": [10, 11, 12], "solut": 20, "sound": [10, 13, 16], "speak": 16, "specif": 0, "sphinx": 9, "step": 13, "stepa": 19, "stone": 13, "stream": [10, 17, 20, 21], "subtitl": 20, "summari": [0, 9, 16, 19, 20], "survei": 5, "switch": 14, "t": 2, "take": 5, "target": [1, 6], "teach": [0, 4, 5, 8, 10, 14, 19], "team": [0, 13], "techniqu": 10, "templat": [2, 9], "term": 5, "termin": 14, "test": 20, "thi": [13, 20], "thing": [2, 10], "think": [3, 10], "through": [9, 12], "time": [5, 6, 13], "tip": 16, "todai": 10, "toliauta": 19, "tool": 10, "tour": 9, "train": 7, "trainer": 7, "try": 5, "typic": 8, "un": 14, "up": [12, 14, 16, 17], "us": [5, 8, 9, 20], "user": 11, "vc": 9, "version": [9, 10], "video": [10, 19, 20], "view": 19, "volum": 16, "we": [5, 8, 10, 13, 14, 20, 21], "websit": 2, "what": [11, 17, 18, 20, 21], "when": [14, 16], "whisper": 20, "who": 17, "why": [9, 10, 21], "window": 17, "work": [8, 14], "workshop": [1, 2, 5, 7, 10, 13], "would": 10, "wrapup": 10, "wrong": 17, "yaml": 20, "you": 8, "your": [5, 8, 9, 14, 20]}}) \ No newline at end of file diff --git a/branch/cff/session-4-intro/index.html b/branch/cff/session-4-intro/index.html new file mode 100644 index 0000000..ac8cde9 --- /dev/null +++ b/branch/cff/session-4-intro/index.html @@ -0,0 +1,190 @@ + + + + + + + Session 4 intro — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Session 4 intro

+

This session covers streaming and technical production. Some +introductory notes:

+
    +
  • (As of 2024) This is the first and only comprehensive introduction +to our online streaming.

  • +
  • These practices are new and well-refined internally, but a +different kind of refinement is needed to teach and reuse them.

  • +
  • The lessons have outlines of what to talk about, but it’s just an +outline. It is not refined, since thees things are new. Many +things will have to be figured out as we talk.

  • +
  • This session is a demo of lots of basics.

    +
      +
    • Ask questions - otherwise it will be boring

    • +
    • If you want to use this in real life: you will need mentoring +sessions and active help. Contact us to do that.

    • +
    +
  • +
+
+

Warning

+

Audio and video weirdness

+

We are setting up video and audio recording, but also capturing that +for re-sharing it. There may be anomalies as video or audio +feedback. Please be prepared.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/singlehtml/_images/BYOC.png b/branch/cff/singlehtml/_images/BYOC.png new file mode 100644 index 0000000..94702a1 Binary files /dev/null and b/branch/cff/singlehtml/_images/BYOC.png differ diff --git a/branch/cff/singlehtml/_images/CR_workshop_setup.png b/branch/cff/singlehtml/_images/CR_workshop_setup.png new file mode 100644 index 0000000..47b4502 Binary files /dev/null and b/branch/cff/singlehtml/_images/CR_workshop_setup.png differ diff --git a/branch/cff/singlehtml/_images/community.png b/branch/cff/singlehtml/_images/community.png new file mode 100644 index 0000000..ddd9a62 Binary files /dev/null and b/branch/cff/singlehtml/_images/community.png differ diff --git a/branch/cff/singlehtml/_images/hackmd--controls.png b/branch/cff/singlehtml/_images/hackmd--controls.png new file mode 100644 index 0000000..46a74c7 Binary files /dev/null and b/branch/cff/singlehtml/_images/hackmd--controls.png differ diff --git a/branch/cff/singlehtml/_images/hackmd--full-demo.png b/branch/cff/singlehtml/_images/hackmd--full-demo.png new file mode 100644 index 0000000..0988b6f Binary files /dev/null and b/branch/cff/singlehtml/_images/hackmd--full-demo.png differ diff --git a/branch/cff/singlehtml/_images/hackmd--questions2.png b/branch/cff/singlehtml/_images/hackmd--questions2.png new file mode 100644 index 0000000..a609199 Binary files /dev/null and b/branch/cff/singlehtml/_images/hackmd--questions2.png differ diff --git a/branch/cff/singlehtml/_images/history-landscape-dark.png b/branch/cff/singlehtml/_images/history-landscape-dark.png new file mode 100644 index 0000000..a1aef3c Binary files /dev/null and b/branch/cff/singlehtml/_images/history-landscape-dark.png differ diff --git a/branch/cff/singlehtml/_images/history-portrait-dark.png b/branch/cff/singlehtml/_images/history-portrait-dark.png new file mode 100644 index 0000000..2fc1fa6 Binary files /dev/null and b/branch/cff/singlehtml/_images/history-portrait-dark.png differ diff --git a/branch/cff/singlehtml/_images/history-portrait-light.png b/branch/cff/singlehtml/_images/history-portrait-light.png new file mode 100644 index 0000000..5f4361c Binary files /dev/null and b/branch/cff/singlehtml/_images/history-portrait-light.png differ diff --git a/branch/cff/singlehtml/_images/history-portrait.png b/branch/cff/singlehtml/_images/history-portrait.png new file mode 100644 index 0000000..28e18b0 Binary files /dev/null and b/branch/cff/singlehtml/_images/history-portrait.png differ diff --git a/branch/cff/singlehtml/_images/history-rsh.png b/branch/cff/singlehtml/_images/history-rsh.png new file mode 100644 index 0000000..1bbb1cc Binary files /dev/null and b/branch/cff/singlehtml/_images/history-rsh.png differ diff --git a/branch/cff/singlehtml/_images/instructor.png b/branch/cff/singlehtml/_images/instructor.png new file mode 100644 index 0000000..718f2a8 Binary files /dev/null and b/branch/cff/singlehtml/_images/instructor.png differ diff --git a/branch/cff/singlehtml/_images/landscape.png b/branch/cff/singlehtml/_images/landscape.png new file mode 100644 index 0000000..eda9d42 Binary files /dev/null and b/branch/cff/singlehtml/_images/landscape.png differ diff --git a/branch/cff/singlehtml/_images/learner-large.png b/branch/cff/singlehtml/_images/learner-large.png new file mode 100644 index 0000000..3b6d2cd Binary files /dev/null and b/branch/cff/singlehtml/_images/learner-large.png differ diff --git a/branch/cff/singlehtml/_images/learner-normal.png b/branch/cff/singlehtml/_images/learner-normal.png new file mode 100644 index 0000000..590135e Binary files /dev/null and b/branch/cff/singlehtml/_images/learner-normal.png differ diff --git a/branch/cff/singlehtml/_images/learner-small.png b/branch/cff/singlehtml/_images/learner-small.png new file mode 100644 index 0000000..5d5f421 Binary files /dev/null and b/branch/cff/singlehtml/_images/learner-small.png differ diff --git a/branch/cff/singlehtml/_images/portrait.png b/branch/cff/singlehtml/_images/portrait.png new file mode 100644 index 0000000..415799f Binary files /dev/null and b/branch/cff/singlehtml/_images/portrait.png differ diff --git a/branch/cff/singlehtml/_images/steps.png b/branch/cff/singlehtml/_images/steps.png new file mode 100644 index 0000000..6c978b5 Binary files /dev/null and b/branch/cff/singlehtml/_images/steps.png differ diff --git a/branch/cff/singlehtml/_images/survey-impact1.png b/branch/cff/singlehtml/_images/survey-impact1.png new file mode 100644 index 0000000..7dd0ddc Binary files /dev/null and b/branch/cff/singlehtml/_images/survey-impact1.png differ diff --git a/branch/cff/singlehtml/_images/survey-impact2.png b/branch/cff/singlehtml/_images/survey-impact2.png new file mode 100644 index 0000000..8771bff Binary files /dev/null and b/branch/cff/singlehtml/_images/survey-impact2.png differ diff --git a/branch/cff/singlehtml/_images/welcome.png b/branch/cff/singlehtml/_images/welcome.png new file mode 100644 index 0000000..302082c Binary files /dev/null and b/branch/cff/singlehtml/_images/welcome.png differ diff --git a/branch/cff/singlehtml/_sphinx_design_static/design-tabs.js b/branch/cff/singlehtml/_sphinx_design_static/design-tabs.js new file mode 100644 index 0000000..b25bd6a --- /dev/null +++ b/branch/cff/singlehtml/_sphinx_design_static/design-tabs.js @@ -0,0 +1,101 @@ +// @ts-check + +// Extra JS capability for selected tabs to be synced +// The selection is stored in local storage so that it persists across page loads. + +/** + * @type {Record} + */ +let sd_id_to_elements = {}; +const storageKeyPrefix = "sphinx-design-tab-id-"; + +/** + * Create a key for a tab element. + * @param {HTMLElement} el - The tab element. + * @returns {[string, string, string] | null} - The key. + * + */ +function create_key(el) { + let syncId = el.getAttribute("data-sync-id"); + let syncGroup = el.getAttribute("data-sync-group"); + if (!syncId || !syncGroup) return null; + return [syncGroup, syncId, syncGroup + "--" + syncId]; +} + +/** + * Initialize the tab selection. + * + */ +function ready() { + // Find all tabs with sync data + + /** @type {string[]} */ + let groups = []; + + document.querySelectorAll(".sd-tab-label").forEach((label) => { + if (label instanceof HTMLElement) { + let data = create_key(label); + if (data) { + let [group, id, key] = data; + + // add click event listener + // @ts-ignore + label.onclick = onSDLabelClick; + + // store map of key to elements + if (!sd_id_to_elements[key]) { + sd_id_to_elements[key] = []; + } + sd_id_to_elements[key].push(label); + + if (groups.indexOf(group) === -1) { + groups.push(group); + // Check if a specific tab has been selected via URL parameter + const tabParam = new URLSearchParams(window.location.search).get( + group + ); + if (tabParam) { + console.log( + "sphinx-design: Selecting tab id for group '" + + group + + "' from URL parameter: " + + tabParam + ); + window.sessionStorage.setItem(storageKeyPrefix + group, tabParam); + } + } + + // Check is a specific tab has been selected previously + let previousId = window.sessionStorage.getItem( + storageKeyPrefix + group + ); + if (previousId === id) { + // console.log( + // "sphinx-design: Selecting tab from session storage: " + id + // ); + // @ts-ignore + label.previousElementSibling.checked = true; + } + } + } + }); +} + +/** + * Activate other tabs with the same sync id. + * + * @this {HTMLElement} - The element that was clicked. + */ +function onSDLabelClick() { + let data = create_key(this); + if (!data) return; + let [group, id, key] = data; + for (const label of sd_id_to_elements[key]) { + if (label === this) continue; + // @ts-ignore + label.previousElementSibling.checked = true; + } + window.sessionStorage.setItem(storageKeyPrefix + group, id); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/branch/cff/singlehtml/_sphinx_design_static/sphinx-design.min.css b/branch/cff/singlehtml/_sphinx_design_static/sphinx-design.min.css new file mode 100644 index 0000000..860c36d --- /dev/null +++ b/branch/cff/singlehtml/_sphinx_design_static/sphinx-design.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative;font-size:var(--sd-fontsize-dropdown)}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary.sd-summary-title{padding:.5em .6em .5em 1em;font-size:var(--sd-fontsize-dropdown-title);font-weight:var(--sd-fontweight-dropdown-title);user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;list-style:none;display:inline-flex;justify-content:space-between}details.sd-dropdown summary.sd-summary-title::-webkit-details-marker{display:none}details.sd-dropdown summary.sd-summary-title:focus{outline:none}details.sd-dropdown summary.sd-summary-title .sd-summary-icon{margin-right:.6em;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary.sd-summary-title .sd-summary-text{flex-grow:1;line-height:1.5;padding-right:.5rem}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker{pointer-events:none;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker svg{opacity:.6}details.sd-dropdown summary.sd-summary-title:hover .sd-summary-state-marker svg{opacity:1;transform:scale(1.1)}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown .sd-summary-chevron-right{transition:.25s}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-right{transform:rotate(90deg)}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-down{transform:rotate(180deg)}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-bg: rgba(0, 113, 188, 0.2);--sd-color-secondary-bg: rgba(108, 117, 125, 0.2);--sd-color-success-bg: rgba(40, 167, 69, 0.2);--sd-color-info-bg: rgba(23, 162, 184, 0.2);--sd-color-warning-bg: rgba(240, 179, 126, 0.2);--sd-color-danger-bg: rgba(220, 53, 69, 0.2);--sd-color-light-bg: rgba(248, 249, 250, 0.2);--sd-color-muted-bg: rgba(108, 117, 125, 0.2);--sd-color-dark-bg: rgba(33, 37, 41, 0.2);--sd-color-black-bg: rgba(0, 0, 0, 0.2);--sd-color-white-bg: rgba(255, 255, 255, 0.2);--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem;--sd-fontsize-dropdown: inherit;--sd-fontsize-dropdown-title: 1rem;--sd-fontweight-dropdown-title: 700} diff --git a/branch/cff/singlehtml/_static/_sphinx_javascript_frameworks_compat.js b/branch/cff/singlehtml/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 0000000..8141580 --- /dev/null +++ b/branch/cff/singlehtml/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/branch/cff/singlehtml/_static/basic.css b/branch/cff/singlehtml/_static/basic.css new file mode 100644 index 0000000..f316efc --- /dev/null +++ b/branch/cff/singlehtml/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/branch/cff/singlehtml/_static/check-solid.svg b/branch/cff/singlehtml/_static/check-solid.svg new file mode 100644 index 0000000..92fad4b --- /dev/null +++ b/branch/cff/singlehtml/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/branch/cff/singlehtml/_static/clipboard.min.js b/branch/cff/singlehtml/_static/clipboard.min.js new file mode 100644 index 0000000..54b3c46 --- /dev/null +++ b/branch/cff/singlehtml/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/branch/cff/singlehtml/_static/copybutton.css b/branch/cff/singlehtml/_static/copybutton.css new file mode 100644 index 0000000..f1916ec --- /dev/null +++ b/branch/cff/singlehtml/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/branch/cff/singlehtml/_static/copybutton.js b/branch/cff/singlehtml/_static/copybutton.js new file mode 100644 index 0000000..2ea7ff3 --- /dev/null +++ b/branch/cff/singlehtml/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/branch/cff/singlehtml/_static/copybutton_funcs.js b/branch/cff/singlehtml/_static/copybutton_funcs.js new file mode 100644 index 0000000..dbe1aaa --- /dev/null +++ b/branch/cff/singlehtml/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/branch/cff/singlehtml/_static/css/badge_only.css b/branch/cff/singlehtml/_static/css/badge_only.css new file mode 100644 index 0000000..c718cee --- /dev/null +++ b/branch/cff/singlehtml/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/branch/cff/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff b/branch/cff/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/branch/cff/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/branch/cff/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff2 b/branch/cff/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/branch/cff/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/branch/cff/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff b/branch/cff/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/branch/cff/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/branch/cff/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff2 b/branch/cff/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/branch/cff/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/branch/cff/singlehtml/_static/css/fonts/fontawesome-webfont.eot b/branch/cff/singlehtml/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/branch/cff/singlehtml/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/branch/cff/singlehtml/_static/css/fonts/fontawesome-webfont.svg b/branch/cff/singlehtml/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/branch/cff/singlehtml/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/branch/cff/singlehtml/_static/css/fonts/fontawesome-webfont.ttf b/branch/cff/singlehtml/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/branch/cff/singlehtml/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/branch/cff/singlehtml/_static/css/fonts/fontawesome-webfont.woff b/branch/cff/singlehtml/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/branch/cff/singlehtml/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/branch/cff/singlehtml/_static/css/fonts/fontawesome-webfont.woff2 b/branch/cff/singlehtml/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/branch/cff/singlehtml/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/branch/cff/singlehtml/_static/css/fonts/lato-bold-italic.woff b/branch/cff/singlehtml/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/branch/cff/singlehtml/_static/css/fonts/lato-bold-italic.woff differ diff --git a/branch/cff/singlehtml/_static/css/fonts/lato-bold-italic.woff2 b/branch/cff/singlehtml/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/branch/cff/singlehtml/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/branch/cff/singlehtml/_static/css/fonts/lato-bold.woff b/branch/cff/singlehtml/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/branch/cff/singlehtml/_static/css/fonts/lato-bold.woff differ diff --git a/branch/cff/singlehtml/_static/css/fonts/lato-bold.woff2 b/branch/cff/singlehtml/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/branch/cff/singlehtml/_static/css/fonts/lato-bold.woff2 differ diff --git a/branch/cff/singlehtml/_static/css/fonts/lato-normal-italic.woff b/branch/cff/singlehtml/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/branch/cff/singlehtml/_static/css/fonts/lato-normal-italic.woff differ diff --git a/branch/cff/singlehtml/_static/css/fonts/lato-normal-italic.woff2 b/branch/cff/singlehtml/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/branch/cff/singlehtml/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/branch/cff/singlehtml/_static/css/fonts/lato-normal.woff b/branch/cff/singlehtml/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/branch/cff/singlehtml/_static/css/fonts/lato-normal.woff differ diff --git a/branch/cff/singlehtml/_static/css/fonts/lato-normal.woff2 b/branch/cff/singlehtml/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/branch/cff/singlehtml/_static/css/fonts/lato-normal.woff2 differ diff --git a/branch/cff/singlehtml/_static/css/theme.css b/branch/cff/singlehtml/_static/css/theme.css new file mode 100644 index 0000000..19a446a --- /dev/null +++ b/branch/cff/singlehtml/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/branch/cff/singlehtml/_static/design-tabs.js b/branch/cff/singlehtml/_static/design-tabs.js new file mode 100644 index 0000000..b25bd6a --- /dev/null +++ b/branch/cff/singlehtml/_static/design-tabs.js @@ -0,0 +1,101 @@ +// @ts-check + +// Extra JS capability for selected tabs to be synced +// The selection is stored in local storage so that it persists across page loads. + +/** + * @type {Record} + */ +let sd_id_to_elements = {}; +const storageKeyPrefix = "sphinx-design-tab-id-"; + +/** + * Create a key for a tab element. + * @param {HTMLElement} el - The tab element. + * @returns {[string, string, string] | null} - The key. + * + */ +function create_key(el) { + let syncId = el.getAttribute("data-sync-id"); + let syncGroup = el.getAttribute("data-sync-group"); + if (!syncId || !syncGroup) return null; + return [syncGroup, syncId, syncGroup + "--" + syncId]; +} + +/** + * Initialize the tab selection. + * + */ +function ready() { + // Find all tabs with sync data + + /** @type {string[]} */ + let groups = []; + + document.querySelectorAll(".sd-tab-label").forEach((label) => { + if (label instanceof HTMLElement) { + let data = create_key(label); + if (data) { + let [group, id, key] = data; + + // add click event listener + // @ts-ignore + label.onclick = onSDLabelClick; + + // store map of key to elements + if (!sd_id_to_elements[key]) { + sd_id_to_elements[key] = []; + } + sd_id_to_elements[key].push(label); + + if (groups.indexOf(group) === -1) { + groups.push(group); + // Check if a specific tab has been selected via URL parameter + const tabParam = new URLSearchParams(window.location.search).get( + group + ); + if (tabParam) { + console.log( + "sphinx-design: Selecting tab id for group '" + + group + + "' from URL parameter: " + + tabParam + ); + window.sessionStorage.setItem(storageKeyPrefix + group, tabParam); + } + } + + // Check is a specific tab has been selected previously + let previousId = window.sessionStorage.getItem( + storageKeyPrefix + group + ); + if (previousId === id) { + // console.log( + // "sphinx-design: Selecting tab from session storage: " + id + // ); + // @ts-ignore + label.previousElementSibling.checked = true; + } + } + } + }); +} + +/** + * Activate other tabs with the same sync id. + * + * @this {HTMLElement} - The element that was clicked. + */ +function onSDLabelClick() { + let data = create_key(this); + if (!data) return; + let [group, id, key] = data; + for (const label of sd_id_to_elements[key]) { + if (label === this) continue; + // @ts-ignore + label.previousElementSibling.checked = true; + } + window.sessionStorage.setItem(storageKeyPrefix + group, id); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/branch/cff/singlehtml/_static/doctools.js b/branch/cff/singlehtml/_static/doctools.js new file mode 100644 index 0000000..4d67807 --- /dev/null +++ b/branch/cff/singlehtml/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/branch/cff/singlehtml/_static/documentation_options.js b/branch/cff/singlehtml/_static/documentation_options.js new file mode 100644 index 0000000..89003c6 --- /dev/null +++ b/branch/cff/singlehtml/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'singlehtml', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/branch/cff/singlehtml/_static/file.png b/branch/cff/singlehtml/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/branch/cff/singlehtml/_static/file.png differ diff --git a/branch/cff/singlehtml/_static/jquery.js b/branch/cff/singlehtml/_static/jquery.js new file mode 100644 index 0000000..c4c6022 --- /dev/null +++ b/branch/cff/singlehtml/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!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(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=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,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).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 w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\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(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.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,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){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 H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.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--)b.attrHandle[n[r]]=t}function pe(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 de(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 d=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")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.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}},b.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[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.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},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),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(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.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},j=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)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(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==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(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?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{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 G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.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("(^|"+M+")"+e+"("+M+"|$)"))&&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:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.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 S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(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").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.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),m(t)&&(t=t.call(e,n,S.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)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.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"===S.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"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.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)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.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?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.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)}}),S.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){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/cff/singlehtml/_static/js/html5shiv.min.js b/branch/cff/singlehtml/_static/js/html5shiv.min.js new file mode 100644 index 0000000..cd1c674 --- /dev/null +++ b/branch/cff/singlehtml/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/cff/singlehtml/_static/js/theme.js b/branch/cff/singlehtml/_static/js/theme.js new file mode 100644 index 0000000..1fddb6e --- /dev/null +++ b/branch/cff/singlehtml/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/branch/cff/singlehtml/_static/minipres.js b/branch/cff/singlehtml/_static/minipres.js new file mode 100644 index 0000000..ad11c87 --- /dev/null +++ b/branch/cff/singlehtml/_static/minipres.js @@ -0,0 +1,223 @@ +// Add goTo method to elements +// http://stackoverflow.com/questions/4801655/how-to-go-to-a-specific-element-on-page +(function($) { + $.fn.goTo = function() { + $('html, body').animate({ + scrollTop: $(this).offset().top //+ 'px' + }, 'fast'); + return this; // for chaining... + } +})(jQuery); + +// NO good way to do this!. Copy a hack from here +// https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript +// https://stackoverflow.com/a/2880929 +var urlParams; +(window.onpopstate = function () { + var match, + pl = /\+/g, // Regex for replacing addition symbol with a space + search = /([^&=]+)=?([^&]*)/g, + decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, + query = window.location.search.substring(1); + urlParams = {}; + while (match = search.exec(query)) + urlParams[decode(match[1])] = decode(match[2]); +})(); + +// Select heading levels +var maxHeading = urlParams['h'] +if (maxHeading === undefined) maxHeading = 2 +var headingLevels = []; +for (h=2 ; h (sections.length-1) ) { + // if we would scroll past bottom, or above top, do nothing + return; + } + + console.log('xxxxxx'); + var targetSection = sections[targetPos]; + console.log(targetSection, typeof(targetSection)); + + // Return targetSection top and height + var secProperties = section_top_and_height(targetSection); + var top = secProperties['top']; + var height = secProperties['height'] + var win_height = window.innerHeight; + //console.info(top, height, win_height) + + var scroll_to = 0; + if (height >= win_height || height == 0) { + scroll_to = top; + } else { + scroll_to = top - (win_height-height)/3.; + } + //console.info(top, height, win_height, scroll_to) + + $('html, body').animate({ + scrollTop: scroll_to //+ 'px' + }, 'fast'); + +} + + +function minipres() { + /* Enable the minipres mode: + - call the hide() function + - set up the scrolling listener + */ + document.addEventListener('keydown', function (event) { + switch(event.which) { + case 37: // left + switch_slide(-1); + event.preventDefault(); + return false; + break; + //case 38: // up + case 39: // right + switch_slide(+1); + event.preventDefault(); + return false; + break; + //case 40: // down + default: + return; // exit this handler for other keys + } + }, true) + + hide() + + // Increase space between sections + //$("div .section").css('margin-bottom', '50%'); + $(sectionSelector).css('margin-top', '50%'); + + // Reduce size/color of other sections + if (hiddenSectionSelector.length > 0) { + var hideNodes = $(hiddenSectionSelector); + console.log(typeof hideNodes, hideNodes); + for (node in hideNodes) { + console.log("a", typeof node, node); + node = hideNodes[node]; // what's right way to iterate values? + console.log("b", typeof node, node); + if (node.parentNode && node.parentNode.className == "section") { + node = node.parentNode; + console.log("c", typeof node, node); + //node.css['transform'] = 'scale(.5)'; + //node.css['transform-origin'] = 'top center'; + $(node).css('color', 'lightgrey'); + //$(node).css('font-size', '20%'); + //$(node).css('visibility', 'collapse'); + //ntahousnatouhasno; + } + } + } +} + +function hide() { + /* Hide all non-essential elements on the page + */ + + // This is for sphinx_rst_theme and readthedocs + $(".wy-nav-side").remove(); + $(".wy-nav-content-wrap").css('margin-left', 0); + $('.rst-versions').remove(); // readthedocs version selector + + // Add other formats here. +} + + +var slideshow = minipres; + +if (window.location.search.match(/[?&](minipres|slideshow|pres)([=&]|$)/) ) { + //minipres() + window.addEventListener("load", minipres); +} else if (window.location.search.match(/[?&](plain)([=&]|$)/) ) { + window.addEventListener("load", hide); +} diff --git a/branch/cff/singlehtml/_static/minus.png b/branch/cff/singlehtml/_static/minus.png new file mode 100644 index 0000000..d96755f Binary files /dev/null and b/branch/cff/singlehtml/_static/minus.png differ diff --git a/branch/cff/singlehtml/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css b/branch/cff/singlehtml/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css new file mode 100644 index 0000000..3356631 --- /dev/null +++ b/branch/cff/singlehtml/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css @@ -0,0 +1,2342 @@ +/* Variables */ +:root { + --mystnb-source-bg-color: #f7f7f7; + --mystnb-stdout-bg-color: #fcfcfc; + --mystnb-stderr-bg-color: #fdd; + --mystnb-traceback-bg-color: #fcfcfc; + --mystnb-source-border-color: #ccc; + --mystnb-source-margin-color: green; + --mystnb-stdout-border-color: #f7f7f7; + --mystnb-stderr-border-color: #f7f7f7; + --mystnb-traceback-border-color: #ffd6d6; + --mystnb-hide-prompt-opacity: 70%; + --mystnb-source-border-radius: .4em; + --mystnb-source-border-width: 1px; +} + +/* Whole cell */ +div.container.cell { + padding-left: 0; + margin-bottom: 1em; +} + +/* Removing all background formatting so we can control at the div level */ +.cell_input div.highlight, +.cell_output pre, +.cell_input pre, +.cell_output .output { + border: none; + box-shadow: none; +} + +.cell_output .output pre, +.cell_input pre { + margin: 0px; +} + +/* Input cells */ +div.cell div.cell_input, +div.cell details.above-input>summary { + padding-left: 0em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + background-color: var(--mystnb-source-bg-color); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; + border-radius: var(--mystnb-source-border-radius); +} + +div.cell_input>div, +div.cell_output div.output>div.highlight { + margin: 0em !important; + border: none !important; +} + +/* All cell outputs */ +.cell_output { + padding-left: 1em; + padding-right: 0em; + margin-top: 1em; +} + +/* Text outputs from cells */ +.cell_output .output.text_plain, +.cell_output .output.traceback, +.cell_output .output.stream, +.cell_output .output.stderr { + margin-top: 1em; + margin-bottom: 0em; + box-shadow: none; +} + +.cell_output .output.text_plain, +.cell_output .output.stream { + background: var(--mystnb-stdout-bg-color); + border: 1px solid var(--mystnb-stdout-border-color); +} + +.cell_output .output.stderr { + background: var(--mystnb-stderr-bg-color); + border: 1px solid var(--mystnb-stderr-border-color); +} + +.cell_output .output.traceback { + background: var(--mystnb-traceback-bg-color); + border: 1px solid var(--mystnb-traceback-border-color); +} + +/* Collapsible cell content */ +div.cell details.above-input div.cell_input { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-top: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; +} + +div.cell div.cell_input.above-output-prompt { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +div.cell details.above-input>summary { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; + padding-left: 1em; + margin-bottom: 0; +} + +div.cell details.above-output>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.below-input>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-top: none; + border-bottom-left-radius: var(--mystnb-source-border-radius); + border-bottom-right-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.hide>summary>span { + opacity: var(--mystnb-hide-prompt-opacity); +} + +div.cell details.hide[open]>summary>span.collapsed { + display: none; +} + +div.cell details.hide:not([open])>summary>span.expanded { + display: none; +} + +@keyframes collapsed-fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} +div.cell details.hide[open]>summary~* { + -moz-animation: collapsed-fade-in 0.3s ease-in-out; + -webkit-animation: collapsed-fade-in 0.3s ease-in-out; + animation: collapsed-fade-in 0.3s ease-in-out; +} + +/* Math align to the left */ +.cell_output .MathJax_Display { + text-align: left !important; +} + +/* Pandas tables. Pulled from the Jupyter / nbsphinx CSS */ +div.cell_output table { + border: none; + border-collapse: collapse; + border-spacing: 0; + color: black; + font-size: 1em; + table-layout: fixed; +} + +div.cell_output thead { + border-bottom: 1px solid black; + vertical-align: bottom; +} + +div.cell_output tr, +div.cell_output th, +div.cell_output td { + text-align: right; + vertical-align: middle; + padding: 0.5em 0.5em; + line-height: normal; + white-space: normal; + max-width: none; + border: none; +} + +div.cell_output th { + font-weight: bold; +} + +div.cell_output tbody tr:nth-child(odd) { + background: #f5f5f5; +} + +div.cell_output tbody tr:hover { + background: rgba(66, 165, 245, 0.2); +} + +/** source code line numbers **/ +span.linenos { + opacity: 0.5; +} + +/* Inline text from `paste` operation */ + +span.pasted-text { + font-weight: bold; +} + +span.pasted-inline img { + max-height: 2em; +} + +tbody span.pasted-inline img { + max-height: none; +} + +/* Font colors for translated ANSI escape sequences +Color values are copied from Jupyter Notebook +https://github.com/jupyter/notebook/blob/52581f8eda9b319eb0390ac77fe5903c38f81e3e/notebook/static/notebook/less/ansicolors.less#L14-L21 +Background colors from +https://nbsphinx.readthedocs.io/en/latest/code-cells.html#ANSI-Colors +*/ +div.highlight .-Color-Bold { + font-weight: bold; +} + +div.highlight .-Color[class*=-Black] { + color: #3E424D +} + +div.highlight .-Color[class*=-Red] { + color: #E75C58 +} + +div.highlight .-Color[class*=-Green] { + color: #00A250 +} + +div.highlight .-Color[class*=-Yellow] { + color: #DDB62B +} + +div.highlight .-Color[class*=-Blue] { + color: #208FFB +} + +div.highlight .-Color[class*=-Magenta] { + color: #D160C4 +} + +div.highlight .-Color[class*=-Cyan] { + color: #60C6C8 +} + +div.highlight .-Color[class*=-White] { + color: #C5C1B4 +} + +div.highlight .-Color[class*=-BGBlack] { + background-color: #3E424D +} + +div.highlight .-Color[class*=-BGRed] { + background-color: #E75C58 +} + +div.highlight .-Color[class*=-BGGreen] { + background-color: #00A250 +} + +div.highlight .-Color[class*=-BGYellow] { + background-color: #DDB62B +} + +div.highlight .-Color[class*=-BGBlue] { + background-color: #208FFB +} + +div.highlight .-Color[class*=-BGMagenta] { + background-color: #D160C4 +} + +div.highlight .-Color[class*=-BGCyan] { + background-color: #60C6C8 +} + +div.highlight .-Color[class*=-BGWhite] { + background-color: #C5C1B4 +} + +/* Font colors for 8-bit ANSI */ + +div.highlight .-Color[class*=-C0] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC0] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C1] { + color: #800000 +} + +div.highlight .-Color[class*=-BGC1] { + background-color: #800000 +} + +div.highlight .-Color[class*=-C2] { + color: #008000 +} + +div.highlight .-Color[class*=-BGC2] { + background-color: #008000 +} + +div.highlight .-Color[class*=-C3] { + color: #808000 +} + +div.highlight .-Color[class*=-BGC3] { + background-color: #808000 +} + +div.highlight .-Color[class*=-C4] { + color: #000080 +} + +div.highlight .-Color[class*=-BGC4] { + background-color: #000080 +} + +div.highlight .-Color[class*=-C5] { + color: #800080 +} + +div.highlight .-Color[class*=-BGC5] { + background-color: #800080 +} + +div.highlight .-Color[class*=-C6] { + color: #008080 +} + +div.highlight .-Color[class*=-BGC6] { + background-color: #008080 +} + +div.highlight .-Color[class*=-C7] { + color: #C0C0C0 +} + +div.highlight .-Color[class*=-BGC7] { + background-color: #C0C0C0 +} + +div.highlight .-Color[class*=-C8] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC8] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C9] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC9] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C10] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC10] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C11] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC11] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C12] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC12] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C13] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC13] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C14] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC14] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C15] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC15] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C16] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC16] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C17] { + color: #00005F +} + +div.highlight .-Color[class*=-BGC17] { + background-color: #00005F +} + +div.highlight .-Color[class*=-C18] { + color: #000087 +} + +div.highlight .-Color[class*=-BGC18] { + background-color: #000087 +} + +div.highlight .-Color[class*=-C19] { + color: #0000AF +} + +div.highlight .-Color[class*=-BGC19] { + background-color: #0000AF +} + +div.highlight .-Color[class*=-C20] { + color: #0000D7 +} + +div.highlight .-Color[class*=-BGC20] { + background-color: #0000D7 +} + +div.highlight .-Color[class*=-C21] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC21] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C22] { + color: #005F00 +} + +div.highlight .-Color[class*=-BGC22] { + background-color: #005F00 +} + +div.highlight .-Color[class*=-C23] { + color: #005F5F +} + +div.highlight .-Color[class*=-BGC23] { + background-color: #005F5F +} + +div.highlight .-Color[class*=-C24] { + color: #005F87 +} + +div.highlight .-Color[class*=-BGC24] { + background-color: #005F87 +} + +div.highlight .-Color[class*=-C25] { + color: #005FAF +} + +div.highlight .-Color[class*=-BGC25] { + background-color: #005FAF +} + +div.highlight .-Color[class*=-C26] { + color: #005FD7 +} + +div.highlight .-Color[class*=-BGC26] { + background-color: #005FD7 +} + +div.highlight .-Color[class*=-C27] { + color: #005FFF +} + +div.highlight .-Color[class*=-BGC27] { + background-color: #005FFF +} + +div.highlight .-Color[class*=-C28] { + color: #008700 +} + +div.highlight .-Color[class*=-BGC28] { + background-color: #008700 +} + +div.highlight .-Color[class*=-C29] { + color: #00875F +} + +div.highlight .-Color[class*=-BGC29] { + background-color: #00875F +} + +div.highlight .-Color[class*=-C30] { + color: #008787 +} + +div.highlight .-Color[class*=-BGC30] { + background-color: #008787 +} + +div.highlight .-Color[class*=-C31] { + color: #0087AF +} + +div.highlight .-Color[class*=-BGC31] { + background-color: #0087AF +} + +div.highlight .-Color[class*=-C32] { + color: #0087D7 +} + +div.highlight .-Color[class*=-BGC32] { + background-color: #0087D7 +} + +div.highlight .-Color[class*=-C33] { + color: #0087FF +} + +div.highlight .-Color[class*=-BGC33] { + background-color: #0087FF +} + +div.highlight .-Color[class*=-C34] { + color: #00AF00 +} + +div.highlight .-Color[class*=-BGC34] { + background-color: #00AF00 +} + +div.highlight .-Color[class*=-C35] { + color: #00AF5F +} + +div.highlight .-Color[class*=-BGC35] { + background-color: #00AF5F +} + +div.highlight .-Color[class*=-C36] { + color: #00AF87 +} + +div.highlight .-Color[class*=-BGC36] { + background-color: #00AF87 +} + +div.highlight .-Color[class*=-C37] { + color: #00AFAF +} + +div.highlight .-Color[class*=-BGC37] { + background-color: #00AFAF +} + +div.highlight .-Color[class*=-C38] { + color: #00AFD7 +} + +div.highlight .-Color[class*=-BGC38] { + background-color: #00AFD7 +} + +div.highlight .-Color[class*=-C39] { + color: #00AFFF +} + +div.highlight .-Color[class*=-BGC39] { + background-color: #00AFFF +} + +div.highlight .-Color[class*=-C40] { + color: #00D700 +} + +div.highlight .-Color[class*=-BGC40] { + background-color: #00D700 +} + +div.highlight .-Color[class*=-C41] { + color: #00D75F +} + +div.highlight .-Color[class*=-BGC41] { + background-color: #00D75F +} + +div.highlight .-Color[class*=-C42] { + color: #00D787 +} + +div.highlight .-Color[class*=-BGC42] { + background-color: #00D787 +} + +div.highlight .-Color[class*=-C43] { + color: #00D7AF +} + +div.highlight .-Color[class*=-BGC43] { + background-color: #00D7AF +} + +div.highlight .-Color[class*=-C44] { + color: #00D7D7 +} + +div.highlight .-Color[class*=-BGC44] { + background-color: #00D7D7 +} + +div.highlight .-Color[class*=-C45] { + color: #00D7FF +} + +div.highlight .-Color[class*=-BGC45] { + background-color: #00D7FF +} + +div.highlight .-Color[class*=-C46] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC46] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C47] { + color: #00FF5F +} + +div.highlight .-Color[class*=-BGC47] { + background-color: #00FF5F +} + +div.highlight .-Color[class*=-C48] { + color: #00FF87 +} + +div.highlight .-Color[class*=-BGC48] { + background-color: #00FF87 +} + +div.highlight .-Color[class*=-C49] { + color: #00FFAF +} + +div.highlight .-Color[class*=-BGC49] { + background-color: #00FFAF +} + +div.highlight .-Color[class*=-C50] { + color: #00FFD7 +} + +div.highlight .-Color[class*=-BGC50] { + background-color: #00FFD7 +} + +div.highlight .-Color[class*=-C51] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC51] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C52] { + color: #5F0000 +} + +div.highlight .-Color[class*=-BGC52] { + background-color: #5F0000 +} + +div.highlight .-Color[class*=-C53] { + color: #5F005F +} + +div.highlight .-Color[class*=-BGC53] { + background-color: #5F005F +} + +div.highlight .-Color[class*=-C54] { + color: #5F0087 +} + +div.highlight .-Color[class*=-BGC54] { + background-color: #5F0087 +} + +div.highlight .-Color[class*=-C55] { + color: #5F00AF +} + +div.highlight .-Color[class*=-BGC55] { + background-color: #5F00AF +} + +div.highlight .-Color[class*=-C56] { + color: #5F00D7 +} + +div.highlight .-Color[class*=-BGC56] { + background-color: #5F00D7 +} + +div.highlight .-Color[class*=-C57] { + color: #5F00FF +} + +div.highlight .-Color[class*=-BGC57] { + background-color: #5F00FF +} + +div.highlight .-Color[class*=-C58] { + color: #5F5F00 +} + +div.highlight .-Color[class*=-BGC58] { + background-color: #5F5F00 +} + +div.highlight .-Color[class*=-C59] { + color: #5F5F5F +} + +div.highlight .-Color[class*=-BGC59] { + background-color: #5F5F5F +} + +div.highlight .-Color[class*=-C60] { + color: #5F5F87 +} + +div.highlight .-Color[class*=-BGC60] { + background-color: #5F5F87 +} + +div.highlight .-Color[class*=-C61] { + color: #5F5FAF +} + +div.highlight .-Color[class*=-BGC61] { + background-color: #5F5FAF +} + +div.highlight .-Color[class*=-C62] { + color: #5F5FD7 +} + +div.highlight .-Color[class*=-BGC62] { + background-color: #5F5FD7 +} + +div.highlight .-Color[class*=-C63] { + color: #5F5FFF +} + +div.highlight .-Color[class*=-BGC63] { + background-color: #5F5FFF +} + +div.highlight .-Color[class*=-C64] { + color: #5F8700 +} + +div.highlight .-Color[class*=-BGC64] { + background-color: #5F8700 +} + +div.highlight .-Color[class*=-C65] { + color: #5F875F +} + +div.highlight .-Color[class*=-BGC65] { + background-color: #5F875F +} + +div.highlight .-Color[class*=-C66] { + color: #5F8787 +} + +div.highlight .-Color[class*=-BGC66] { + background-color: #5F8787 +} + +div.highlight .-Color[class*=-C67] { + color: #5F87AF +} + +div.highlight .-Color[class*=-BGC67] { + background-color: #5F87AF +} + +div.highlight .-Color[class*=-C68] { + color: #5F87D7 +} + +div.highlight .-Color[class*=-BGC68] { + background-color: #5F87D7 +} + +div.highlight .-Color[class*=-C69] { + color: #5F87FF +} + +div.highlight .-Color[class*=-BGC69] { + background-color: #5F87FF +} + +div.highlight .-Color[class*=-C70] { + color: #5FAF00 +} + +div.highlight .-Color[class*=-BGC70] { + background-color: #5FAF00 +} + +div.highlight .-Color[class*=-C71] { + color: #5FAF5F +} + +div.highlight .-Color[class*=-BGC71] { + background-color: #5FAF5F +} + +div.highlight .-Color[class*=-C72] { + color: #5FAF87 +} + +div.highlight .-Color[class*=-BGC72] { + background-color: #5FAF87 +} + +div.highlight .-Color[class*=-C73] { + color: #5FAFAF +} + +div.highlight .-Color[class*=-BGC73] { + background-color: #5FAFAF +} + +div.highlight .-Color[class*=-C74] { + color: #5FAFD7 +} + +div.highlight .-Color[class*=-BGC74] { + background-color: #5FAFD7 +} + +div.highlight .-Color[class*=-C75] { + color: #5FAFFF +} + +div.highlight .-Color[class*=-BGC75] { + background-color: #5FAFFF +} + +div.highlight .-Color[class*=-C76] { + color: #5FD700 +} + +div.highlight .-Color[class*=-BGC76] { + background-color: #5FD700 +} + +div.highlight .-Color[class*=-C77] { + color: #5FD75F +} + +div.highlight .-Color[class*=-BGC77] { + background-color: #5FD75F +} + +div.highlight .-Color[class*=-C78] { + color: #5FD787 +} + +div.highlight .-Color[class*=-BGC78] { + background-color: #5FD787 +} + +div.highlight .-Color[class*=-C79] { + color: #5FD7AF +} + +div.highlight .-Color[class*=-BGC79] { + background-color: #5FD7AF +} + +div.highlight .-Color[class*=-C80] { + color: #5FD7D7 +} + +div.highlight .-Color[class*=-BGC80] { + background-color: #5FD7D7 +} + +div.highlight .-Color[class*=-C81] { + color: #5FD7FF +} + +div.highlight .-Color[class*=-BGC81] { + background-color: #5FD7FF +} + +div.highlight .-Color[class*=-C82] { + color: #5FFF00 +} + +div.highlight .-Color[class*=-BGC82] { + background-color: #5FFF00 +} + +div.highlight .-Color[class*=-C83] { + color: #5FFF5F +} + +div.highlight .-Color[class*=-BGC83] { + background-color: #5FFF5F +} + +div.highlight .-Color[class*=-C84] { + color: #5FFF87 +} + +div.highlight .-Color[class*=-BGC84] { + background-color: #5FFF87 +} + +div.highlight .-Color[class*=-C85] { + color: #5FFFAF +} + +div.highlight .-Color[class*=-BGC85] { + background-color: #5FFFAF +} + +div.highlight .-Color[class*=-C86] { + color: #5FFFD7 +} + +div.highlight .-Color[class*=-BGC86] { + background-color: #5FFFD7 +} + +div.highlight .-Color[class*=-C87] { + color: #5FFFFF +} + +div.highlight .-Color[class*=-BGC87] { + background-color: #5FFFFF +} + +div.highlight .-Color[class*=-C88] { + color: #870000 +} + +div.highlight .-Color[class*=-BGC88] { + background-color: #870000 +} + +div.highlight .-Color[class*=-C89] { + color: #87005F +} + +div.highlight .-Color[class*=-BGC89] { + background-color: #87005F +} + +div.highlight .-Color[class*=-C90] { + color: #870087 +} + +div.highlight .-Color[class*=-BGC90] { + background-color: #870087 +} + +div.highlight .-Color[class*=-C91] { + color: #8700AF +} + +div.highlight .-Color[class*=-BGC91] { + background-color: #8700AF +} + +div.highlight .-Color[class*=-C92] { + color: #8700D7 +} + +div.highlight .-Color[class*=-BGC92] { + background-color: #8700D7 +} + +div.highlight .-Color[class*=-C93] { + color: #8700FF +} + +div.highlight .-Color[class*=-BGC93] { + background-color: #8700FF +} + +div.highlight .-Color[class*=-C94] { + color: #875F00 +} + +div.highlight .-Color[class*=-BGC94] { + background-color: #875F00 +} + +div.highlight .-Color[class*=-C95] { + color: #875F5F +} + +div.highlight .-Color[class*=-BGC95] { + background-color: #875F5F +} + +div.highlight .-Color[class*=-C96] { + color: #875F87 +} + +div.highlight .-Color[class*=-BGC96] { + background-color: #875F87 +} + +div.highlight .-Color[class*=-C97] { + color: #875FAF +} + +div.highlight .-Color[class*=-BGC97] { + background-color: #875FAF +} + +div.highlight .-Color[class*=-C98] { + color: #875FD7 +} + +div.highlight .-Color[class*=-BGC98] { + background-color: #875FD7 +} + +div.highlight .-Color[class*=-C99] { + color: #875FFF +} + +div.highlight .-Color[class*=-BGC99] { + background-color: #875FFF +} + +div.highlight .-Color[class*=-C100] { + color: #878700 +} + +div.highlight .-Color[class*=-BGC100] { + background-color: #878700 +} + +div.highlight .-Color[class*=-C101] { + color: #87875F +} + +div.highlight .-Color[class*=-BGC101] { + background-color: #87875F +} + +div.highlight .-Color[class*=-C102] { + color: #878787 +} + +div.highlight .-Color[class*=-BGC102] { + background-color: #878787 +} + +div.highlight .-Color[class*=-C103] { + color: #8787AF +} + +div.highlight .-Color[class*=-BGC103] { + background-color: #8787AF +} + +div.highlight .-Color[class*=-C104] { + color: #8787D7 +} + +div.highlight .-Color[class*=-BGC104] { + background-color: #8787D7 +} + +div.highlight .-Color[class*=-C105] { + color: #8787FF +} + +div.highlight .-Color[class*=-BGC105] { + background-color: #8787FF +} + +div.highlight .-Color[class*=-C106] { + color: #87AF00 +} + +div.highlight .-Color[class*=-BGC106] { + background-color: #87AF00 +} + +div.highlight .-Color[class*=-C107] { + color: #87AF5F +} + +div.highlight .-Color[class*=-BGC107] { + background-color: #87AF5F +} + +div.highlight .-Color[class*=-C108] { + color: #87AF87 +} + +div.highlight .-Color[class*=-BGC108] { + background-color: #87AF87 +} + +div.highlight .-Color[class*=-C109] { + color: #87AFAF +} + +div.highlight .-Color[class*=-BGC109] { + background-color: #87AFAF +} + +div.highlight .-Color[class*=-C110] { + color: #87AFD7 +} + +div.highlight .-Color[class*=-BGC110] { + background-color: #87AFD7 +} + +div.highlight .-Color[class*=-C111] { + color: #87AFFF +} + +div.highlight .-Color[class*=-BGC111] { + background-color: #87AFFF +} + +div.highlight .-Color[class*=-C112] { + color: #87D700 +} + +div.highlight .-Color[class*=-BGC112] { + background-color: #87D700 +} + +div.highlight .-Color[class*=-C113] { + color: #87D75F +} + +div.highlight .-Color[class*=-BGC113] { + background-color: #87D75F +} + +div.highlight .-Color[class*=-C114] { + color: #87D787 +} + +div.highlight .-Color[class*=-BGC114] { + background-color: #87D787 +} + +div.highlight .-Color[class*=-C115] { + color: #87D7AF +} + +div.highlight .-Color[class*=-BGC115] { + background-color: #87D7AF +} + +div.highlight .-Color[class*=-C116] { + color: #87D7D7 +} + +div.highlight .-Color[class*=-BGC116] { + background-color: #87D7D7 +} + +div.highlight .-Color[class*=-C117] { + color: #87D7FF +} + +div.highlight .-Color[class*=-BGC117] { + background-color: #87D7FF +} + +div.highlight .-Color[class*=-C118] { + color: #87FF00 +} + +div.highlight .-Color[class*=-BGC118] { + background-color: #87FF00 +} + +div.highlight .-Color[class*=-C119] { + color: #87FF5F +} + +div.highlight .-Color[class*=-BGC119] { + background-color: #87FF5F +} + +div.highlight .-Color[class*=-C120] { + color: #87FF87 +} + +div.highlight .-Color[class*=-BGC120] { + background-color: #87FF87 +} + +div.highlight .-Color[class*=-C121] { + color: #87FFAF +} + +div.highlight .-Color[class*=-BGC121] { + background-color: #87FFAF +} + +div.highlight .-Color[class*=-C122] { + color: #87FFD7 +} + +div.highlight .-Color[class*=-BGC122] { + background-color: #87FFD7 +} + +div.highlight .-Color[class*=-C123] { + color: #87FFFF +} + +div.highlight .-Color[class*=-BGC123] { + background-color: #87FFFF +} + +div.highlight .-Color[class*=-C124] { + color: #AF0000 +} + +div.highlight .-Color[class*=-BGC124] { + background-color: #AF0000 +} + +div.highlight .-Color[class*=-C125] { + color: #AF005F +} + +div.highlight .-Color[class*=-BGC125] { + background-color: #AF005F +} + +div.highlight .-Color[class*=-C126] { + color: #AF0087 +} + +div.highlight .-Color[class*=-BGC126] { + background-color: #AF0087 +} + +div.highlight .-Color[class*=-C127] { + color: #AF00AF +} + +div.highlight .-Color[class*=-BGC127] { + background-color: #AF00AF +} + +div.highlight .-Color[class*=-C128] { + color: #AF00D7 +} + +div.highlight .-Color[class*=-BGC128] { + background-color: #AF00D7 +} + +div.highlight .-Color[class*=-C129] { + color: #AF00FF +} + +div.highlight .-Color[class*=-BGC129] { + background-color: #AF00FF +} + +div.highlight .-Color[class*=-C130] { + color: #AF5F00 +} + +div.highlight .-Color[class*=-BGC130] { + background-color: #AF5F00 +} + +div.highlight .-Color[class*=-C131] { + color: #AF5F5F +} + +div.highlight .-Color[class*=-BGC131] { + background-color: #AF5F5F +} + +div.highlight .-Color[class*=-C132] { + color: #AF5F87 +} + +div.highlight .-Color[class*=-BGC132] { + background-color: #AF5F87 +} + +div.highlight .-Color[class*=-C133] { + color: #AF5FAF +} + +div.highlight .-Color[class*=-BGC133] { + background-color: #AF5FAF +} + +div.highlight .-Color[class*=-C134] { + color: #AF5FD7 +} + +div.highlight .-Color[class*=-BGC134] { + background-color: #AF5FD7 +} + +div.highlight .-Color[class*=-C135] { + color: #AF5FFF +} + +div.highlight .-Color[class*=-BGC135] { + background-color: #AF5FFF +} + +div.highlight .-Color[class*=-C136] { + color: #AF8700 +} + +div.highlight .-Color[class*=-BGC136] { + background-color: #AF8700 +} + +div.highlight .-Color[class*=-C137] { + color: #AF875F +} + +div.highlight .-Color[class*=-BGC137] { + background-color: #AF875F +} + +div.highlight .-Color[class*=-C138] { + color: #AF8787 +} + +div.highlight .-Color[class*=-BGC138] { + background-color: #AF8787 +} + +div.highlight .-Color[class*=-C139] { + color: #AF87AF +} + +div.highlight .-Color[class*=-BGC139] { + background-color: #AF87AF +} + +div.highlight .-Color[class*=-C140] { + color: #AF87D7 +} + +div.highlight .-Color[class*=-BGC140] { + background-color: #AF87D7 +} + +div.highlight .-Color[class*=-C141] { + color: #AF87FF +} + +div.highlight .-Color[class*=-BGC141] { + background-color: #AF87FF +} + +div.highlight .-Color[class*=-C142] { + color: #AFAF00 +} + +div.highlight .-Color[class*=-BGC142] { + background-color: #AFAF00 +} + +div.highlight .-Color[class*=-C143] { + color: #AFAF5F +} + +div.highlight .-Color[class*=-BGC143] { + background-color: #AFAF5F +} + +div.highlight .-Color[class*=-C144] { + color: #AFAF87 +} + +div.highlight .-Color[class*=-BGC144] { + background-color: #AFAF87 +} + +div.highlight .-Color[class*=-C145] { + color: #AFAFAF +} + +div.highlight .-Color[class*=-BGC145] { + background-color: #AFAFAF +} + +div.highlight .-Color[class*=-C146] { + color: #AFAFD7 +} + +div.highlight .-Color[class*=-BGC146] { + background-color: #AFAFD7 +} + +div.highlight .-Color[class*=-C147] { + color: #AFAFFF +} + +div.highlight .-Color[class*=-BGC147] { + background-color: #AFAFFF +} + +div.highlight .-Color[class*=-C148] { + color: #AFD700 +} + +div.highlight .-Color[class*=-BGC148] { + background-color: #AFD700 +} + +div.highlight .-Color[class*=-C149] { + color: #AFD75F +} + +div.highlight .-Color[class*=-BGC149] { + background-color: #AFD75F +} + +div.highlight .-Color[class*=-C150] { + color: #AFD787 +} + +div.highlight .-Color[class*=-BGC150] { + background-color: #AFD787 +} + +div.highlight .-Color[class*=-C151] { + color: #AFD7AF +} + +div.highlight .-Color[class*=-BGC151] { + background-color: #AFD7AF +} + +div.highlight .-Color[class*=-C152] { + color: #AFD7D7 +} + +div.highlight .-Color[class*=-BGC152] { + background-color: #AFD7D7 +} + +div.highlight .-Color[class*=-C153] { + color: #AFD7FF +} + +div.highlight .-Color[class*=-BGC153] { + background-color: #AFD7FF +} + +div.highlight .-Color[class*=-C154] { + color: #AFFF00 +} + +div.highlight .-Color[class*=-BGC154] { + background-color: #AFFF00 +} + +div.highlight .-Color[class*=-C155] { + color: #AFFF5F +} + +div.highlight .-Color[class*=-BGC155] { + background-color: #AFFF5F +} + +div.highlight .-Color[class*=-C156] { + color: #AFFF87 +} + +div.highlight .-Color[class*=-BGC156] { + background-color: #AFFF87 +} + +div.highlight .-Color[class*=-C157] { + color: #AFFFAF +} + +div.highlight .-Color[class*=-BGC157] { + background-color: #AFFFAF +} + +div.highlight .-Color[class*=-C158] { + color: #AFFFD7 +} + +div.highlight .-Color[class*=-BGC158] { + background-color: #AFFFD7 +} + +div.highlight .-Color[class*=-C159] { + color: #AFFFFF +} + +div.highlight .-Color[class*=-BGC159] { + background-color: #AFFFFF +} + +div.highlight .-Color[class*=-C160] { + color: #D70000 +} + +div.highlight .-Color[class*=-BGC160] { + background-color: #D70000 +} + +div.highlight .-Color[class*=-C161] { + color: #D7005F +} + +div.highlight .-Color[class*=-BGC161] { + background-color: #D7005F +} + +div.highlight .-Color[class*=-C162] { + color: #D70087 +} + +div.highlight .-Color[class*=-BGC162] { + background-color: #D70087 +} + +div.highlight .-Color[class*=-C163] { + color: #D700AF +} + +div.highlight .-Color[class*=-BGC163] { + background-color: #D700AF +} + +div.highlight .-Color[class*=-C164] { + color: #D700D7 +} + +div.highlight .-Color[class*=-BGC164] { + background-color: #D700D7 +} + +div.highlight .-Color[class*=-C165] { + color: #D700FF +} + +div.highlight .-Color[class*=-BGC165] { + background-color: #D700FF +} + +div.highlight .-Color[class*=-C166] { + color: #D75F00 +} + +div.highlight .-Color[class*=-BGC166] { + background-color: #D75F00 +} + +div.highlight .-Color[class*=-C167] { + color: #D75F5F +} + +div.highlight .-Color[class*=-BGC167] { + background-color: #D75F5F +} + +div.highlight .-Color[class*=-C168] { + color: #D75F87 +} + +div.highlight .-Color[class*=-BGC168] { + background-color: #D75F87 +} + +div.highlight .-Color[class*=-C169] { + color: #D75FAF +} + +div.highlight .-Color[class*=-BGC169] { + background-color: #D75FAF +} + +div.highlight .-Color[class*=-C170] { + color: #D75FD7 +} + +div.highlight .-Color[class*=-BGC170] { + background-color: #D75FD7 +} + +div.highlight .-Color[class*=-C171] { + color: #D75FFF +} + +div.highlight .-Color[class*=-BGC171] { + background-color: #D75FFF +} + +div.highlight .-Color[class*=-C172] { + color: #D78700 +} + +div.highlight .-Color[class*=-BGC172] { + background-color: #D78700 +} + +div.highlight .-Color[class*=-C173] { + color: #D7875F +} + +div.highlight .-Color[class*=-BGC173] { + background-color: #D7875F +} + +div.highlight .-Color[class*=-C174] { + color: #D78787 +} + +div.highlight .-Color[class*=-BGC174] { + background-color: #D78787 +} + +div.highlight .-Color[class*=-C175] { + color: #D787AF +} + +div.highlight .-Color[class*=-BGC175] { + background-color: #D787AF +} + +div.highlight .-Color[class*=-C176] { + color: #D787D7 +} + +div.highlight .-Color[class*=-BGC176] { + background-color: #D787D7 +} + +div.highlight .-Color[class*=-C177] { + color: #D787FF +} + +div.highlight .-Color[class*=-BGC177] { + background-color: #D787FF +} + +div.highlight .-Color[class*=-C178] { + color: #D7AF00 +} + +div.highlight .-Color[class*=-BGC178] { + background-color: #D7AF00 +} + +div.highlight .-Color[class*=-C179] { + color: #D7AF5F +} + +div.highlight .-Color[class*=-BGC179] { + background-color: #D7AF5F +} + +div.highlight .-Color[class*=-C180] { + color: #D7AF87 +} + +div.highlight .-Color[class*=-BGC180] { + background-color: #D7AF87 +} + +div.highlight .-Color[class*=-C181] { + color: #D7AFAF +} + +div.highlight .-Color[class*=-BGC181] { + background-color: #D7AFAF +} + +div.highlight .-Color[class*=-C182] { + color: #D7AFD7 +} + +div.highlight .-Color[class*=-BGC182] { + background-color: #D7AFD7 +} + +div.highlight .-Color[class*=-C183] { + color: #D7AFFF +} + +div.highlight .-Color[class*=-BGC183] { + background-color: #D7AFFF +} + +div.highlight .-Color[class*=-C184] { + color: #D7D700 +} + +div.highlight .-Color[class*=-BGC184] { + background-color: #D7D700 +} + +div.highlight .-Color[class*=-C185] { + color: #D7D75F +} + +div.highlight .-Color[class*=-BGC185] { + background-color: #D7D75F +} + +div.highlight .-Color[class*=-C186] { + color: #D7D787 +} + +div.highlight .-Color[class*=-BGC186] { + background-color: #D7D787 +} + +div.highlight .-Color[class*=-C187] { + color: #D7D7AF +} + +div.highlight .-Color[class*=-BGC187] { + background-color: #D7D7AF +} + +div.highlight .-Color[class*=-C188] { + color: #D7D7D7 +} + +div.highlight .-Color[class*=-BGC188] { + background-color: #D7D7D7 +} + +div.highlight .-Color[class*=-C189] { + color: #D7D7FF +} + +div.highlight .-Color[class*=-BGC189] { + background-color: #D7D7FF +} + +div.highlight .-Color[class*=-C190] { + color: #D7FF00 +} + +div.highlight .-Color[class*=-BGC190] { + background-color: #D7FF00 +} + +div.highlight .-Color[class*=-C191] { + color: #D7FF5F +} + +div.highlight .-Color[class*=-BGC191] { + background-color: #D7FF5F +} + +div.highlight .-Color[class*=-C192] { + color: #D7FF87 +} + +div.highlight .-Color[class*=-BGC192] { + background-color: #D7FF87 +} + +div.highlight .-Color[class*=-C193] { + color: #D7FFAF +} + +div.highlight .-Color[class*=-BGC193] { + background-color: #D7FFAF +} + +div.highlight .-Color[class*=-C194] { + color: #D7FFD7 +} + +div.highlight .-Color[class*=-BGC194] { + background-color: #D7FFD7 +} + +div.highlight .-Color[class*=-C195] { + color: #D7FFFF +} + +div.highlight .-Color[class*=-BGC195] { + background-color: #D7FFFF +} + +div.highlight .-Color[class*=-C196] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC196] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C197] { + color: #FF005F +} + +div.highlight .-Color[class*=-BGC197] { + background-color: #FF005F +} + +div.highlight .-Color[class*=-C198] { + color: #FF0087 +} + +div.highlight .-Color[class*=-BGC198] { + background-color: #FF0087 +} + +div.highlight .-Color[class*=-C199] { + color: #FF00AF +} + +div.highlight .-Color[class*=-BGC199] { + background-color: #FF00AF +} + +div.highlight .-Color[class*=-C200] { + color: #FF00D7 +} + +div.highlight .-Color[class*=-BGC200] { + background-color: #FF00D7 +} + +div.highlight .-Color[class*=-C201] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC201] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C202] { + color: #FF5F00 +} + +div.highlight .-Color[class*=-BGC202] { + background-color: #FF5F00 +} + +div.highlight .-Color[class*=-C203] { + color: #FF5F5F +} + +div.highlight .-Color[class*=-BGC203] { + background-color: #FF5F5F +} + +div.highlight .-Color[class*=-C204] { + color: #FF5F87 +} + +div.highlight .-Color[class*=-BGC204] { + background-color: #FF5F87 +} + +div.highlight .-Color[class*=-C205] { + color: #FF5FAF +} + +div.highlight .-Color[class*=-BGC205] { + background-color: #FF5FAF +} + +div.highlight .-Color[class*=-C206] { + color: #FF5FD7 +} + +div.highlight .-Color[class*=-BGC206] { + background-color: #FF5FD7 +} + +div.highlight .-Color[class*=-C207] { + color: #FF5FFF +} + +div.highlight .-Color[class*=-BGC207] { + background-color: #FF5FFF +} + +div.highlight .-Color[class*=-C208] { + color: #FF8700 +} + +div.highlight .-Color[class*=-BGC208] { + background-color: #FF8700 +} + +div.highlight .-Color[class*=-C209] { + color: #FF875F +} + +div.highlight .-Color[class*=-BGC209] { + background-color: #FF875F +} + +div.highlight .-Color[class*=-C210] { + color: #FF8787 +} + +div.highlight .-Color[class*=-BGC210] { + background-color: #FF8787 +} + +div.highlight .-Color[class*=-C211] { + color: #FF87AF +} + +div.highlight .-Color[class*=-BGC211] { + background-color: #FF87AF +} + +div.highlight .-Color[class*=-C212] { + color: #FF87D7 +} + +div.highlight .-Color[class*=-BGC212] { + background-color: #FF87D7 +} + +div.highlight .-Color[class*=-C213] { + color: #FF87FF +} + +div.highlight .-Color[class*=-BGC213] { + background-color: #FF87FF +} + +div.highlight .-Color[class*=-C214] { + color: #FFAF00 +} + +div.highlight .-Color[class*=-BGC214] { + background-color: #FFAF00 +} + +div.highlight .-Color[class*=-C215] { + color: #FFAF5F +} + +div.highlight .-Color[class*=-BGC215] { + background-color: #FFAF5F +} + +div.highlight .-Color[class*=-C216] { + color: #FFAF87 +} + +div.highlight .-Color[class*=-BGC216] { + background-color: #FFAF87 +} + +div.highlight .-Color[class*=-C217] { + color: #FFAFAF +} + +div.highlight .-Color[class*=-BGC217] { + background-color: #FFAFAF +} + +div.highlight .-Color[class*=-C218] { + color: #FFAFD7 +} + +div.highlight .-Color[class*=-BGC218] { + background-color: #FFAFD7 +} + +div.highlight .-Color[class*=-C219] { + color: #FFAFFF +} + +div.highlight .-Color[class*=-BGC219] { + background-color: #FFAFFF +} + +div.highlight .-Color[class*=-C220] { + color: #FFD700 +} + +div.highlight .-Color[class*=-BGC220] { + background-color: #FFD700 +} + +div.highlight .-Color[class*=-C221] { + color: #FFD75F +} + +div.highlight .-Color[class*=-BGC221] { + background-color: #FFD75F +} + +div.highlight .-Color[class*=-C222] { + color: #FFD787 +} + +div.highlight .-Color[class*=-BGC222] { + background-color: #FFD787 +} + +div.highlight .-Color[class*=-C223] { + color: #FFD7AF +} + +div.highlight .-Color[class*=-BGC223] { + background-color: #FFD7AF +} + +div.highlight .-Color[class*=-C224] { + color: #FFD7D7 +} + +div.highlight .-Color[class*=-BGC224] { + background-color: #FFD7D7 +} + +div.highlight .-Color[class*=-C225] { + color: #FFD7FF +} + +div.highlight .-Color[class*=-BGC225] { + background-color: #FFD7FF +} + +div.highlight .-Color[class*=-C226] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC226] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C227] { + color: #FFFF5F +} + +div.highlight .-Color[class*=-BGC227] { + background-color: #FFFF5F +} + +div.highlight .-Color[class*=-C228] { + color: #FFFF87 +} + +div.highlight .-Color[class*=-BGC228] { + background-color: #FFFF87 +} + +div.highlight .-Color[class*=-C229] { + color: #FFFFAF +} + +div.highlight .-Color[class*=-BGC229] { + background-color: #FFFFAF +} + +div.highlight .-Color[class*=-C230] { + color: #FFFFD7 +} + +div.highlight .-Color[class*=-BGC230] { + background-color: #FFFFD7 +} + +div.highlight .-Color[class*=-C231] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC231] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C232] { + color: #080808 +} + +div.highlight .-Color[class*=-BGC232] { + background-color: #080808 +} + +div.highlight .-Color[class*=-C233] { + color: #121212 +} + +div.highlight .-Color[class*=-BGC233] { + background-color: #121212 +} + +div.highlight .-Color[class*=-C234] { + color: #1C1C1C +} + +div.highlight .-Color[class*=-BGC234] { + background-color: #1C1C1C +} + +div.highlight .-Color[class*=-C235] { + color: #262626 +} + +div.highlight .-Color[class*=-BGC235] { + background-color: #262626 +} + +div.highlight .-Color[class*=-C236] { + color: #303030 +} + +div.highlight .-Color[class*=-BGC236] { + background-color: #303030 +} + +div.highlight .-Color[class*=-C237] { + color: #3A3A3A +} + +div.highlight .-Color[class*=-BGC237] { + background-color: #3A3A3A +} + +div.highlight .-Color[class*=-C238] { + color: #444444 +} + +div.highlight .-Color[class*=-BGC238] { + background-color: #444444 +} + +div.highlight .-Color[class*=-C239] { + color: #4E4E4E +} + +div.highlight .-Color[class*=-BGC239] { + background-color: #4E4E4E +} + +div.highlight .-Color[class*=-C240] { + color: #585858 +} + +div.highlight .-Color[class*=-BGC240] { + background-color: #585858 +} + +div.highlight .-Color[class*=-C241] { + color: #626262 +} + +div.highlight .-Color[class*=-BGC241] { + background-color: #626262 +} + +div.highlight .-Color[class*=-C242] { + color: #6C6C6C +} + +div.highlight .-Color[class*=-BGC242] { + background-color: #6C6C6C +} + +div.highlight .-Color[class*=-C243] { + color: #767676 +} + +div.highlight .-Color[class*=-BGC243] { + background-color: #767676 +} + +div.highlight .-Color[class*=-C244] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC244] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C245] { + color: #8A8A8A +} + +div.highlight .-Color[class*=-BGC245] { + background-color: #8A8A8A +} + +div.highlight .-Color[class*=-C246] { + color: #949494 +} + +div.highlight .-Color[class*=-BGC246] { + background-color: #949494 +} + +div.highlight .-Color[class*=-C247] { + color: #9E9E9E +} + +div.highlight .-Color[class*=-BGC247] { + background-color: #9E9E9E +} + +div.highlight .-Color[class*=-C248] { + color: #A8A8A8 +} + +div.highlight .-Color[class*=-BGC248] { + background-color: #A8A8A8 +} + +div.highlight .-Color[class*=-C249] { + color: #B2B2B2 +} + +div.highlight .-Color[class*=-BGC249] { + background-color: #B2B2B2 +} + +div.highlight .-Color[class*=-C250] { + color: #BCBCBC +} + +div.highlight .-Color[class*=-BGC250] { + background-color: #BCBCBC +} + +div.highlight .-Color[class*=-C251] { + color: #C6C6C6 +} + +div.highlight .-Color[class*=-BGC251] { + background-color: #C6C6C6 +} + +div.highlight .-Color[class*=-C252] { + color: #D0D0D0 +} + +div.highlight .-Color[class*=-BGC252] { + background-color: #D0D0D0 +} + +div.highlight .-Color[class*=-C253] { + color: #DADADA +} + +div.highlight .-Color[class*=-BGC253] { + background-color: #DADADA +} + +div.highlight .-Color[class*=-C254] { + color: #E4E4E4 +} + +div.highlight .-Color[class*=-BGC254] { + background-color: #E4E4E4 +} + +div.highlight .-Color[class*=-C255] { + color: #EEEEEE +} + +div.highlight .-Color[class*=-BGC255] { + background-color: #EEEEEE +} diff --git a/branch/cff/singlehtml/_static/plus.png b/branch/cff/singlehtml/_static/plus.png new file mode 100644 index 0000000..7107cec Binary files /dev/null and b/branch/cff/singlehtml/_static/plus.png differ diff --git a/branch/cff/singlehtml/_static/pygments.css b/branch/cff/singlehtml/_static/pygments.css new file mode 100644 index 0000000..84ab303 --- /dev/null +++ b/branch/cff/singlehtml/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/branch/cff/singlehtml/_static/searchtools.js b/branch/cff/singlehtml/_static/searchtools.js new file mode 100644 index 0000000..b08d58c --- /dev/null +++ b/branch/cff/singlehtml/_static/searchtools.js @@ -0,0 +1,620 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/branch/cff/singlehtml/_static/sphinx-design.min.css b/branch/cff/singlehtml/_static/sphinx-design.min.css new file mode 100644 index 0000000..860c36d --- /dev/null +++ b/branch/cff/singlehtml/_static/sphinx-design.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative;font-size:var(--sd-fontsize-dropdown)}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary.sd-summary-title{padding:.5em .6em .5em 1em;font-size:var(--sd-fontsize-dropdown-title);font-weight:var(--sd-fontweight-dropdown-title);user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;list-style:none;display:inline-flex;justify-content:space-between}details.sd-dropdown summary.sd-summary-title::-webkit-details-marker{display:none}details.sd-dropdown summary.sd-summary-title:focus{outline:none}details.sd-dropdown summary.sd-summary-title .sd-summary-icon{margin-right:.6em;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary.sd-summary-title .sd-summary-text{flex-grow:1;line-height:1.5;padding-right:.5rem}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker{pointer-events:none;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker svg{opacity:.6}details.sd-dropdown summary.sd-summary-title:hover .sd-summary-state-marker svg{opacity:1;transform:scale(1.1)}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown .sd-summary-chevron-right{transition:.25s}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-right{transform:rotate(90deg)}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-down{transform:rotate(180deg)}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-bg: rgba(0, 113, 188, 0.2);--sd-color-secondary-bg: rgba(108, 117, 125, 0.2);--sd-color-success-bg: rgba(40, 167, 69, 0.2);--sd-color-info-bg: rgba(23, 162, 184, 0.2);--sd-color-warning-bg: rgba(240, 179, 126, 0.2);--sd-color-danger-bg: rgba(220, 53, 69, 0.2);--sd-color-light-bg: rgba(248, 249, 250, 0.2);--sd-color-muted-bg: rgba(108, 117, 125, 0.2);--sd-color-dark-bg: rgba(33, 37, 41, 0.2);--sd-color-black-bg: rgba(0, 0, 0, 0.2);--sd-color-white-bg: rgba(255, 255, 255, 0.2);--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem;--sd-fontsize-dropdown: inherit;--sd-fontsize-dropdown-title: 1rem;--sd-fontweight-dropdown-title: 700} diff --git a/branch/cff/singlehtml/_static/sphinx_highlight.js b/branch/cff/singlehtml/_static/sphinx_highlight.js new file mode 100644 index 0000000..8a96c69 --- /dev/null +++ b/branch/cff/singlehtml/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/branch/cff/singlehtml/_static/sphinx_lesson.css b/branch/cff/singlehtml/_static/sphinx_lesson.css new file mode 100644 index 0000000..14b20c6 --- /dev/null +++ b/branch/cff/singlehtml/_static/sphinx_lesson.css @@ -0,0 +1,51 @@ +/* sphinx_lesson.css */ + +body.wy-body-for-nav img.with-border { + border: 2px solid; +} + +.rst-content .admonition-no-content { + padding-bottom: 0px; +} + +.rst-content .demo > .admonition-title::before { + content: "\01F440"; /* Eyes */ } +.rst-content .type-along > .admonition-title::before { + content: "\02328\0FE0F"; /* Keyboard */ } +.rst-content .exercise > .admonition-title::before { + content: "\0270D\0FE0F"; /* Hand */ } +.rst-content .solution > .admonition-title::before { + content: "\02714\0FE0E"; /* Check mark */ } +.rst-content .homework > .admonition-title::before { + content: "\01F4DD"; /* Memo */ } +.rst-content .discussion > .admonition-title::before { + content: "\01F4AC"; /* Speech balloon */ } +.rst-content .questions > .admonition-title::before { + content: "\02753\0FE0E"; /* Question mark */ } +.rst-content .prerequisites > .admonition-title::before { + content: "\02699"; /* Gear */ } +.rst-content .seealso > .admonition-title::before { + content: "\027A1\0FE0E"; /* Question mark */ } + + +/* instructor-note */ +.rst-content .instructor-note { + background: #e7e7e7; +} +.rst-content .instructor-note > .admonition-title { + background: #6a6a6a; +} +.rst-content .instructor-note > .admonition-title::before { + content: ""; +} + + +/* sphinx_toggle_button, make the font white */ +.rst-content .toggle.admonition button.toggle-button { + color: white; +} + +/* sphinx-togglebutton, remove underflow when toggled to hidden mode */ +.rst-content .admonition.toggle-hidden { + padding-bottom: 0px; +} diff --git a/branch/cff/singlehtml/_static/sphinx_rtd_theme_ext_color_contrast.css b/branch/cff/singlehtml/_static/sphinx_rtd_theme_ext_color_contrast.css new file mode 100644 index 0000000..e68feb8 --- /dev/null +++ b/branch/cff/singlehtml/_static/sphinx_rtd_theme_ext_color_contrast.css @@ -0,0 +1,47 @@ +/* The following are for web accessibility of sphinx_rtd_theme: they + * solve some of the most frequent contrast issues. Remove when this + * solved: + * https://github.com/readthedocs/sphinx_rtd_theme/issues/971 + */ +/* background: #fcfcfc, note boxes #E7F2FA */ +a { color: #2573A7; } /* original #2980B9, #1F5C84; */ +body { color: #242424; } /* original #404040, #383838 */ +.wy-side-nav-search>a, .wy-side-nav-search .wy-dropdown>a { + color: #ffffff; +} /* original #fcfcfc */ +footer { color: #737373; } /* original gray=#808080*/ +footer span.commit code, footer span.commit .rst-content tt, .rst-content footer span.commit tt { + color: #737373; +} /* original gray=#808080*/ +.rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal { + color: #AB2314; +} +/* Sidebar background */ +.wy-side-nav-search { background-color: #277CB4;} + +/* Same, but for pygments */ +.highlight .ch { color: #3E7A89; } /* #! line */ +.highlight .c1 { color: #3E7A89; } /* also comments */ +.highlight .nv { color: #AD3ECC; } /* variable */ +.highlight .gp { color: #B45608; } /* prompt character, $*/ +.highlight .si { color: #3975B1; } /* ${} variable text */ +.highlight .nc { color: #0C78A7; } + +/* Sphinx admonitions */ +/* warning */ +.wy-alert.wy-alert-warning .wy-alert-title, .rst-content .wy-alert-warning.note .wy-alert-title, .rst-content .attention .wy-alert-title, .rst-content .caution .wy-alert-title, .rst-content .wy-alert-warning.danger .wy-alert-title, .rst-content .wy-alert-warning.error .wy-alert-title, .rst-content .wy-alert-warning.hint .wy-alert-title, .rst-content .wy-alert-warning.important .wy-alert-title, .rst-content .wy-alert-warning.tip .wy-alert-title, .rst-content .warning .wy-alert-title, .rst-content .wy-alert-warning.seealso .wy-alert-title, .rst-content .admonition-todo .wy-alert-title, .rst-content .wy-alert-warning.admonition .wy-alert-title, .wy-alert.wy-alert-warning .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-warning .admonition-title, .rst-content .wy-alert-warning.note .admonition-title, .rst-content .attention .admonition-title, .rst-content .caution .admonition-title, .rst-content .wy-alert-warning.danger .admonition-title, .rst-content .wy-alert-warning.error .admonition-title, .rst-content .wy-alert-warning.hint .admonition-title, .rst-content .wy-alert-warning.important .admonition-title, .rst-content .wy-alert-warning.tip .admonition-title, .rst-content .warning .admonition-title, .rst-content .wy-alert-warning.seealso .admonition-title, .rst-content .admonition-todo .admonition-title, .rst-content .wy-alert-warning.admonition .admonition-title { + background: #B15E16; } +/* important */ +.wy-alert.wy-alert-success .wy-alert-title, .rst-content .wy-alert-success.note .wy-alert-title, .rst-content .wy-alert-success.attention .wy-alert-title, .rst-content .wy-alert-success.caution .wy-alert-title, .rst-content .wy-alert-success.danger .wy-alert-title, .rst-content .wy-alert-success.error .wy-alert-title, .rst-content .hint .wy-alert-title, .rst-content .important .wy-alert-title, .rst-content .tip .wy-alert-title, .rst-content .wy-alert-success.warning .wy-alert-title, .rst-content .wy-alert-success.seealso .wy-alert-title, .rst-content .wy-alert-success.admonition-todo .wy-alert-title, .rst-content .wy-alert-success.admonition .wy-alert-title, .wy-alert.wy-alert-success .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-success .admonition-title, .rst-content .wy-alert-success.note .admonition-title, .rst-content .wy-alert-success.attention .admonition-title, .rst-content .wy-alert-success.caution .admonition-title, .rst-content .wy-alert-success.danger .admonition-title, .rst-content .wy-alert-success.error .admonition-title, .rst-content .hint .admonition-title, .rst-content .important .admonition-title, .rst-content .tip .admonition-title, .rst-content .wy-alert-success.warning .admonition-title, .rst-content .wy-alert-success.seealso .admonition-title, .rst-content .wy-alert-success.admonition-todo .admonition-title, .rst-content .wy-alert-success.admonition .admonition-title { + background: #12826C; } +/* seealso, note, etc */ +.wy-alert.wy-alert-info .wy-alert-title, .rst-content .note .wy-alert-title, .rst-content .wy-alert-info.attention .wy-alert-title, .rst-content .wy-alert-info.caution .wy-alert-title, .rst-content .wy-alert-info.danger .wy-alert-title, .rst-content .wy-alert-info.error .wy-alert-title, .rst-content .wy-alert-info.hint .wy-alert-title, .rst-content .wy-alert-info.important .wy-alert-title, .rst-content .wy-alert-info.tip .wy-alert-title, .rst-content .wy-alert-info.warning .wy-alert-title, .rst-content .seealso .wy-alert-title, .rst-content .wy-alert-info.admonition-todo .wy-alert-title, .rst-content .wy-alert-info.admonition .wy-alert-title, .wy-alert.wy-alert-info .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-info .admonition-title, .rst-content .note .admonition-title, .rst-content .wy-alert-info.attention .admonition-title, .rst-content .wy-alert-info.caution .admonition-title, .rst-content .wy-alert-info.danger .admonition-title, .rst-content .wy-alert-info.error .admonition-title, .rst-content .wy-alert-info.hint .admonition-title, .rst-content .wy-alert-info.important .admonition-title, .rst-content .wy-alert-info.tip .admonition-title, .rst-content .wy-alert-info.warning .admonition-title, .rst-content .seealso .admonition-title, .rst-content .wy-alert-info.admonition-todo .admonition-title, .rst-content .wy-alert-info.admonition .admonition-title { + background: #277CB4; } +/* error, danger */ +.rst-content .danger .admonition-title, .rst-content .danger .wy-alert-title, .rst-content .error .admonition-title, .rst-content .error .wy-alert-title, .rst-content .wy-alert-danger.admonition-todo .admonition-title, .rst-content .wy-alert-danger.admonition-todo .wy-alert-title, .rst-content .wy-alert-danger.admonition .admonition-title, .rst-content .wy-alert-danger.admonition .wy-alert-title, .rst-content .wy-alert-danger.attention .admonition-title, .rst-content .wy-alert-danger.attention .wy-alert-title, .rst-content .wy-alert-danger.caution .admonition-title, .rst-content .wy-alert-danger.caution .wy-alert-title, .rst-content .wy-alert-danger.hint .admonition-title, .rst-content .wy-alert-danger.hint .wy-alert-title, .rst-content .wy-alert-danger.important .admonition-title, .rst-content .wy-alert-danger.important .wy-alert-title, .rst-content .wy-alert-danger.note .admonition-title, .rst-content .wy-alert-danger.note .wy-alert-title, .rst-content .wy-alert-danger.seealso .admonition-title, .rst-content .wy-alert-danger.seealso .wy-alert-title, .rst-content .wy-alert-danger.tip .admonition-title, .rst-content .wy-alert-danger.tip .wy-alert-title, .rst-content .wy-alert-danger.warning .admonition-title, .rst-content .wy-alert-danger.warning .wy-alert-title, .rst-content .wy-alert.wy-alert-danger .admonition-title, .wy-alert.wy-alert-danger .rst-content .admonition-title, .wy-alert.wy-alert-danger .wy-alert-title { + background: #e31704; +} + +/* Generic admonition titles */ +.wy-alert-title, .rst-content .admonition-title { + background: #277CB4; } diff --git a/branch/cff/singlehtml/_static/tabs.css b/branch/cff/singlehtml/_static/tabs.css new file mode 100644 index 0000000..957ba60 --- /dev/null +++ b/branch/cff/singlehtml/_static/tabs.css @@ -0,0 +1,89 @@ +.sphinx-tabs { + margin-bottom: 1rem; +} + +[role="tablist"] { + border-bottom: 1px solid #a0b3bf; +} + +.sphinx-tabs-tab { + position: relative; + font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; + color: #1D5C87; + line-height: 24px; + margin: 0; + font-size: 16px; + font-weight: 400; + background-color: rgba(255, 255, 255, 0); + border-radius: 5px 5px 0 0; + border: 0; + padding: 1rem 1.5rem; + margin-bottom: 0; +} + +.sphinx-tabs-tab[aria-selected="true"] { + font-weight: 700; + border: 1px solid #a0b3bf; + border-bottom: 1px solid white; + margin: -1px; + background-color: white; +} + +.sphinx-tabs-tab:focus { + z-index: 1; + outline-offset: 1px; +} + +.sphinx-tabs-panel { + position: relative; + padding: 1rem; + border: 1px solid #a0b3bf; + margin: 0px -1px -1px -1px; + border-radius: 0 0 5px 5px; + border-top: 0; + background: white; +} + +.sphinx-tabs-panel.code-tab { + padding: 0.4rem; +} + +.sphinx-tab img { + margin-bottom: 24 px; +} + +/* Dark theme preference styling */ + +@media (prefers-color-scheme: dark) { + body[data-theme="auto"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); + } + + body[data-theme="auto"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); + } + + body[data-theme="auto"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 1px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); + } +} + +/* Explicit dark theme styling */ + +body[data-theme="dark"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); +} + +body[data-theme="dark"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); +} + +body[data-theme="dark"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 2px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); +} diff --git a/branch/cff/singlehtml/_static/tabs.js b/branch/cff/singlehtml/_static/tabs.js new file mode 100644 index 0000000..48dc303 --- /dev/null +++ b/branch/cff/singlehtml/_static/tabs.js @@ -0,0 +1,145 @@ +try { + var session = window.sessionStorage || {}; +} catch (e) { + var session = {}; +} + +window.addEventListener("DOMContentLoaded", () => { + const allTabs = document.querySelectorAll('.sphinx-tabs-tab'); + const tabLists = document.querySelectorAll('[role="tablist"]'); + + allTabs.forEach(tab => { + tab.addEventListener("click", changeTabs); + }); + + tabLists.forEach(tabList => { + tabList.addEventListener("keydown", keyTabs); + }); + + // Restore group tab selection from session + const lastSelected = session.getItem('sphinx-tabs-last-selected'); + if (lastSelected != null) selectNamedTabs(lastSelected); +}); + +/** + * Key focus left and right between sibling elements using arrows + * @param {Node} e the element in focus when key was pressed + */ +function keyTabs(e) { + const tab = e.target; + let nextTab = null; + if (e.keyCode === 39 || e.keyCode === 37) { + tab.setAttribute("tabindex", -1); + // Move right + if (e.keyCode === 39) { + nextTab = tab.nextElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.firstElementChild; + } + // Move left + } else if (e.keyCode === 37) { + nextTab = tab.previousElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.lastElementChild; + } + } + } + + if (nextTab !== null) { + nextTab.setAttribute("tabindex", 0); + nextTab.focus(); + } +} + +/** + * Select or deselect clicked tab. If a group tab + * is selected, also select tab in other tabLists. + * @param {Node} e the element that was clicked + */ +function changeTabs(e) { + // Use this instead of the element that was clicked, in case it's a child + const notSelected = this.getAttribute("aria-selected") === "false"; + const positionBefore = this.parentNode.getBoundingClientRect().top; + const notClosable = !this.parentNode.classList.contains("closeable"); + + deselectTabList(this); + + if (notSelected || notClosable) { + selectTab(this); + const name = this.getAttribute("name"); + selectNamedTabs(name, this.id); + + if (this.classList.contains("group-tab")) { + // Persist during session + session.setItem('sphinx-tabs-last-selected', name); + } + } + + const positionAfter = this.parentNode.getBoundingClientRect().top; + const positionDelta = positionAfter - positionBefore; + // Scroll to offset content resizing + window.scrollTo(0, window.scrollY + positionDelta); +} + +/** + * Select tab and show associated panel. + * @param {Node} tab tab to select + */ +function selectTab(tab) { + tab.setAttribute("aria-selected", true); + + // Show the associated panel + document + .getElementById(tab.getAttribute("aria-controls")) + .removeAttribute("hidden"); +} + +/** + * Hide the panels associated with all tabs within the + * tablist containing this tab. + * @param {Node} tab a tab within the tablist to deselect + */ +function deselectTabList(tab) { + const parent = tab.parentNode; + const grandparent = parent.parentNode; + + Array.from(parent.children) + .forEach(t => t.setAttribute("aria-selected", false)); + + Array.from(grandparent.children) + .slice(1) // Skip tablist + .forEach(panel => panel.setAttribute("hidden", true)); +} + +/** + * Select grouped tabs with the same name, but no the tab + * with the given id. + * @param {Node} name name of grouped tab to be selected + * @param {Node} clickedId id of clicked tab + */ +function selectNamedTabs(name, clickedId=null) { + const groupedTabs = document.querySelectorAll(`.sphinx-tabs-tab[name="${name}"]`); + const tabLists = Array.from(groupedTabs).map(tab => tab.parentNode); + + tabLists + .forEach(tabList => { + // Don't want to change the tabList containing the clicked tab + const clickedTab = tabList.querySelector(`[id="${clickedId}"]`); + if (clickedTab === null ) { + // Select first tab with matching name + const tab = tabList.querySelector(`.sphinx-tabs-tab[name="${name}"]`); + deselectTabList(tab); + selectTab(tab); + } + }) +} + +if (typeof exports === 'undefined') { + exports = {}; +} + +exports.keyTabs = keyTabs; +exports.changeTabs = changeTabs; +exports.selectTab = selectTab; +exports.deselectTabList = deselectTabList; +exports.selectNamedTabs = selectNamedTabs; diff --git a/branch/cff/singlehtml/_static/term_role_formatting.css b/branch/cff/singlehtml/_static/term_role_formatting.css new file mode 100644 index 0000000..0b66095 --- /dev/null +++ b/branch/cff/singlehtml/_static/term_role_formatting.css @@ -0,0 +1,4 @@ +/* Make terms bold */ +a.reference span.std-term { + font-weight: bold; +} diff --git a/branch/cff/singlehtml/_static/togglebutton.css b/branch/cff/singlehtml/_static/togglebutton.css new file mode 100644 index 0000000..54a6787 --- /dev/null +++ b/branch/cff/singlehtml/_static/togglebutton.css @@ -0,0 +1,160 @@ +/** + * Admonition-based toggles + */ + +/* Visibility of the target */ +.admonition.toggle .admonition-title ~ * { + transition: opacity .3s, height .3s; +} + +/* Toggle buttons inside admonitions so we see the title */ +.admonition.toggle { + position: relative; +} + +/* Titles should cut off earlier to avoid overlapping w/ button */ +.admonition.toggle .admonition-title { + padding-right: 25%; + cursor: pointer; +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:hover { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 1%); +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:active { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 3%); +} + +/* Remove extra whitespace below the admonition title when hidden */ +.admonition.toggle-hidden { + padding-bottom: 0; +} + +.admonition.toggle-hidden .admonition-title { + margin-bottom: 0; +} + +/* hides all the content of a page until de-toggled */ +.admonition.toggle-hidden .admonition-title ~ * { + height: 0; + margin: 0; + opacity: 0; + visibility: hidden; +} + +/* General button style and position*/ +button.toggle-button { + /** + * Background and shape. By default there's no background + * but users can style as they wish + */ + background: none; + border: none; + outline: none; + + /* Positioning just inside the admonition title */ + position: absolute; + right: 0.5em; + padding: 0px; + border: none; + outline: none; +} + +/* Display the toggle hint on wide screens */ +@media (min-width: 768px) { + button.toggle-button.toggle-button-hidden:before { + content: attr(data-toggle-hint); /* This will be filled in by JS */ + font-size: .8em; + align-self: center; + } +} + +/* Icon behavior */ +.tb-icon { + transition: transform .2s ease-out; + height: 1.5em; + width: 1.5em; + stroke: currentColor; /* So that we inherit the color of other text */ +} + +/* The icon should point right when closed, down when open. */ +/* Open */ +.admonition.toggle button .tb-icon { + transform: rotate(90deg); +} + +/* Closed */ +.admonition.toggle button.toggle-button-hidden .tb-icon { + transform: rotate(0deg); +} + +/* With details toggles, we don't rotate the icon so it points right */ +details.toggle-details .tb-icon { + height: 1.4em; + width: 1.4em; + margin-top: 0.1em; /* To center the button vertically */ +} + + +/** + * Details-based toggles. + * In this case, we wrap elements with `.toggle` in a details block. + */ + +/* Details blocks */ +details.toggle-details { + margin: 1em 0; +} + + +details.toggle-details summary { + display: flex; + align-items: center; + cursor: pointer; + list-style: none; + border-radius: .2em; + border-left: 3px solid #1976d2; + background-color: rgb(204 204 204 / 10%); + padding: 0.2em 0.7em 0.3em 0.5em; /* Less padding on left because the SVG has left margin */ + font-size: 0.9em; +} + +details.toggle-details summary:hover { + background-color: rgb(204 204 204 / 20%); +} + +details.toggle-details summary:active { + background: rgb(204 204 204 / 28%); +} + +.toggle-details__summary-text { + margin-left: 0.2em; +} + +details.toggle-details[open] summary { + margin-bottom: .5em; +} + +details.toggle-details[open] summary .tb-icon { + transform: rotate(90deg); +} + +details.toggle-details[open] summary ~ * { + animation: toggle-fade-in .3s ease-out; +} + +@keyframes toggle-fade-in { + from {opacity: 0%;} + to {opacity: 100%;} +} + +/* Print rules - we hide all toggle button elements at print */ +@media print { + /* Always hide the summary so the button doesn't show up */ + details.toggle-details summary { + display: none; + } +} \ No newline at end of file diff --git a/branch/cff/singlehtml/_static/togglebutton.js b/branch/cff/singlehtml/_static/togglebutton.js new file mode 100644 index 0000000..215a7ee --- /dev/null +++ b/branch/cff/singlehtml/_static/togglebutton.js @@ -0,0 +1,187 @@ +/** + * Add Toggle Buttons to elements + */ + +let toggleChevron = ` + + + +`; + +var initToggleItems = () => { + var itemsToToggle = document.querySelectorAll(togglebuttonSelector); + console.log(`[togglebutton]: Adding toggle buttons to ${itemsToToggle.length} items`) + // Add the button to each admonition and hook up a callback to toggle visibility + itemsToToggle.forEach((item, index) => { + if (item.classList.contains("admonition")) { + // If it's an admonition block, then we'll add a button inside + // Generate unique IDs for this item + var toggleID = `toggle-${index}`; + var buttonID = `button-${toggleID}`; + + item.setAttribute('id', toggleID); + if (!item.classList.contains("toggle")){ + item.classList.add("toggle"); + } + // This is the button that will be added to each item to trigger the toggle + var collapseButton = ` + `; + + title = item.querySelector(".admonition-title") + title.insertAdjacentHTML("beforeend", collapseButton); + thisButton = document.getElementById(buttonID); + + // Add click handlers for the button + admonition title (if admonition) + admonitionTitle = document.querySelector(`#${toggleID} > .admonition-title`) + if (admonitionTitle) { + // If an admonition, then make the whole title block clickable + admonitionTitle.addEventListener('click', toggleClickHandler); + admonitionTitle.dataset.target = toggleID + admonitionTitle.dataset.button = buttonID + } else { + // If not an admonition then we'll listen for the button click + thisButton.addEventListener('click', toggleClickHandler); + } + + // Now hide the item for this toggle button unless explicitly noted to show + if (!item.classList.contains("toggle-shown")) { + toggleHidden(thisButton); + } + } else { + // If not an admonition, wrap the block in a
block + // Define the structure of the details block and insert it as a sibling + var detailsBlock = ` +
+ + ${toggleChevron} + ${toggleHintShow} + +
`; + item.insertAdjacentHTML("beforebegin", detailsBlock); + + // Now move the toggle-able content inside of the details block + details = item.previousElementSibling + details.appendChild(item) + item.classList.add("toggle-details__container") + + // Set up a click trigger to change the text as needed + details.addEventListener('click', (click) => { + let parent = click.target.parentElement; + if (parent.tagName.toLowerCase() == "details") { + summary = parent.querySelector("summary"); + details = parent; + } else { + summary = parent; + details = parent.parentElement; + } + // Update the inner text for the proper hint + if (details.open) { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintShow; + } else { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintHide; + } + + }); + + // If we have a toggle-shown class, open details block should be open + if (item.classList.contains("toggle-shown")) { + details.click(); + } + } + }) +}; + +// This should simply add / remove the collapsed class and change the button text +var toggleHidden = (button) => { + target = button.dataset['target'] + var itemToToggle = document.getElementById(target); + if (itemToToggle.classList.contains("toggle-hidden")) { + itemToToggle.classList.remove("toggle-hidden"); + button.classList.remove("toggle-button-hidden"); + } else { + itemToToggle.classList.add("toggle-hidden"); + button.classList.add("toggle-button-hidden"); + } +} + +var toggleClickHandler = (click) => { + // Be cause the admonition title is clickable and extends to the whole admonition + // We only look for a click event on this title to trigger the toggle. + + if (click.target.classList.contains("admonition-title")) { + button = click.target.querySelector(".toggle-button"); + } else if (click.target.classList.contains("tb-icon")) { + // We've clicked the icon and need to search up one parent for the button + button = click.target.parentElement; + } else if (click.target.tagName == "polyline") { + // We've clicked the SVG elements inside the button, need to up 2 layers + button = click.target.parentElement.parentElement; + } else if (click.target.classList.contains("toggle-button")) { + // We've clicked the button itself and so don't need to do anything + button = click.target; + } else { + console.log(`[togglebutton]: Couldn't find button for ${click.target}`) + } + target = document.getElementById(button.dataset['button']); + toggleHidden(target); +} + +// If we want to blanket-add toggle classes to certain cells +var addToggleToSelector = () => { + const selector = ""; + if (selector.length > 0) { + document.querySelectorAll(selector).forEach((item) => { + item.classList.add("toggle"); + }) + } +} + +// Helper function to run when the DOM is finished +const sphinxToggleRunWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} +sphinxToggleRunWhenDOMLoaded(addToggleToSelector) +sphinxToggleRunWhenDOMLoaded(initToggleItems) + +/** Toggle details blocks to be open when printing */ +if (toggleOpenOnPrint == "true") { + window.addEventListener("beforeprint", () => { + // Open the details + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.dataset["togglestatus"] = el.open; + el.open = true; + }); + + // Open the admonitions + document.querySelectorAll(".admonition.toggle.toggle-hidden").forEach((el) => { + console.log(el); + el.querySelector("button.toggle-button").click(); + el.dataset["toggle_after_print"] = "true"; + }); + }); + window.addEventListener("afterprint", () => { + // Re-close the details that were closed + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.open = el.dataset["togglestatus"] == "true"; + delete el.dataset["togglestatus"]; + }); + + // Re-close the admonition toggle buttons + document.querySelectorAll(".admonition.toggle").forEach((el) => { + if (el.dataset["toggle_after_print"] == "true") { + el.querySelector("button.toggle-button").click(); + delete el.dataset["toggle_after_print"]; + } + }); + }); +} diff --git a/branch/cff/singlehtml/index.html b/branch/cff/singlehtml/index.html new file mode 100644 index 0000000..5ca874d --- /dev/null +++ b/branch/cff/singlehtml/index.html @@ -0,0 +1,6199 @@ + + + + + + + Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Train the trainer workshop

+
+

August/September 2024 CodeRefinery train the trainer workshop

+

Do you teach the use of computers and computational tools? Are you curious about scaling your training and learn about tested and proven practices from CodeRefinery workshops and other trainers? Join us for the CodeRefinery train the trainer workshop: four self-contained sessions on tools and techniques for computational training offer a great chance to enhance your teaching skills and learn about new tools and practices. What you will learn is also used a lot outside CodeRefinery, whenever good beginner friendly training is needed.

+

Learning objectives:

+
    +
  • Learn about tools and techniques and practice to create engaging online teaching experiences (screenshare, audio, etc.).

  • +
  • Become mentally ready to be an instructor in a collaborative interactive online workshop (not only large workshops but in general).

  • +
  • Learn how to design and develop lesson material collaboratively.

  • +
+

Target audience:

+
    +
  • Everyone teaching online workshops about computational topics or interested in teaching.

  • +
  • Previous and future instructors and helpers of CodeRefinery workshops.

  • +
+

Prerequisites: +An interest in teaching.

+

Workshop structure: +We aim for a mix of modular presentations and work in small groups. The latter will be done in breakoutrooms - +be prepared to switch on your camera and have a fruitful exchange with fellow participants!

+

Organizers and instructors:

+

The workshop is organized by partner organizations of the CodeRefinery project.

+

Facilitators and instructors:

+
    +
  • Radovan Bast

  • +
  • Richard Darst

  • +
  • Bjørn Lindi

  • +
  • Dhanya Pushpadas

  • +
  • Jarno Rantaharju

  • +
  • Stephan Smuts

  • +
  • Stepas Toliautas

  • +
  • Samantha Wittke

  • +
+

Content and timing:

+

The workshop consists of four sessions every Tuesday between August +13th and September 3rd 2024, + to +:

+
    +
  • Session 1: About lesson design, deployment and iterative improvement (Aug 13)

  • +
  • Session 2: Tools and techniques adopted in CodeRefinery workshops (Aug 20)

  • +
  • Session 3: About teaching & cool things we all would like to share (Aug 27)

  • +
  • Session 4: Workshop streaming practices and post-workshop tasks (Sep 3)

  • +
+

You can join all sessions, or the just the ones that interest you. More details on each session will be shared later.

+

The workshop is free of charge for everyone, please register below to get the Zoom link and other useful information for the workshop.

+

The workshop is over and registration is closed now.

+

If you have any questions, please write to support@coderefinery.org.

+
+
+
+

Lesson design and development

+
+

Objectives

+
    +
  • We share our design processes for teaching material and presentations.

  • +
  • Learn how to design lessons “backwards”, starting from learning objectives +and learner personas.

  • +
  • Learn good practices for improving existing material based on feedback.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 20 min

  • +
  • Exercises: 35 min

  • +
+
+
+

Exercise: How do you design your teaching material?

+
+

We collect notes using a shared document (5 min)

+
    +
  • When you start preparing a new lesson or training material, where do you start?

  • +
  • What tricks help you with “writer’s block” or the empty page problem?

  • +
  • Maybe you haven’t designed training material yet. But how do you start when creating a new presentation?

  • +
  • If your design process has changed over time, please describe what you used to do and what you do now instead.

  • +
  • What do you know now about preparing lessons/training/presentations that you wish you knew earlier?

  • +
+
+
+
+

Creating new teaching material

+
+

Typical problems

+
    +
  • Someone creates a lesson, but they think about what is interesting to them, +not what is important for the learners.

  • +
  • “I want to show a number of things which I think are cool about +tool X - how do I press these into 90 minutes?”

  • +
  • Write down material you want to cover and then sprinkle in some exercises.

  • +
  • Thinking about how I work, not how the learners work.

  • +
  • Trying to bring learners to their level/setup, not trying to meet the learners +where they are.

  • +
  • Not really knowing the learning objectives or the learner personas.

  • +
+
+
+

Better approach

+

Good questions to ask and discuss with a group of colleagues from diverse backgrounds:

+
    +
  • What is the expected educational level of my audience?

  • +
  • Have they been already exposed to the technologies I am planning to teach?

  • +
  • What tools do they already use?

  • +
  • What are the main issues they are currently experiencing?

  • +
  • What do they need to remember/understand/apply/analyze/evaluate/create +(Bloom’s taxonomy)?

  • +
  • Define learner personas.

  • +
  • It may be an advantage to share an imperfect lesson with others early to +collect feedback and suggestions before the lesson “solidifies” too much. +Draft it and collect feedback. The result will probably be better than +working in isolation towards a “perfect” lesson.

  • +
+
+
+

The process of designing a lesson “backwards”

+

As described in “A lesson design process” in the book Teaching Tech +Together:

+
    +
  1. Understand your learners.

  2. +
  3. Brainstorm rough ideas.

  4. +
  5. Create an summative assessment to know your overall goal.

    +
    +

    [Think of the things your learners will be able to do at the end of the lesson]

    +
    +
  6. +
  7. Create formative assessments to go from the starting point to this.

    +
    +

    [Think of some engaging and active exercises]

    +
    +
  8. +
  9. Order the formative assessments (exercises) into a reasonable order.

  10. +
  11. Write just enough material to get from one assessment (exercise) to +another.

  12. +
  13. Describe the course so the learners know if it is relevant to them.

  14. +
+
+
+
+

Improving existing lessons

+
+

All CodeRefinery lessons are on GitHub

+ +
+

Collect feedback during the workshop:

+
    +
  • Collect feedback from learners and instructors (Example from a past +workshop).

  • +
  • Convert feedback about lessons and suggestions for improvements into issues +so that these don’t get lost and stay close to the lesson material.

  • +
+

Collect feedback before you start a big rewrite:

+
    +
  • First open an issue and describe your idea and collect feedback before you +start with an extensive rewrite.

  • +
  • For things still under construction, open a draft pull/merge request to collect +feedback and to signal to others what you are working on.

  • +
+

Small picture changes vs. big picture changes:

+
    +
  • Lesson changes should be accompanied with instructor guide changes (it’s like +a documentation for the lesson material).

  • +
  • Instructor guide is essential for new instructors.

  • +
  • Before making larger changes, talk with somebody and discuss these changes.

  • +
+
+
+

Use case: our lessons

+

As an example to demonstrate the process of designing and improving lessons, we +will have a look at one of our own lessons: Introduction to version control +with Git.

+
    +
  • Initial 2014-2016 version

    + +
  • +
  • Some time in 2014-2015 attended Carpentries instructor training.

  • +
  • 2016: CodeRefinery started.

  • +
  • 2017: Started a new repository based on the Carpentries lesson template (at the time using Jekyll).

    +
      +
    • Exercises become part of the lesson.

    • +
    • We start in the command line and only later move to GitHub.

    • +
    +
  • +
  • 2019: A lot more thought about learning objectives and personas.

    +
      +
    • Also license change to CC-BY.

    • +
    +
  • +
  • 2022: Convert lesson from Jekyll to Sphinx.

    +
      +
    • Using the tools that we teach/advocate.

    • +
    • We can have tabs and better code highlighting/emphasis.

    • +
    • Easier local preview (Python environment instead of Ruby environment which we were not used to in our daily work).

    • +
    +
  • +
  • 2024: Big redesign. We move the lesson closer to where learners are.

    +
      +
    • Start from GitHub instead of on the command line.

    • +
    • Start from an existing repository instead of with an empty one.

    • +
    • Offer several tracks to participate in the lesson (GitHub, VS Code, and command line) and learners can choose which one they want to follow.

    • +
    • Blog post: We have completely changed our Git lessons. Hopefully to the better.

    • +
    +
  • +
  • Next steps?

    +
      +
    • Making the lesson citable following +our blog post.

    • +
    • Improvements based on what we learn from this workshop.

    • +
    +
  • +
+

The overarching trend was to make the lesson simpler and more accessible - to +meet the learners where they are instead of pulling them to the tool choices of +the instructors. Looking back, we learned a lot and the learning process is +not over yet.

+
+
+

Exercise: Discussion about learning objectives and exercise design

+
+

We work in groups but use the shared document as result (20 min)

+
    +
  1. As a group pick a lesson topic. It can be one of the topics listed here but +you can also choose something else that your group is interested in, or a topic +that you have taught before or would like to teach. Some suggestions:

    +
      +
    • Git: Creating a repository and porting your project to Git and GitHub

    • +
    • Git: Basic commands

    • +
    • Git: Branching and merging

    • +
    • Git: Recovering from typical mistakes

    • +
    • Code documentation

    • +
    • Jupyter Notebooks

    • +
    • Collaboration using Git and GitHub/GitLab

    • +
    • Using GitHub without the command line

    • +
    • Project organization

    • +
    • Automated testing

    • +
    • Data transfer

    • +
    • Data management and versioning

    • +
    • Code quality and good practices

    • +
    • Modular code development

    • +
    • How to release and publish your code

    • +
    • How to document and track code dependencies

    • +
    • Recording environments in containers

    • +
    • Profiling memory and CPU usage

    • +
    • Strategies for parallelization

    • +
    • Conda environments

    • +
    • Data processing using workflow managers

    • +
    • Regular expressions

    • +
    • Making papers in LaTeX

    • +
    • Making figures in your favorite programming language

    • +
    • Linux shell basics

    • +
    • Something non-technical, such as painting a room

    • +
    • Introduction to high-performance computing

    • +
    • A lesson you always wanted to teach

    • +
    • +
    +
  2. +
  3. Try to define 2-3 learning objectives for the lesson and write them down. +You can think of these as “three simple enough messages that someone will +remember the next day” - they need to be pretty simple.

  4. +
  5. Can you come up with one or two engaging exercises that could be used to +demonstrate one of those objectives? +They should be simple enough people can actually do them. Creating simple exercises is not easy. +Some standard exercise types:

    +
      +
    • Multiple choice (easy to get feedback via a classroom tool - try to design each wrong answer so that it identifies a specific misconception).

    • +
    • Code yourself (traditional programming)

    • +
    • Code yourself + multiple choice to see what the answer is (allows you to get feedback)

    • +
    • Inverted coding (given code, have to debug)

    • +
    • Parsons problems (working solution but lines in random order, learner must only put in proper order)

    • +
    • Fill in the blank

    • +
    • Discussions, self directed learning exercises

    • +
    +
  6. +
+
+
+
+

Great resources

+ +
+
+
+

Lessons with version control

+
+

Objectives

+
    +
  • Understand why version control is useful even for teaching material

  • +
  • Understand how version control managed lessons can be modified.

  • +
  • Understand how the CodeRefinery lesson template is used to create new lessons

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 25 min

  • +
  • Exercises or demos: 20 min

  • +
+
+
+

Why version control?

+
    +
  • If you are in CodeRefinery TTT, you probably know what version +control is and why it is important.

  • +
  • The benefits of version control also extend to lessons:

    +
      +
    • Change history

    • +
    • Others can submit contributions

    • +
    • Others can make derived versions and sync up later

    • +
    • Same workflow as everything else

    • +
    • Write it like documentation: probably more reading after than +watching it as a presentation.

    • +
    +
  • +
  • Disadvantages

    +
      +
    • “What you see is what you get” editing is hard

    • +
    • Requires knowing version control

    • +
    +
  • +
+
+

Accepting the smallest contribution

+

Question: if someone wants to make a tiny fix to your material, can they?

+
+
+
+

Tour of lesson templates options

+

There are different ways to make lessons with git. Some dedicated to +teaching:

+ +

Our philosophy is that anything works: it doesn’t have to be just +designed for lessons

+
    +
  • Jupyter Book

    +
      +
    • Example: https://jupyterbook.org/

    • +
    • Note: is based on sphinx, many extensions here are used in CR lessons

    • +
    +
  • +
  • Various ways to make slides out of Markdown

  • +
  • Cicero: GitHub-hosted Markdown to slides easily

    + +
  • +
  • Whatever your existing documentation is.

  • +
+

We like the CodeRefinery format, but think that you should use +whatever fits your needs the most.

+
+
+

Sphinx

+
    +
  • We build all our lesson material with Sphinx

  • +
  • Generate HTML/PDF/LaTeX from RST and Markdown.

  • +
  • Many Python projects use Sphinx for documentation but Sphinx is not limited to Python.

  • +
  • Read the docs hosts public Sphinx documentation for free!

  • +
  • Also hostable anywhere else, like Github pages, like our lesson material

  • +
  • For code a selling point for Sphinx is that also API documentation +is possible.

  • +
+

Sphinx is a doc generator, not HTML generator. It can:

+
    +
  • Markdown, Jupyter, and ReST (and more…) inputs. Executable inputs.

    +
      +
    • jupyter-book is Sphinx, so anything it can do we can do. This was one of the +inspirations for using Sphinx

    • +
    +
  • +
  • Good support for inline code. Much more than static code display, if +you want to look at extensions.

  • +
  • Generate different output formats (html, single-page html, pdf, epub, etc.)

  • +
  • Strong cross-referencing within and between projects

  • +
+
+
+

CodeRefinery lesson template

+

It is “just a normal Sphinx project” - with extensions:

+
    +
  • Sphinx lesson extension

    +
      +
    • adds is various directives (boxes) tuned to lesson purposes

    • +
    • provides a sample organization and template repo you can use so that lessons look consistent

    • +
    +
  • +
  • Sphinx gives us other nice features for free

    +
      +
    • Tabs: they are very important for us and allow us to customize in-place instead of copying everything and fragmenting lessons

    • +
    • Emphasize lines: they make it easier to spot what has changed in longer code snippets

    • +
    • Various input formats

      +
        +
      • Markdown (via the MyST-parser), ReStructured text, Jupyter +Notebooks.

      • +
      +
    • +
    • Many other features designed for presenting and interacting with code

    • +
    +
  • +
  • It’s fine if you use some other static site generator or git-based lesson method.

  • +
+
+

Instructors go through the building and contributing process

+

Depending on the course, instructors will demo what is roughly +exercise 4 below. Or a course might go straight to exercises.

+
    +
  • Instructors decide what change they would want to make

  • +
  • Instructors clone the repository

  • +
  • Instructors make the change

  • +
  • Instructors set up the build environment

  • +
  • Instructors build and preview

  • +
  • Instructors command and send upstream

  • +
+
+
+
+

Exercises

+

Some exercises have prerequisites (Git or Github accounts). Most +instances of this course will have you do 1 and 2 below.

+
+

Lesson-VCS-1: Present and discuss your own lesson formats

+

We don’t want to push everyone towards one format, but as long as you +use Git, it’s easy to share and reuse.

+
    +
  • Discuss what formats you do use

  • +
  • Within your team, show examples of the lessons formats you use +now. Discuss what is good and to-be-improved about them.

  • +
  • Look at how they source is managed and how easy it might be to edit.

  • +
+
+
+

Lesson-VCS-2: Tour a CodeRefinery or Carpentries lesson on Github

+
    +
  • Look at either a CodeRefinery or Carpentries lesson

    + +
  • +
  • Can you find

    +
      +
    • Where is the content of the lessons?

    • +
    • What recent change propsals (pull requests) have been made?

    • +
    • What are the open issues?

    • +
    • How you would contribute something?

    • +
    • How would you use this yourself?

    • +
    +
  • +
+
+
+

Lesson-VCS-3: Modify a CodeRefinery example lesson on Github

+

In this, you will make a change to a lesson on Github, using only the +Github interface. (Github account required, and we assume some +knowledge of Github. Ask for help in your team if it is new to you!)

+
    +
  • Navigate to the example lesson we have set up: +repo, web

  • +
  • Go to some page and follow the link to go to the respective page on +Github. (Alternatively, you can find the page from the Github repo directly).

  • +
  • Follow the Github flow to make a change, and open a Pull Request +with the change proposal:

    +
      +
    • Click on the pencil icon

    • +
    • Make a change

    • +
    • Follow the flow to make a commit and change. You’ll fork the +repository to make your own copy, add a message, and open a pull +request.

    • +
    +
  • +
+

We will look at these together and accept some changes.

+
+
+

Lesson-VCS-4: Clone and build a CodeRefinery lesson locally

+

In this exercise, you will use Git to clone one a CodeRefinery lesson +and try to preview it locally. It assumes installation and knowledge +of Git.

+
    +
  • Use this sample repository: +git-intro (or whatever +else you would like)

  • +
  • Clone the repository to your own computer

  • +
  • Create a virtual environment using the requirements.txt +contained within the repository.

  • +
  • Build the lesson.

    +
      +
    • Most people will probably run: sphinx-build content/ _build/

    • +
    • If you have make installed you can make html

    • +
    • Look in the _build directory for the built HTML files.

    • +
    +
  • +
+

Overall, this is pretty easy and straightforward, if you have a Python +environment set up. The CodeRefinery documentation +lesson teaches +this for every operating system.

+

This same tool can be used to build documentation for other software +projects and is pretty standard.

+
+
+

Lesson-VCS-5: (advanced) Create your own lesson using the CodeRefinery format

+

In this lesson, you’ll copy the CodeRefinery template and do basic +modifications for your own lesson.

+
    +
  • Clone the lesson template: +https://github.com/coderefinery/sphinx-lesson-template

  • +
  • Attempt to build it as it is (see the previous exercise)

  • +
  • How can you do tabs?

  • +
  • How can you highlight lines in code boxes?

  • +
  • How can you change color, logo and fonts?

  • +
  • What directives are available?

  • +
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Version control takes teaching materials to the next level: +shareable and easy to contribute

  • +
  • There are different formats that use version control, but we like +Sphinx with a sphinx-lesson extension.

  • +
+
+
+
+
+

How we collect feedback and measure impact

+
+

Objectives

+
    +
  • Discuss how one can collect feedback from learners (“what can we improve?”).

  • +
  • Discuss how we convert feedback into actionable items.

  • +
  • Discuss how we measure the impact of teaching (“did we achieve our goals?”).

  • +
  • Discuss the “why”.

  • +
  • Get to know the reasons and sources of inspiration behind major lesson and workshop updates.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 20 min

  • +
  • Exercises: 10 min

  • +
+
+
+

Asking questions before the workshop

+ +
+
+

Collecting feedback as we teach

+
    +
  • Each day we ask for feedback in the collaborative notes.

    +
      +
    • One good thing about today.

    • +
    • One thing to improve for next time.

    • +
    • Any other comments?

    • +
    +
  • +
  • During the workshop we sometimes check in and ask about the pace, example:

    +
    How is the speed so far? (add an "o")
    +- Too fast:   oooooo
    +- Too slow:   ooo
    +- Just right: ooooooooooooooooooo
    +
    +
    +
  • +
  • We publish all questions, answers, and feedback. Example: https://coderefinery.github.io/2024-03-12-workshop/questions/

  • +
  • How we follow up:

    +
      +
    • Some problems we can fix already before the next workshop day.

    • +
    • We convert feedback/problems into GitHub issues and track these close to the lesson material.

    • +
    +
  • +
+
+
+

Trying to measure impact with longer-term surveys

+ +
+
+

Lessons learned

+
    +
  • Think about how to measure impact/success from the beginning.

  • +
  • Make the feedback and survey results public.

  • +
  • Make the results persistent and citable.

  • +
  • Have a mechanism to follow-up on feedback.

  • +
  • Anonymization is more than just removing or dissociating names.

  • +
  • Take time designing your survey and collect feedback on the survey itself.

  • +
+
+
+

Take time designing your survey

+

We are not experts in survey design but we reached out to RISE Research +Institutes of Sweden to get feedback on our survey questions. They provided us +with a lot of valuable feedback and suggestions for improvements. +Below are few examples.

+
+

Example 1

+

First version of our survey question about impact:

+
    +
  • “Do our workshops help to save time in future?” Please quantify in hours saved: …

  • +
+

Feedback:

+
    +
  • Difficult to answer.

  • +
  • Since when? Until all eternity?

  • +
+
+Screenshot of earlier version of the survey question about impact. +
+

Earlier version of the survey question about impact.

+
+
+

Feedback:

+
    +
  • The question “Do our workshops help to save time in future?” is unspecified, +unnecessary, and leading.

  • +
  • “No time saving” does not match the wording “save time” in the question.

  • +
+
+Screenshot of later version of the survey question about impact. +
+

Later version of the survey question about impact.

+
+
+
    +
  • The wording “have you saved” now matches “No time saved”.

  • +
+
+
+

Example 2

+
    +
  • Earlier version:

    +
    Would you judge your code to be better reusable/reproducible/modular/documented
    +as a result of attending the workshop?
    +
    +- More reusable
    +- More reproducible
    +- More modular
    +- Better documented
    +- None of the above
    +
    +
    +
  • +
  • Feedback: The question is not neutrally formulated and risks leading to +over-reporting of yes answers. Consider balancing so that the questions are +formulated more neutrally.

  • +
  • Reformulated to:

    +
    After attending the workshop, would you judge your code to be
    +more reusable or not more reusable?
    +
    +- My code is more reusable
    +- My code is not more reusable
    +- Not sure
    +
    +
    +
  • +
+
+
+

Example 3

+
    +
  • Early version:

    +
    What else has changed in how you write code since attending the workshop?
    +
    +[free-form text field]
    +
    +
    +
  • +
  • Feedback: Leading and assumes that something has changed.

  • +
  • Reformulated to:

    +
    Has anything else changed in how you write code for your research after
    +attending the workshop?
    +
    +[free-form text field]
    +
    +
    +
  • +
+
+
+

Example 4

+
    +
  • Earlier version:

    +
    Has it become easier for you to collaborate on software development with your
    +colleagues and collaborators?
    +
    +- Yes
    +- Not sure
    +- No
    +
    +
    +
  • +
  • Feedback:

    +
      +
    • Leading question.

    • +
    • Avoid “Yes” and “No” response options because respondents tend to answer +“Yes” if that option is available, leading to a risk of measurement error +(acquiescence bias).

    • +
    • Do not place “Not sure” in the middle of the scale because it captures +participants who actually don’t know and should therefore be placed at the +bottom instead of in the middle of the scale.

    • +
    +
  • +
  • Reformulated to:

    +
    After attending the workshop, has it become easier or not for you to
    +collaborate on software development with your colleagues and collaborators?
    +
    +- Collaboration is easier
    +- Collaboration is not easier
    +- Not sure
    +
    +
    +
  • +
+
+
+
+

Exercise: Group discussion (10 min)

+
+

Group discussion using the collaborative notes

+
    +
  • What tricks/techniques have you tried in your teaching or seen in someone +else’s teaching that you think have been particularly effective in collecting +feedback from learners?

  • +
  • Can you give tips or share your experiences about how to convert feedback +into actionable items?

  • +
  • How do you measure the impact of your teaching? Any tips or experiences about +what you have tried or seen other courses do?

  • +
  • Anybody knows of good resources on survey design? Please link them in +the collaborative notes.

  • +
+
+
+
+
+
+
+

About the CodeRefinery project and CodeRefinery workshops in general

+
+

Objectives

+
    +
  • Discuss what CodeRefinery is and how we got here

  • +
  • Understand about the challenges to define our target audience

  • +
+
+

CodeRefinery is a +Nordic e-Infrastructure Collaboration (NeIC) +project that has started in October 2016 and is currently +funded until February 2025. We are working on the continuation plans.

+

The funding from 2022-2025 is designed to keep this project active +beyond 2025 by forming a support network and building a community of +instructors and contributors.

+
+

History

+

The CodeRefinery project idea grew out of two SeSE courses given at KTH Stockholm in 2014 and 2016. +The project proposal itself was submitted to NeIC in 2015, accepted in 2015, and started in 2016.

+

We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form.

+
+
+

Goals

+
    +
  • Develop and maintain training material on good enough software development practices for researchers that write code/scripts/notebooks.

  • +
  • Our material addresses all academic disciplines and tries to be as programming language-independent as possible.

  • +
  • Provide a code repository hosting service that is open and free +for all researchers based in universities and research institutes from Nordic countries.

  • +
  • Provide training opportunities in the Nordics using (Carpentries and) CodeRefinery training materials.

  • +
  • Evolve the project towards a community-driven project with a network of instructors and contributors.

  • +
+
+
+

Community

+
+_images/community.png +
+

Image showing the key areas of the CodeRefinery community: Workshops, chat inlcuding help channel, online meetings and co-working, +other collaborative training, eg on High Performance Computing topics.

+
+
+

CodeRefinery is not just workshops, we are community and want you to be part of it!

+

There are many different levels of involvement, from the occasional commenter in chat, +CodeRefinery ambassador (people who like the project and workshops and help us spreading the word) or lesson issue creators and lesson contributors to +local host, co-instructor or co-organizer.

+

Best first step in any case is to join the CodeRefinery Zulip chat +or let us know about your interest at support@coderefinery.org.

+
+
+

Target audience

+

One common question we get is how do we relate to the Carpentries. +This section describes how we see it:

+
+

Carpentries audience

+

The Carpentries aims to teach computational competence to learners through an applied approach, +avoiding the theoretical and general in favor of the practical and specific.

+

Mostly, learners do not need to have any prior experience in programming. +One major goal of a Carpentries workshop is to raise awareness on the tools researchers can learn/use to speed up their research.

+

By showing learners how to solve specific problems with specific tools and providing hands-on practice, +learners develops confidence for future learning.

+
+

Novices

+

We often qualify Carpentries learners as novices: they do not know what they need to learn yet. +A typical example is the usage of version control: the Carpentries lesson +Version Control with Git +aims to give a +very high level conceptual overview of Git but it does not explain how it can be used in research projects.

+
+
+
+

CodeRefinery audience

+

In that sense, CodeRefinery workshops differ from Carpentries workshops as we assume +our audience already writes code and scripts and we aim at teaching them best software practices.

+

Our learners usually do not have a good overview of best software practices but are aware of the need to learn them. +Very often, they know of the tools (Git, Jupyter, etc.) we are teaching +but have difficulties to make the best use of them in their software development workflow.

+

Whenever we can, we direct learners that do not have sufficient coding experience to Carpentries workshops.

+
+

Competent practitioners

+

We often qualify CodeRefinery learners as competent practitioners because they already have an understanding of their needs.

+
+ +
+
+

Keypoints: CodeRefinery

+
    +
  • Teaches intermediate-level software development tool lessons

  • +
  • It is difficult to define “best practices”, we try to teach “good enough” practices

  • +
  • Training network for other lessons

  • +
  • Publicly-funded discrete projects (3 projects actually) transitioning towards an open community project

  • +
  • We have online material, teaching, and exercise sessions

  • +
  • Our main target audience are competent practitioners, but also novices and experts can get something out of the workshops

  • +
  • We want more people to work with us, and to work with more people

  • +
+
+
+
+
+
+

Collaborative notes

+
+

Objectives

+
    +
  • Be able to provide a highly interactive online workshop environment with collaborative documents

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Exercise: 15 min

  • +
  • Questions & Answers: 5 min

  • +
+
+
+

Introduction

+

The Collaborative document is how you interact with the participants. +The participants can ask questions and give feedback through the collaborative +document. During a CodeRefinery session there can be a large a volume of questions. +A dedicated person, a Collaborative document-manager, is needed to answer and edit the collaborative document. +Let us see how the collaborative document is used, then discuss the role of +the editor or collaborative document-manager.

+
+
+

Collaborative document mechanics and controls

+

Technologies that can be used as a collaborative document are Hackmd, HedgeDoc, +or Google Docs

+

Hackmd or HedgeDoc are real-time text editor online. We use it to:

+
    +
  • As a threaded chat, to answer questions and provide other information without +interrupting the main flow of the room.

  • +
  • provide everyone with a more equal opportunity to ask questions.

  • +
  • create notes which will be archived, for your later reference.

  • +
+

You do not need to login/create an account to be able to edit the document.

+
+

Basic controls

+
+_images/hackmd--controls.png +
+

This may look slightly different on mobile devices and small windows.

+
+
+
    +
  • At the top (left or right), you can switch between view, +edit, and split view and edit modes.

  • +
  • You write in markdown here. Don’t +worry about the syntax, just see what others do and try to be like +that! Someone will come and fix any problems there may be.

  • +
  • Please go back to view mode if you think you won’t edit for a +while - it will still live update.

  • +
+
+
+

Asking questions

+

Always ask questions and add new sections at the very bottom. +You can also answer and comment on older questions, too.

+
+_images/hackmd--questions2.png +
+

Questions and answers in bullet points

+
+
+

Since we plan to publish the questions and answers later as part +of the workshop page, we recommend to not use any names. You can indicate +your own name to make it easier to discuss more during the workshop but +then always use this form: [name=Myname]. This makes it easier for +us to automatically remove all names before publishing the notes.

+

Other hints:

+
    +
  • Use +1 to agree with a statement or question (we are more likely +to comment on it).

  • +
  • Please leave some blank lines at the bottom

  • +
  • NOTE: Please don’t “select all”, it highlights for everyone and adds a +risk of losing data (there are periodic backups, but not instant).

  • +
  • It can be quite demanding to follow the collaborative document closely. Keep an eye +on it, but consider how distracted you may get from the course. For +things beyond the scope of the course, we may come back and answer +later.

  • +
+
+
+

Don’t get overwhelmed

+

There can be a flood of information on the collaborative document. Scan for what is +important, then if you would like come back later. But it is +important to keep checking it.

+
+
+

Privacy

+
    +
  • Assume the collaborative document is public and published: you never +need to put your name there.

  • +
  • The collaborative document will be published on the website afterwards. We will +remove all non-instructors names, but it’s easier if you don’t add +it there in the first place.

  • +
  • Please keep the link private during the workshop, since since +security is “editable by those who have the link”.

  • +
  • You can use [name=YOURNAME], to name yourself. We will remove +all names (but not the comments) before archiving the notes (use +this format to make it easy for us).

  • +
+
+
+
+

Exercise

+
+

Discuss how to collaborate and handle questions (15 min)

+

Write down your conclusions in the shared document. Items to discuss are:

+
    +
  • What is your experience with questions and discussions while teaching?

  • +
  • How do you deal with them?

  • +
  • What kind of technologies do you prefer: chat, shared document, or voices +and discussion raised during instruction? And why?

  • +
+
+
+
+

Collaborative Document Manager

+

We have one person who is a “Collaborative Document helper”. This isn’t the only +person that should edit and answer, but one person shouldn’t have too +much else on their mind so can focus on it. They also make sure that +the collaborative document is updated with exercise, break, and other meta-information to +keep people on track.

+

Below, (*) = important.

+
+

Before the workshop

+
    +
  • Create a new collaborative document for the workshop

  • +
  • make sure that editing is enabled for anyone without login

  • +
  • Add workshop information, links to the workshop page and material +and an example question and answer to the top of the collaborative document(see below)

  • +
+
+
+

Most things to edit (everyone)

+

Make it easy to post after the course and consistent to follow:

+
    +
  • Tag all names with [name=XXX] (so they can be removed later), +remove other personal data or make it obvious.

  • +
  • Add in information on exercises (new section for them, link, end +time, what to accomplish)

  • +
  • Make a logical section structure (# for title, ## for sections, +### for episodes, etc. - or what makes sense)

  • +
+
+
+

General Collaborative Document practices

+
+_images/hackmd--full-demo.png +
+

A live demo of a Collaborative Document during a Q&A time. The two instructors are +discussing some of the import answers. Multiple learners have asked +questions, multiple answers, and some remaining to be answered

+
+
+

Keep it formatted well:

+
    +
  • (*) Tag names you see with [name=XXX] so that we can remove it +later.

  • +
  • Heading level # is only the page title

  • +
  • Add a new ## heading when a new lesson or similar thing is +started (introduction, icebreaker, break between lessons, etc)

  • +
  • Add a new ### heading when a new episode, exercise, break +(within exercise session)

  • +
  • Ensure people are asking questions at the bottom, direct them there +if they aren’t.

  • +
  • (*) Ensure each question is a bullet point. Each answer or follow-up +should be a bullet point below.

    +
      +
    • Should you use more deeply nested bullet points, or have only one +level below the initial question? It depends on the context, but +if a conversation goes on too long, try not to let it go too +deep.

    • +
    +
  • +
+

Update with meta-talk, so that learners can follow along easily:

+
    +
  • Add Icebreaker and introductory material of the day. Try to talk to +people as they joined to get them to open the collaborative document and answer.

  • +
  • Anything important for following along should not be only said via +voice. It needs to be in the collaborative document, too.

  • +
  • New lessons or episodes, with links to them.

  • +
  • For exercises, link to exercise and add the duration, end time, +goals. If these are unclear, bring it up to the instructor by voice.

  • +
  • Add a status display about breaks.

  • +
+

Screenshare it when necessary:

+
    +
  • During breaks and other times, share the collaborative document(including the +notification about break, and when it ends).

  • +
  • It is nice if the arrangement allows some of the latest questions to +be seen, so people are reminded to ask there.

  • +
  • Someone else may do this, but should make sure it happens.

  • +
+

Answer questions

+
    +
  • If there is an question that should be answered by the instructor by +voice, bring it up (by voice) to the instructor immediately.

  • +
  • How soon do you answer questions? Two points of view:

    +
      +
    • Answer questions right away: can be really intense to follow.

    • +
    • Wait some so that we don’t overload learners: reduces the info +flow. But then do people need to check back more often.

    • +
    • You need to find your own balance. Maybe a quick answer right +away, and more detailed later. Or delay answers during the most +important parts of the lecture.

    • +
    +
  • +
  • Avoid wall-of-text answers. If reading an answer takes too long, it +puts the person (and other people who even try to read it) behind +even more by taking up valuable mental energy. If an answer needs a +wall of text, consider these alternatives:

    +
      +
    • Progressive bullet points getting more detailed (first ones +useful alone for basic cases)

    • +
    • Don’t be worried to say “don’t worry about this now, let’s talk +later.”

    • +
    • Figure out the root problem instead of answering every possible +interpretation

    • +
    • Declare it advanced and that you will come back later.

    • +
    +
  • +
+

Ensure it can be posted quickly:

+
    +
  • The collaborative document gets posted to the workshop webpage. For this, it needs some +minimal amount of formatting (it doesn’t need to be perfect, just +not horrible).

  • +
  • All names and private information needs to be stripped. This is why +you should rigorously tag all names with [name=XXX] so they can be +removed (see above).

    +
      +
    • Learner names can be completely removed. CR staff names can be +[name=CR] or something similar.

    • +
    • There may be other private URLs at the top or bottom.

    • +
    +
  • +
  • If possible, send the PR adding the collaborative document to the workshop webpage +(though others can do this, too).

  • +
+
+
+

Collaborative document format example

+
# Workshop, day 1
+
+
+## Lesson name
+https://coderefinery.github.io/lesson/
+
+### Episode name
+https://coderefinery.github.io/01-episode/
+
+- This is a question
+  - Anwser
+  - More detailed answer
+- question
+  - answer
+
+### Exercises:
+https://link-to-exercise/.../.../#section
+20 minutes, until xx:45
+Try to accomplish all of points 1-3.  Parts 4-5 are optional.
+
+Breakout room status:
+- room 2, need help with Linux permissions
+- room 5, done
+
+### Break
+:::danger
+We are on a 10 minute break until xx:10
+:::
+
+
+## Lesson 2
+https://coderefinery.github.io/lesson-2/
+
+
+
+
+
+

Posting the collaborative document to the website

+

The collaborative document should be posted sooner rather than later, and hopefully the +steps above will make it easy to do so quickly. You could wait a few +hours, to allow any remaining questions to be asked an answered.

+
    +
  • Download as markdown

  • +
  • Remove any private links at the top

  • +
  • Adjust headings so that they are reasonable

  • +
  • Look for private info and remove it

    +
      +
    • Search document for [name=???] (change to [name=staff] or +[name=learner])

    • +
    • Any names not tagged with [name=]

    • +
    • usernames in URLs

    • +
    • private links

    • +
    +
  • +
+
+
+

Feedback template

+
## Feedback, day N
+
+:::info
+### News for day N+1
+- .
+- .
+:::
+
+### Today was (multi-answer):
+- too fast: 
+- just right: 
+- too slow: 
+- too easy: 
+- right level: 
+- too advanced: 
+- I would recommend this course to others: 
+- Exercises were good: 
+- I would recommend today to others: 
+- I wouldn't recommend today: 
+
+### One good thing about today:
+- ...
+- ...
+
+### One thing to be improved for next time:
+- ...
+- ...
+
+### Any other comments:
+- ...
+- ...
+
+
+
+

Keypoints

+
    +
  • Having a collaborative document improves communication and interaction.

  • +
  • Answering questions requires a dedicated person - A Collaborative Document Manager.

  • +
  • The collaborative document should be posted on the web site as soon as possible.

  • +
+
+
+
+
+
+

A workshop seen from different perspectives

+
+

Objectives

+
    +
  • Understand the general structure of CodeRefinery workshops and why it is the way it is

  • +
  • Get to know the different roles of a workshop and which ones are the most essential ones

  • +
  • Understand the importance of installation instructions and how they contribute to learners success

  • +
  • Understand the importance of onboarding and a welcoming community for volunteers in a workshop

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 15 min

  • +
  • Roles journeys can be shortened to looking only at instructor role.

  • +
+
+
+

Note

+

This episode focuses on the large scale streamed workshop setup. Some of the features can also be applied to smaller scale workshops though.

+
+
+

Discussion

+
+

Discussion

+

In breakoutrooms: choose one or two questions to talk about your own experiences; summary in collaborative notes:

+
    +
  • What kind of roles have you been in yourself regarding workshops?

  • +
  • How were you prepared for your role?

  • +
  • What are the things you would like to know before a workshop?

  • +
  • How are you preparing your participants for your trainings?

  • +
  • What was the best workshop experience for you as learner, helper or instructor? What made it great?

  • +
+
+
+
+

One workshop - many parts

+
+_images/CR_workshop_setup.png +
+

Image showing the different phases of a CodeRefinery workshop described below. Also showing that while there is only two people teaching, many people work behind the scenes.

+
+
+
+

Before the workshop

+
    +
  • During winter/summer: “Someone” takes the coordinator role for the next workshop

  • +
  • Coordinator fills other roles:

    +
      +
    • Coordinator: collects necessary lesson updates, supports other coordinators

    • +
    • Registration coordinator: Sets up web page, starts and manages registration

    • +
    • Instructor coordinator: Finds instructors and onboards them

    • +
    • Advertising coordinator: Prepares advertizement texts and finds people to distribute them

    • +
    • Team coordinator: Gathers local organizers/teams

    • +
    • Bring your own code session coordinator: If available, offer BYOC session after main workshop

    • +
    +
  • +
  • Instructor: Onboarding with (instructor-) coordinator and previous instructor of lesson; update of lesson materials (urgent issues and personal touches)

  • +
  • Local organizer/Team lead: Group onboarding ~ week/or two before workshop

  • +
  • Learner: Gets installation instructions, invited to installation help session, workshop info from event page and summary via e-mail

  • +
  • Collaborative notes manager sets up the notes document

  • +
+
+

Note

+

Onboarding manuals

+
    +
  • Outline of what will happen during the workshop

  • +
  • Discussion of different strategies to handle the exercise sessions

  • +
  • Lowering the barrier to ask for support by meeting some organizers

  • +
  • Q&A

  • +
+
+
+

Note

+

Installation instructions

+
    +
  • Instructions for all operating systems

  • +
  • Goal: Learners leave the workshop and are ready to apply the learned tools and techniques to their own work

  • +
  • Support session for installation challenges

  • +
+
+
+
+

During the workshop

+
+_images/BYOC.png +
+

Image showing the different ways learners can do the exercises. No matter which way they choose, they always watch the stream and interact with instructors and organizers via collaborative notes. Individual learners do the exercises alone, people in online or local classrooms in addition get to discuss with their peers.

+
+
+
    +
  • Everyone watches stream

  • +
  • Co-instructors +- Present content +- Answer questions in collaborative notes

  • +
  • Collaborative notes manager

    +
      +
    • Keeps the collaborative notes clean

    • +
    • Helps answering questions

    • +
    • Adds sections

    • +
    • Archives the document after each day

    • +
    +
  • +
  • Learners do exercises individually or in team

  • +
  • Local organizer / Team lead

    +
      +
    • Guides learners through exercises

    • +
    • Facilitates discussion

    • +
    +
  • +
  • (Registration-) coordinator sends out e-mails to participants after each day (summary + preparation)

  • +
  • Director/Broadcaster manages the streaming (see session 4)

  • +
+
+
+

After the workshop

+
    +
  • Coordinator collects lessons learned based on experience and feedback and turns them into issues

  • +
  • Coordinator organizes debriefing week after the workshop, where anyone can join to give feedback

  • +
  • “Someone” sends out post-workshop survey half a year after workshop

  • +
  • Coordinator organizes “Bring your own code” sessions

  • +
  • Broadcaster prepares and shares recording (see session 4)

  • +
+
+

Note

+

Bring your own code sessions

+

We want to support learners to apply what they have learned in the workshop to their own work by offering one/two sessions where they can drop in, and discuss challenges with CodeRefinery instructors and helpers.

+
+_images/welcome.png +
+

Image showing a classroom learning about git leading to a discussion between student and teacher to start a welcoming environment for asking for help.

+
+
+
+
+
+
+

This sounds like a lot of people and time investment!

+
    +
  • Many roles can be combined or adjusted as needed

  • +
  • Some roles can be taken on by multiple people

  • +
+

So how many people are needed for this kind of workshop?

+
    +
  • Recommended minimum: 2-3 people

  • +
  • Optimum: ~ 4-5 people +The more people you involve, the more time goes into coordination work.

  • +
+
+
+

How did we get to this setup?

+
    +
  • Collaborative in-person workshops since 2016 around the Nordics

  • +
  • Moved online in 2020

  • +
  • Started with “traditional zoom” workshops, breakoutrooms, volunteer helpers

  • +
  • Thought about scaling and ease of joining -> current setup (More about this in session 4)

  • +
  • Continuous development

  • +
+

We also still do smaller scale local workshops, if instructors are available. +You can offer your own CodeRefinery workshop by inviting other CodeRefinery instructors. +You can also reuse single lessons and integrate them into your own teaching.

+
+
+

Workshop roles and their journeys

+
+

Individual learner journey

+
    +
  • Registration

  • +
  • Installation

  • +
  • (if appicable: Invited to local meetup)

  • +
  • Workshop

    +
      +
    • Watch stream

    • +
    • Q&A in notes

    • +
    • Exercises alone or in team

    • +
    • Daily feedback

    • +
    +
  • +
  • Debrief/ Feedback session

  • +
  • Post workshop survey

  • +
+
+
+

Instructor journey

+
    +
  • Indicate interest in CodeRefinery chat

  • +
  • Onboarding

  • +
  • Lesson material updates

  • +
  • Teaching

  • +
  • (if wished: supports answering questions in notes)

  • +
  • Debrief

  • +
+
+
+

Team lead / Local host journey

+
    +
  • Registration

  • +
  • (if applicable: run own registration)

  • +
  • Onboarding

  • +
  • Workshop

    +
      +
    • Watch stream

    • +
    • Facilitate exercises/discussions

    • +
    • Daily feedback

    • +
    +
  • +
  • Debrief / feedback / survey

  • +
+
+
+

Other roles

+

Director and broadcaster roles will be discussed in Session 4. +For more in-depth descriptions and other roles (host, instructor, registration coordinator, etc), see also our CodeRefinery manuals.

+
+
+
+

Different roles as stepping stones for community involvement

+
+_images/steps.png +
+

Image showing a person jumping from step to step following learner, helper, expert helper, co-instructor, co-organizer.

+
+
+

There is no “one way” to get involved. Do what feels right. +Interested in teaching with us? Let us know and we can discuss what is a suitable path for you!

+
+

Keypoints

+
    +
  • CodeRefinery workshops are a collaborative effort with many different roles

  • +
  • Onboarding the different roles is one key aspect of our workshops

  • +
  • Everyone has their own path

  • +
+
+
+
+
+

Sound

+
+

Objectives

+
    +
  • Understand that sound quality is very important

  • +
  • Evaluate your and others sound quality and know how to improve it

  • +
  • Test tips and tricks for achieving good sound quality

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Exercises: 10 min

  • +
+
+
+

The importance of audio

+
    +
  • Pleasing audio quality makes events much more enjoyable

  • +
  • Audio is one of the most important things you can control

  • +
  • Things that can go wrong:

    +
      +
    • Too quiet

    • +
    • Too loud

    • +
    • Instructors’ volumes imbalanced

    • +
    • Background noise

    • +
    • Low-quality/breaking up audio hard to hear.

    • +
    • “Ducking” (first words lower volume, or lower volume other times)

    • +
    +
  • +
+
+
+

Tips for good sound quality

+
    +
  • Have a headset with mounted microphone

    +
      +
    • Even if you have a professional external microphone, it doesn’t +matter if your room has bad acoustics.

    • +
    • The close pickup can’t be beat with normal tools.

    • +
    • As long as it’s headset mounted, price doesn’t seem to matter +that much.

    • +
    +
  • +
  • Don’t use Bluetooth

    +
      +
    • Bluetooth can have too much latency (300-500ms)

    • +
    • This may seem small but for interactive work, it’s a lot

    • +
    • Use a wired headset, or wireless with a non-Bluetooth USB plug +(like gaming headsets have). These have much lower latency.

    • +
    • Bluetooth 5 can have much lower latency, but you probably +shouldn’t count on that without testing.

    • +
    • It can also have lower sound quality on some devices due to +bandwidth limitations.

    • +
    +
  • +
  • Once you have a headset, turn input noise cancellation to low +(wherever it might be: headphone, meeting software, etc.).

  • +
+
+
+

Balancing and dynamic adjustment

+
    +
  • It’s important that instructors volumes match.

  • +
  • An exercise will go over a systematic procedure for matching +volumes.

    +
      +
    • Practice so that you can do this quickly.

    • +
    +
  • +
  • May need re-adjusting when instructors swap out or start getting +excited.

  • +
  • An exercise below will demonstrate our procedure.

  • +
+
+
+

Speak up when there are problems

+
    +
  • If you notice someone with audio issues, let them know right away +(voice if bad, or chat/notes if less urgent).

  • +
  • Take the time to fix it as soon as practical.

  • +
  • Make a culture of speaking up, helping, and not suffering.

  • +
+
+
+

Recommendations

+
    +
  • Procure some reasonable headset.

  • +
  • Low/medium-priced gaming-type headsets have worked well for us.

    +
      +
    • (gaming headsets usually aren’t Bluetooth, because gaming needs +low latency.)

    • +
    +
  • +
  • Show this page to your workplace (if you have one) and call a good +headset work equipment.

  • +
+
+
+

Exercises

+
+

Sound-1: Evaluate sound quality

+

It’s important to be able to discuss with others the quality of their +audio. They can’t hear themselves, after all.

+
    +
  • Within the teams, discuss each person’s audio quality and what kind +of setup they have.

  • +
  • Be respectful and constructive (and realize that people came +prepared to listen, not teach).

  • +
  • Consider, for example

    +
      +
    • Volume

    • +
    • Clarity

    • +
    • Background noise

    • +
    • Noise cancellation artifacts

    • +
    • “Ducking”: first words at lower volume or missing

    • +
    +
  • +
  • Discuss how to bring this up during other courses and meetings.

  • +
+
+
+

Sound-2: Adjust volume up and down

+

In addition to individual quality, it is important that sound is +balanced among all instructors. Have you ever been to a event when +one person is too quiet and they can’t make themselves any louder? +And they can’t adjust it?

+

You should ensure that you have a range of volumes available to you. +You might have to look into several different locations in order to +make the full adjustment ().

+
    +
  • Go to your sound settings

  • +
  • One by one, each person

    +
      +
    • Adjusts their microphone volume so quiet that they can’t be heard.

    • +
    • Adjusts their microphone volume so that it is extremely loud (this +may require going beyond 100% if possible).

    • +
    +
  • +
  • Basically, make sure you aren’t so close to either end that you have +no potential to make an adjustment in that direction.

  • +
  • Everyone tries to set the volume to something reasonable, in +preparation for the next exercise.

  • +
+

Once you know where these settings are , you won’t be panicked when the +volume is too low or high during a course.

+
+
+

Sound-3: Do a balance check

+

It’s important that instructor audio is balanced (the same volume). +But how can you do this?

+
    +
  • Pick a leader.

  • +
  • The leader decides the order (“I am first, then [name-1] and +[name-2]”)

  • +
  • The leader says “one”. Everyone else says “one” in the order +specified.

  • +
  • The leader says “two”. Everyone else says “two” in the order.

  • +
  • The leader asks for opinions on who they think is louder or softer. +If there are more than three people, you can figure it out +yourselves. With less than two, you have to ask someone in the +audience.

  • +
+

Example:

+
    +
  • Leader: Let’s do a sound check. I am first, then AAA and BBB.

  • +
  • Leader: One

  • +
  • AAA: One

  • +
  • BBB: One

  • +
  • Leader: Two

  • +
  • AAA: Two

  • +
  • BBB: Two

  • +
  • Leader: Three

  • +
  • AAA: Three

  • +
  • BBB: Three

  • +
  • Leader: How did that sound to everyone?

  • +
  • [Someone else]: Leader and BBB were pretty similar but AAA is a bit +lower.

  • +
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Audio quality is important and one of the most notable parts of the +workshop.

  • +
  • Improving audio isn’t hard or expensive, but does require preparation.

  • +
+
+
+
+
+

How to prepare a quality screen-share

+
+

Objectives

+
    +
  • Discuss the importance of a well planned screen-share.

  • +
  • Learn how to prepare and how to test your screen-share setup.

  • +
  • Know about typical pitfalls and habits to avoid.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 15 min

  • +
  • Exercises: 15 min

  • +
+
+
+

Share portrait layout instead of sharing entire screen when teaching online

+
    +
  • Many learners will have a smaller screen than you.

  • +
  • You should plan for learners with only one small screen.

  • +
  • A learner will need to focus on both your screen share and their +work.

  • +
  • Share a portrait/vertical half of your screen (840 × 1080 is our standard and your +maximum).

  • +
  • Zoom provides a “Share a part of screen” that is good for this.

    +
      +
    • Our latest streaming setup (day 4) can take the portrait part for +you so you can share landscape.

    • +
    • Zoom + Linux + Wayland display manager doesn’t have “Share a +portion of the screen”

      +
        +
      • You can share a single window portrait.

      • +
      • Or you can start your desktop session in “X11” or “Xorg” legacy +mode.

      • +
      • Or possibly other workarounds (does anyone know other solutions?)

      • +
      +
    • +
    +
  • +
+
+_images/landscape.png +
+

A FullHD 1920x1080 screen shared. Learners have to make this really small if +they want to have something else open.

+
+
+
+_images/portrait.png +
+

Portrait layout. Allows learners to have something else open in the other half.

+
+
+

Motivation for portrait layout:

+
    +
  • This makes it easier for you to look at some other notes or to coordinate +with other instructors at the same time +without distracting with too much information.

  • +
  • This makes it possible for participants to have something else open in the +other screen half: terminal or browser or notebook.

  • +
+
+

Instructor perspective

+
+_images/instructor.png +
+

I1: +This is how it can look for the instructor. Zoom is sharing a portion of the left +side, the right side is free for following notes, chat, etc.

+
+
+
+
+

Learner perspective

+

Here are three examples of how it can look for the learner.

+
+_images/learner-large.png +
+

L1: +Learner with a large screen, Zoom in dual-monitor mode so that the instructor +pictures are not shown. Screen-share is on the left side, collaborative notes +at bottom left, terminal and web browser on the right.

+
+
+
+_images/learner-normal.png +
+

L2: +A learner with a single large screen (Zoom in “single monitor mode”). +Instructor screen share at right, learner stuff at left.

+
+
+
+_images/learner-small.png +
+

L3: +A learner with a particularly small screen. Instructor screen-share at left, +your windows at right.

+
+
+
+
+
+

Share the history of your commands

+

Even if you type slowly it is almost impossible to follow every command. We +all get distracted or want to read up on something or while following a command +fails on the learner laptop while instructor gets no error.

+

Add pauses and share the commands that you have typed so that one can catch up.

+

Below are some examples (some more successful than others) of sharing history +of commands.

+
+_images/history-portrait.png +
+

H1: +A vertical screen layout shared. Note the extra shell history at the top. The +web browser is at the bottom, because the Zoom toolbar can cover the bottom +bit.

+
+
+
+_images/history-rsh.png +
+

H2: +This isn’t a screen-share from CodeRefinery, but may be instructive. Note the +horizontal layout and shell history at the bottom right.

+
+
+
+_images/history-landscape-dark.png +
+

H3: +Similar to above, but dark. Includes contents on the right.

+
+
+
+_images/history-portrait-light.png +
+

H4: +Jupyter + terminal, including the fish shell and the terminal history.

+
+
+
+_images/history-portrait-dark.png +
+

H5: +Lesson + terminal, tmux plus terminal history and dark background.

+
+
+
+_images/portrait.png +
+

H6: +HPC Kickstart course. Note the colors contrast of the windows and colors of +the prompt and text. The history is smaller and doesn’t take up primary +working space. The working directory is in the window title bar.

+
+
+
+https://raw.githubusercontent.com/bast/history-window/main/demo.gif +
+

H7: +Show command history “picture-in-picture”, in the same terminal window.

+
+
+
+
+

How to configure history sharing

+

You need to find a way to show the recent commands you have entered, so that +learners can see the recent commands. Below are many solutions. Try them out +and see what works for you.

+
    +
  • prompt-log: +It adds a interesting idea that the command you enter is in color and also +provides terminal history before the command returns.

  • +
  • Simple: The simple way is PROMPT_COMMAND="history -a" and then +tail -f -n0 ~/.bash_history, but this doesn’t capture ssh, +sub-shells, and only shows the command after it is completed.

  • +
  • Better yet still simple: Many Software Carpentry instructors use +this script, +which sets the prompt, splits the terminal window using tmux and displays command history +in the upper panel. Requirement: tmux

  • +
  • Better (bash): This prints the output before the command is run, +instead of after. Tail with tail -f ~/demos.out.

    +
    BASH_LOG=~/demos.out
    +bash_log_commands () {
    +    # https://superuser.com/questions/175799
    +    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    +    [[ "$PROMPT_COMMAND" =~ "$BASH_COMMAND" ]] && return # don't cause a preexec for $PROMPT_COMMAND
    +    local this_command=`HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"`;
    +    echo "$this_command" >> "$BASH_LOG"
    +}
    +trap 'bash_log_commands' DEBUG
    +
    +
    +
  • +
  • Better (zsh): This works like above, with zsh. Tail with tail -f ~/demos.out.

    +
    preexec() { echo $1 >> ~/demos.out }
    +
    +
    +
  • +
  • Better (fish): This works like above, but for fish. Tail with +tail -f ~/demos.out.

    +
    function cmd_log --on-event fish_preexec ; echo "$argv" >> ~/demos.out  ; end
    +
    +
    +
  • +
  • Better (tmuxp): This will save some typing. +TmuxP is a Python program (pip install tmuxp) that gives you programmable tmux sessions. One configuration that +works (in this case for fish shell):

    +
    session_name: demo
    +windows:
    +  - window_name: demo
    +    layout: main-horizontal
    +    options:
    +      main-pane-height: 7
    +    panes:
    +      - shell_command:
    +          - touch /tmp/demo.history
    +          - tail -f /tmp/demo.history
    +      - shell_command:
    +          - function cmd_log --on-event fish_preexec ; echo "$argv" >> /tmp/demo.history  ; end
    +
    +
    +
  • +
  • Windows PowerShell: In Windows Terminal, +a split can be made by pressing CTRL+SHIFT+=. Then, in one of the splits, the following +PowerShell command will start tracking the shell history:

    +
    Get-Content (Get-PSReadlineOption).HistorySavePath -Wait
    +
    +
    +

    Unfortunately, this only shows commands after they have been executed.

    +
  • +
  • Tavatar: shell history mirroring teaching tool can copy recent history to a remote server.

  • +
  • history-window: Show command +history “picture-in-picture” when teaching command line. Requires Bash.

  • +
+
+
+

Font, colors, and prompt

+
+

Terminal color schemes

+
    +
  • Dark text on light background, not dark theme. Research and our +experience says that dark-text-on-light is better in some cases and +similar in others.

  • +
  • You might want to make the background light grey, to avoid +over-saturating people’s eyes and provide some contrast to the pure +white web browser. (this was an accessibility recommendation when +looking for ideal color schemes)

  • +
  • Do you have any yellows or reds in your prompt or program outputs? +Adjust colors if possible.

  • +
+
+
+

Font size

+
    +
  • Font should be large (a separate history terminal can have a smaller +font).

  • +
  • Be prepared to resize the terminal and font as needed. Find out +the keyboard shortcuts to do this since you will need it.

  • +
+
+
+

Prompt

+

At the beginning of the workshop your goal is to have a shell +as easy to follow as possible and as close to what learners will +see on their screens:

+
    +
  • Your prompt should be minimal: few distractions, and not take up many +columns of text.

  • +
  • prompt-log does +this for you.

  • +
  • The minimum to do is is export PS1='\$ '.

  • +
  • Blank line between entries: export PS1='\n\$ '.

  • +
  • Have a space after the $ or % or whatever prompt character you +use.

  • +
  • Strongly consider the Bash shell. This is what most new people will +use, and Bash will be less confusing to them.

  • +
  • Eliminate menu bars and any other decoration that uses valuable +screen space.

  • +
  • Add colors only if it simplifies the reading of the prompt.

  • +
+

Later in the workshop or in more advanced lessons:

+
    +
  • Using other shells and being more adventurous is OK - learners will +know what is essential to the terminal and what is extra for your +environment.

  • +
+

Try to find a good balance between:

+
    +
  • Showing a simple setup and showing a more realistic setup.

  • +
  • Showing a consistent setup among all instructors and showing a +variety of setups.

  • +
+
+
+
+

Habits we need to un-learn

+
    +
  • Do not clear the terminal. Un-learn CTRL-L or clear if possible. +More people will wonder what +just got lost than are helped by seeing a blank screen. Push +ENTER a few times instead to add some white space.

  • +
  • Do not rapidly switch between windows or navigate quickly between multiple +terminals, browser tabs, etc. This is useful during your own work when nobody +is watching, but it is very hard to follow for learners.

  • +
  • Avoid using aliases or shortcuts that are not part of the +standard setup. Learners probably don’t have them, and they will fail +if they try to follow your typing. Consider even to rename corresponding +files (.bashrc, .gitconfig, .ssh/config, .ssh/authorized_keys, .conda/*).

  • +
  • Be careful about using tab completion or reverse history search if these +haven’t been introduced yet.

  • +
+
+
+

Desktop environment and browser

+
    +
  • Try to remove window title bars if they take up lots of space +without adding value to the learner.

  • +
  • Can you easily resize your windows for adjusting during teaching?

  • +
  • Does your web browser have a way to reduce its menu bars and other +decoration size?

    +
      +
    • Firefox-based browsers: go to about:config and set +layout.css.devPixelsPerPx to a value slightly smaller than one, +like 0.75. Be careful you don’t set it too small or large since +it might be hard to recover! When you set it to something smaller +than 1, all window decorations become smaller, and you compensate +by zooming in on the website more (you can set the default zoom to +be greater than 100% to compensate). Overall, you get more +information and less distraction.

    • +
    +
  • +
+
+
+

How to switch between teaching setup and work setup?

+
    +
  • Make a dedicated “demos” profile in your terminal emulator, if +relevant. Or use a different terminal emulator just for demos.

  • +
  • Same idea for the browser: Consider using a different browser profile for +teaching/demos.

  • +
  • Another idea is to containerize the setup for teaching. +We might demonstrate this during the Sharing teaching gems session later.

  • +
+
+
+

Keypoints

+
    +
  • Share portrait layout instead of sharing entire screen

  • +
  • Adjust your prompt to make commands easy to read

  • +
  • Readability and beauty is important: adjust your setup for your audience

  • +
  • Share the history of your commands

  • +
  • Get set up a few days in advance and get feedback from someone else. +Feedback and time to improve is very important to make things clear and accessible. +10 minutes before the session starts is typically too late.

  • +
+
+
+
+

Exercises

+
+

Evaluate screen captures (20 min)

+

Evaluate screenshots on this page. Discuss the trade-offs of each one. Which +one do you prefer? Which are useful in each situation?

+

Please take notes in the collaborative document.

+
+
+

Set up your own environment (20 min)

+

Set up your screen to teach something. Get some feedback from another learner +or your exercise group.

+
+
+
+

Other resources

+ +
+
+
+
+
+

Computational thinking

+
+

Objectives

+
    +
  • Explain what is computational thinking

  • +
  • Get to know how the theory of computational thinking can be used in teaching

  • +
  • Short exercise

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 10 min

  • +
+
+

Materials available as slides.

+
+

Keypoints

+
    +
  • Computational Thinking consists of 4 main parts: decomposition, pattern recognition, abstraction and algorithmic design.

  • +
  • How can this be a useful framework for solving problems?

  • +
  • How can this be used practically?

  • +
+
+
+
+

CodeRefinery teaching philosophies

+
+

Objectives

+
    +
  • Get to know the teaching philosophies of CodeRefinery instructors

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Discussion: 20 min

  • +
+
+
+

Introduction

+

During this episode we split into breakoutrooms and discuss own teaching philosophies. +Collect your teaching philosophies in the collaborative document. We will be going through +these and the end of the lesson.

+
+

Ice-breaker in groups (20 minutes)

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+
+

Instructor views

+

Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops.

+

It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us.

+
+

Video recordings

+

We have recorded some of the below as videos: https://www.youtube.com/playlist?list=PLpLblYHCzJAAHF89P-GCjEXWC8CF-7nhX

+
+
+

Bjørn Lindi

+

My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this “BLOB” (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the “BLOB”, to be able to share it with others.

+

In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic.

+

When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson.

+

Tools that I find useful in preparing a lesson is concept maps and Learner Personas (though I have developed too few of them):

+ +
+
+

Radovan Bast

+

My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos.

+

My goal for a lesson is to spark curiosity to try things after the lesson, both +for the novices (“This looks like a useful tool, I want to try using it after +the workshop.”) and the more experienced participants (“Aha - I did not know +you could do this. I wonder whether I can make it work with X.”). I like to +start lessons with a question because this makes participants look up from +their browsers.

+

Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise.

+

For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate the +answer.

+

I try to avoid jargon and “war stories” from the professional developers’ +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid “customer”, +“production”, also a lot of Agile jargon is hard to relate to.

+

Less and clear is better than more and unclear. Simple examples are better than +complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +“simply”, “just”, “easy”. If participants take home one or two points from a +lesson, that’s for me success.

+

I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don’t want to be +surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or slide. +This allows me to skip and distill the essence and not read bullet point by +bullet point.

+

I try to never deviate from the script and if I do, be very explicit about it.

+

A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel listening to me.

+

I very much like the co-teaching approach where the other person helps +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson.

+
+
+

Sabry Razick

+

My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case.

+
+
+

Richard Darst

+

Like many people, I’ve often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I’ve realized long ago that my most important lessons weren’t +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I’ve realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds.

+

My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I’m often start at the +very basics, because this is what I see missing most often.

+

When teaching, I like lots of audience questions and don’t mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don’t have to know everything perfectly, just show how +you’d approach a problem.

+
+
+

Stepas Toliautas

+

I aim for my learners to understand things (concepts, techniques…), instead of just memorizing them. The phrase I use from time to time when teaching information technology topics (be it hardware or software) is “there is no magic”: everything can be explained if necessary. While CodeRefinery also emphasizes usefulness/ immediate applicability of the content, often having the correct notions actually helps to start using them sooner and with less mistakes.

+

I try to guide my audience through the presented material with occasional questions related to previous topics and common knowledge – to help them link the concepts already during the lesson. I’m also fully aware that waiting for someone to answer is quite uncomfortable in-person and doubly so in an online environment, especially if no one uses their cameras :)

+

And if I get the question I don’t have the answer for (or material to show it) at the moment, in university classes I prepare and come back to it next time. While with one-off workshops there might not be a “next time”, open-source material used by CodeRefinery allows to have the same outcome: the latest and greatest version stays available for self-study afterwards.

+
+
+
+

Summary

+
+

Keypoints

+
    +
  • People have different viewpoints on teaching.

  • +
+
+
+
+
+

Co-teaching

+
+

Objectives

+
    +
  • Get to know the principle of co-teaching: How we do it and how you can too.

  • +
  • Learn the team teaching concept and how to tailor it to your situation.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 15 min

  • +
  • Exercises: 10 min

  • +
  • Discussion: 5 min

  • +
+
+
+

Overview

+

CodeRefinery lessons benefit from the application of the concepts of co-teaching.

+
+

Co-teaching

+

Co-teaching can be defined as “the division of labor between educators to plan, organize, instruct and make assessments on the same group of students, generally in a common classroom, and often with a strong focus on those teaching as a team complementing one another’s particular skills or other strengths”.

+
+

Co-teaching can be used in various forms, some of which are present in our workshops:

+
    +
  • Teaching + support, e.g. one of the teachers leading instruction while the other watches over and maintains the collaborative document (HackMD/HedgeDoc/…).

  • +
  • Another similar example is remote learning groups that watch the streamed CodeRefinery lessons guided by the local instructors.

  • +
  • Having open-source material and planning jointly allows multiple instances of a lesson to be held by multiple teachers:

    +
      +
    • parallel teaching, to different audiences at the same time,

    • +
    • alternative teaching, to different audiences at the same or different time, with potential content adjustments (for example, different installation procedures).

    • +
    +
  • +
  • Team teaching, where the lesson is presented by multiple (in most cases, two) teachers who actively engage in conversation with each other. The team-teaching concept is explained in more detail in the CodeRefinery manual.

  • +
+

In reality, different forms are very often mixed or fused together, even within a single lesson.

+

Co-teaching is not an online-only concept. However, it is very practical in online teaching due to larger number of instructors and learners potentially available to join a teaching session.

+
+
+

Co-teaching and team teaching benefits

+
    +
  • It saves preparation time. Co-teachers can rely on each other’s strengths while creating/ revising the material as well as in unexpected situations during the lesson.

  • +
  • It helps with onboarding new instructors. One of the co-teachers can be learning at the same time, either the subtleties of the material taught (in this case literally being the “voice of the audience”) or the teaching process itself.

  • +
  • Team teaching looks more interactive and engaging to the audience in many cases, without forcing the learners to speak up if they can’t or don’t want to do so.

  • +
  • It also ensures responsive feedback and less workload by having more active minds.

  • +
+
+

Are there any downsides?

+

Not every learner and not every instructor might like the team-teaching approach.

+
    +
  • It might seem less structured, unprepared, and chaotic, even with preparation.

    +
      +
    • It might create situations where instructors accidentally talk over each other or “interrupt” and change the flow of the lesson.

    • +
    • For some instructors it can be stressful to not know in advance what questions they get asked from the co-instructor.

    • +
    • Sometimes when an unexpected question is asked that throws the other instructor off, it can add to the feeling of chaos and unpreparedness.

    • +
    +
  • +
  • It can be interactive and engaging but it can also end up awkward if the co-teachers don’t have a good synergy.

    +
      +
    • Can sound awkward: Main instructor talking all the time and at the end asking co-instructor whether everything is clear and co-instructor only saying “yes”.

    • +
    • Possibly more engaging: Co-instructor asking questions which help with the flow and a common understanding of the material.

    • +
    +
  • +
+
+
+
+

Team teaching specifics

+
    +
  • For successful team teaching, additional coordination is needed, first of all to agree on the teaching model (see below) and the person in control (the director) for the lesson or its parts.

  • +
  • It’s useful to keep track of the lecture plan. The discussion is a good way to make lesson more interactive and adjust to the audience, but deviating too much will become disorienting (for example, if someone dropped their attention for a minute and now is trying to catch-up by reading lecture notes).

  • +
  • Experienced solo teacher might have a habit to keep talking (lecturing), while the co-teacher might not want to “interrupt”. Therefore, it is important for the leading presenter to anticipate and allow for remarks/ questions, and this can be different from one’s previous teaching style at first.

  • +
+
+
+

Team teaching models

+

We propose two basic models, but of course there is a constant continuum.

+
+

Guide and demo-giver

+

One person serves the role of guide, explaining the big picture and context of the examples.

+

Another, the demo-giver,

+
    +
  • shows the typing and does the examples,

  • +
  • might take the role of a learner who is asking about what is going on, to actually explain the details, or to comment occasionally.

  • +
+

Hands-on demos and exercises work especially well like this.

+
+
+

Presenter and interviewer

+

In this case, one is the presenter who is mostly explaining (including demos or examples), and trying to move the forward through the material.

+

Another, the interviewer,

+
    +
  • serves as a learner or spotter,

  • +
  • fills in gaps by asking relevant questions,

  • +
  • tries to comment to the presenter when things are going off track.

  • +
+

This can be seen as closer to classical teaching, but with a dedicated and prepared “voice of the audience”.

+
+
+

Exercise

+
+

Discuss the models of team teaching (10 min)

+

While in breakout rooms, discuss one of the basic team-teaching models presented here:

+
    +
  • Have you already tried this or similar model in your teaching?

  • +
  • Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best?

  • +
+

Write your comments in the collaborative document.

+
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Co-teaching focuses on complementing individual skills and strengths in teaching process.

  • +
  • Co-teaching may save time, reduce teachers’ workload and make lessons more interactive/ engaging.

  • +
  • Team teaching requires some adjustments in lesson preparation and delivery.

  • +
+
+
+
+
+

Sharing teaching gems

+
+

Objectives

+
    +
  • Our goal is to share our teaching tricks and tools and demonstrate them in +very short presentations/discussions.

  • +
+
+
+

Instructor note

+
    +
  • Demonstrations: 35 min

  • +
+
+

Here we encourage participants to take the screen share for 3 minutes and +demonstrate either some tool or trick they found useful for their teaching or +something from a course you liked.

+
+
+
+
+

Session 4 intro

+

This session covers streaming and technical production. Some +introductory notes:

+
    +
  • (As of 2024) This is the first and only comprehensive introduction +to our online streaming.

  • +
  • These practices are new and well-refined internally, but a +different kind of refinement is needed to teach and reuse them.

  • +
  • The lessons have outlines of what to talk about, but it’s just an +outline. It is not refined, since thees things are new. Many +things will have to be figured out as we talk.

  • +
  • This session is a demo of lots of basics.

    +
      +
    • Ask questions - otherwise it will be boring

    • +
    • If you want to use this in real life: you will need mentoring +sessions and active help. Contact us to do that.

    • +
    +
  • +
+
+

Warning

+

Audio and video weirdness

+

We are setting up video and audio recording, but also capturing that +for re-sharing it. There may be anomalies as video or audio +feedback. Please be prepared.

+
+
+
+

Why we stream

+
+

Objectives

+
    +
  • Learn the general history of CodeRefinery streaming.

  • +
  • Discuss the benefits of streaming and recording

  • +
  • Discuss the downsides and difficulties

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 10 min

  • +
  • Q&A: 5 min

  • +
  • Exercises: 0 min

  • +
+
+

This is a general discussion of the topics of the day, focused on the +history of why we stream and record, how we got here, and how people +feel about it. We won’t focus on how anything is done.

+
+

Icebreaker questions

+
    +
  • What is the most people you have taught for?

  • +
  • What are the distinct parts of teaching, that can be +separated? (teaching, helping, etc)

  • +
+
+
+

What is streaming and recording?

+
    +
  • Streaming is mass communication: one to many

    +
      +
    • Interaction audience→presenters is more limited (but different)

    • +
    +
  • +
  • Using consumer-grade tools, normal people can reach huge audiences +by Twitch/YouTube/etc.

  • +
  • This isn’t actually that hard: people with much less training than +us do it all the time.

  • +
  • They reach huge audiences and maintain engagement for long events.

  • +
+

Recording and rapid video editing is useful even without +streaming.

+
+
+

History

+
    +
  • In-person workshops

    +
      +
    • 3 × full day, required travel, infrequent, one-shot

    • +
    +
  • +
  • Covid and remote teaching

    +
      +
    • Traditional “Zoom” teaching several times

    • +
    +
  • +
  • Mega-CodeRefinery workshop

    +
      +
    • 100-person Zoom teaching

    • +
    • Emphasis on teams

    • +
    +
  • +
  • Research Software Hour

    +
      +
    • Livestream free-form discussions on Twitch

    • +
    +
  • +
  • Streamed “HPC Kickstart” courses

  • +
+
+
+

Benefits and disadvantages

+

Benefits:

+
    +
  • Larger size gives more (but different) interaction possibility

    +
      +
    • “Notes” for async Q&A

    • +
    +
  • +
  • Recording (with no privacy risk) allows instant reviews

  • +
  • Stream-scale allows for many of the things you have learned about in +days 1-3.

  • +
+

Disadvantages:

+
    +
  • Requires training for using the tools

  • +
  • Requires a certain scale to be worth it

  • +
  • Coordination is much harder for big events

  • +
+

When would I recommend it?

+
    +
  • No: For small courses

  • +
  • Questionable: Medium sized courses with no videos

  • +
  • Yes: When you want the largest audience

  • +
  • Yes: When you want without registration required

  • +
  • Yes: When you want good reusability/fast videos

  • +
+
+
+

Future prospects (briefly)

+
    +
  • Streaming probably stays as a CodeRefinery tool

  • +
  • We can scale our courses much larger than they are now. Why don’t +we, together with others?

  • +
  • These tools are useful in other places too

    +
      +
    • I’ve used them to record my own talks to make videos of my +single-person presentations or record conference talks nicer than Zoom.

    • +
    +
  • +
+
+
+

Q&A

+

Q&A from audience

+
+

Keypoints

+
    +
  • Streaming optimizes a course for different things

  • +
  • The disadvantages can be compensated for

  • +
  • There are benefits and disadvantages

  • +
+
+
+
+
+

Behind the stream

+
+

Objectives

+
    +
  • Take a first look at the broadcaster’s view.

  • +
  • Get to know what happens “behind the stream” of a workshop

  • +
  • See what the “broadcaster” sees and what they need to do.

  • +
  • Not yet: learn details of how to do this.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Q&A 10 min

  • +
+
+

In this episode, you’ll see an end-to-end view of streaming from the +broadcaster’s point of view. It’s a tour but not an explanation or +tutorial.

+
+

Who does what

+

We have certain role definitions:

+
    +
  • Broadcaster: Our term for the person who manages the streaming.

  • +
  • Director: Person who is guiding the instructors to their +sessions, changing the scenes, calling the breaks, etc.

    +
      +
    • Could be the same as broadcaster.

    • +
    +
  • +
  • Instructor: One who is teaching. They don’t have to know +anything else about how streaming works.

  • +
+

This lesson describes what the Broadcaster/Director sees.

+
+
+

Window layouts

+

What does the broadcaster see on their screen?

+
    +
  • What are the main windows you see?

  • +
  • What do each of them do?

  • +
  • Which ones do you need to focus on?

  • +
  • How do you keep all this straight in your head?

  • +
+
+
+

CodeRefinery control panel

+
    +
  • A custom application that controls scenes

  • +
  • Based on OBS-websocket (remote control connection for OBS - we’ll +learn about this later)

  • +
  • Can also work remotely, so that you can have a remote director

  • +
+
+
+

How scenes are controlled

+

What has to be done during a course?

+
    +
  • How do you start the stream?

  • +
  • How do you change the view?

  • +
  • How do you adjust things based on what the instructors share?

  • +
  • How do you coordinate with the instructors?

  • +
  • How do you know when to change the view?

  • +
+
+
+

Getting it set up

+
    +
  • How hard was it to figure this out?

  • +
  • How hard is it to set it up for each new workshop?

  • +
+
+
+

What can go wrong

+
    +
  • What’s the worst that has happened?

  • +
  • What if you need to walk away for a bit?

  • +
  • Someone broadcasts something unexpectedly

  • +
+
+
+

Alternatives

+
    +
  • Youtube vs Twitch

  • +
  • Zoom stream directly to YouTube/Twitch

  • +
  • Direct streaming platform, e.g. streamyard

  • +
+
+
+

Q&A

+

Q&A from audience

+
+

Keypoints

+
    +
  • The broadcaster’s view shouldn’t be so scary.

  • +
  • There is a lot to manage, but each individual part isn’t that hard.

  • +
+
+
+
+
+

Video editing

+
+

Objectives

+
    +
  • Get to know ways of quick video editing to be able to provide +accessible videos

  • +
  • Learn how video editing can be distributed and done the same day.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 20 min

  • +
+
+

Video recordings could be useful for people watching later, +but also are (perhaps more) useful for immediate review and catching +up after missing a day in a workshop. For this, they need to be +released immediately, within a few hours of the workshop. +CodeRefinery does this, and you can too.

+

Hypothesis: videos must be processed the same evening as they were +recorded, otherwise (it may never happen) or (it’s too late to be +useful). To do that, we have to make processing good enough (not +perfect) and fast and the work distributeable.

+
+

Primary articles

+ +
+
+

How this relates to streaming

+
    +
  • If you stream, then the audience can not appear in the recorded +videos

  • +
  • This allows you to release videos very quickly if you have the +right tools.

  • +
  • When you have a large audience, the videos start helping more +(review a missed day, catch up later, review later)

  • +
  • Thus

    +
      +
    • If you would never want videos, there may never be a benefit to +streaming

    • +
    • If you want videos, it gives motivation to stream.

    • +
    +
  • +
+
+
+

Summary

+
    +
  • Basic principle: privacy is more important than any other factor. +If we can’t guarantee privacy, we can’t release videos at all.

    +
      +
    • Disclaimers such as “if you don’t want to appear in a recording, +leave your video off and don’t say anything”, since a) accidents +happen especially when coming back from breakout rooms. b) it +creates an incentive to not interact or participate in the course.

    • +
    +
  • +
  • Livestreaming is important here: by separating the instruction from +the audience audio/video, there is no privacy risk in the raw +recording. They could be released or shared unprocessed.

  • +
  • Our overall priorities

    +
      +
    1. No learner (or anyone not staff) video, audio, names, etc. are +present in the recordings.

    2. +
    3. Good descriptions.

    4. +
    5. Removing breaks and other dead time.

    6. +
    7. Splitting videos into useful chunks (e.g. per-episode), perhaps +equal with the next one:

    8. +
    9. Good Table of Contents information so learners can jump to the +right spots (this also helps with “good description”.)

    10. +
    +
  • +
  • ffmpeg-editlist +allows us to define an edit in a text file (crowdsourceable on +Github), and then generate videos very quickly.

  • +
+
+
+

How we do it

+

The full explanation is in the form of the exercises below. As a +summary:

+
    +
  • Record raw video (if from a stream, audience can’t possibly be in +it)

  • +
  • Run Whisper to get good-enough subtitles. Distribute to someone for +checking and improving.

  • +
  • Define the editing steps (which segments become which videos and +their descriptions) in a YAML file.

  • +
  • Run ffmpeg-editlist, which takes combines the previous three steps +into final videos.

  • +
+
+
+

Exercises

+
+

Exercise A

+

These exercises will take you through the whole sequence.

+
+

Editing-1: Get your sample video

+

Download a sample video:

+ +
+

Editing-2: Run Whisper to generate raw subtitles and test video.

+

First off, install Whisper and generate the base subtitles, based +on the. Since this is probably too much to expect for a short +lesson, they are provided for you (above), but if you want you can +try using Whisper, or generating the subtitles some other way.

+

You can start generating subtitles now, while you do the next +steps, so that they are ready by the time you are ready to apply +the editlist. ffmpeg-editlist can also slice up the subtitles from +the main video to make subtitles for each segment you cut out.

+

Whisper is left as an exercise to the reader.

+ +
+
+
+

Editing-3: Create the basic editlist.yaml file

+

Install +ffmpeg-editlist and +try to follow its instructions, to create an edit with these features:

+
    +
  • The input definition.

  • +
  • Two output sections: the “Intro to the course”, and “From data +storage to your science” talks (Remember it said the recording +started at 11:35… look at the schedule for hints on when it +might start!). This should have a start/end timestamp from the +original video.

  • +
+

A basic example:

+
- input: day1-raw.mkv
+
+# This is the output from one section.  Your result should have two of these sections.
+- output: part1.mkv
+  title: something
+  description: >-
+    some long
+    description of the
+    segment
+  editlist:
+    - start: 10:00    # start timestamp of the section, in *original* video
+    - end: 20:00      # end timestamp of the section, in the *original* video
+
+
+ +
+
+

Discussion: what makes a video easy to edit?

+
    +
  • Clear speaking and have high audio quality.

  • +
  • For subtitle generation: Separate sentences cleanly, otherwise it +gets in a “stream of words” instead of “punctuated sentences” +mode.

  • +
  • Clearly screen-sharing the place you are at, including section +name.

  • +
  • Clear transitions, “OK, now let’s move on to the next lesson, +LESSON-NAME. Going back to the main page, we see it here.”

  • +
  • Clearly indicate where the transitions are

  • +
  • Hover mouse cursor over the area you are currently talking about.

  • +
  • Scroll screen when you move on to a new topic.

  • +
  • Accurate course webpage and sticking to the schedule

  • +
+

All of these are also good for learners. By editing videos, you +become an advocate for good teaching overall.

+
+
+

Editing-4: Run ffmpeg-editlist

+

Install ffmpeg-editlist: pip install ffmpeg-editlist[srt] (you +may want to use a virtual environment, but these are very minimal +dependencies).

+

The ffmpeg command line tool must be available in your +PATH.

+ +
+
+

Editing-5: Add more features

+
    +
  • Several chapter definitions.(re-run and you should see a +.info.txt file also generated). Video chapter definitions +are timestamps of the original video, that get translated to +timestamps of the output video.

    +
    - output: part1.mkv
    +  editlist:
    +  - start: 10:00
    +  - -: Introduction    #  <-- New, `-` means "at start time"
    +  - 10:45: Part 1      #  <-- New
    +  - 15:00: Part 2      #  <-- New
    +  - end: 20:00
    +
    +
    +

    Look at the .info.txt files that come out now. What is new in it?

    +
  • +
  • Add in “workshop title”, “workshop description”, and see the +.info.txt files that come out now. This is ready for +copy-pasting into a YouTube description (first line is the title, +rest is the description).

    +

    Look at the new .info.txt files. What is new?

    +
  • +
+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+
+
+

Editing-7: Generate the final output file.

+
    +
  • Run ffmpeg-editlist with the --reencode option: this +re-encodes the video and makes sure that there is no black point +at the start.

  • +
  • If you re-run with --check, it won’t output a new video file, +but it will re-output the .info.txt and .srt files. +This is useful when you adjust descriptions or chapters.

  • +
+
+
+

Discussion: how to distribute this?

+

Create a flowchat of all the parts that need to be done, and which +parts can be done in parallel. Don’t forget things that you might +need to do before the workshop starts.

+

How hard was this editing? Was it worth it?

+
+
+
+

Exercise B

+

This is a more limited (and older) version of the above exercise, +using an synthetic example video.

+
+

Use ffmpeg-editlist to edit this sample video

+

Prerequisites: ffmpeg must be installed on your computer +outside of Python. Be able to install ffmpeg-editlist. This is +simple in a Python virtual environment, but if not the only +dependency is PyYAML.

+ + +
+
+
+
+

See also

+ +
+

Keypoints

+
    +
  • Video editing is very useful for learning

  • +
  • Set your time budget and make it good enough in that time

  • +
  • Reviewing videos improves your teaching, too.

  • +
+
+
+
+
+

Open Broadcaster Software (OBS) introduction

+
+

Objectives

+
    +
  • Understand that OBS is a video mixer.

  • +
  • Understand the basic controls and features of OBS.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 15 min

  • +
  • Q&A 5 min

  • +
+
+ +

In this episode, you’ll get more familiar with the OBS portion of the +streaming setup. You’ll see how it’s used, but not yet how to +configure it from scratch. You’ll learn how to be a “director”.

+
+

What is OBS?

+
    +
  • Formally “OBS Studio”

  • +
  • Most commonly known as a livestreaming application.

  • +
  • Open source, free.

  • +
  • Cross-platform, easy to use screencasting and streaming application.

  • +
  • Real-time video mixer.

  • +
+
+
+

OBS user interface

+
    +
  • We’ll click through each view.

  • +
  • What does each view do?

  • +
  • Let’s click through the buttons.

  • +
  • Let’s see the important config options.

  • +
+
+
+

OBS during a course

+
    +
  • What management is needed.

  • +
  • The control panel.

  • +
  • Audio.

  • +
  • Adjusting windows and so on.

  • +
+
+
+

Hardware requirements

+
    +
  • Reasonably powerful broadcast computer

    +
      +
    • CodeRefinerys streaming computer is 8 CPU AMD, 64GB memory

    • +
    • That is way overkill: a powerful laptop can probably do this.

    • +
    +
  • +
  • Large second monitor for laying out the windows you capture

  • +
  • Stable internet connection (wired preferable)

    +
      +
    • CodeRefinery’s broadcast is the slowest purchasable: 100 Mbit down / +25Mbit up

    • +
    +
  • +
+
+
+

Q&A

+

We’ll answer audience questions.

+
+
+

See also

+ +
+

Keypoints

+
    +
  • OBS may seem complicated, but it’s a graphical application and most +pieces make sense once you know how it works.

  • +
+
+
+
+
+

Open Broadcaster Software (OBS) setup

+
+

Objectives

+
    +
  • See how to configure OBS using the pre-made CodeRefinery scene +collections

  • +
  • Modify the collections to suit your needs.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: ?? min

  • +
  • Hands-on: ?? min

  • +
  • Q&A: ?? min

  • +
+
+ +

In this lesson, we’ll see how to configure OBS from scratch for your +purposes. We’ll do this by deleting the instructor’s configuration +and trying to recreate it

+

This section is short, since it has never been done before: we’ll just +give it a short and update the lesson later.

+
+

CodeRefinery OBS configs

+
    +
  • CodeRefinery configs are shared in a repository: +https://github.com/coderefinery/obs-config

  • +
  • These can be imported to pre-configure some things

  • +
  • There are two types of configs:

    +
      +
    • Profiles

      +
        +
      • Servers, resolutions, audio, video, etc.

      • +
      +
    • +
    • Scene collections

      +
        +
      • The graphical layouts.

      • +
      +
    • +
    +
  • +
+
+
+

Installing the OBS config

+
    +
  • Clone the git repository.

  • +
  • Import the profile and scene collections under their respective +menus.

  • +
+
+
+

Initial setup

+
    +
  • Click through each menu and change anything that is needed

  • +
  • Set the streaming server

  • +
+
+

The instructor will go through the setup.

+
    +
  • Reset configuration: mv .config/obs-studio/ .config/obs-studio-old/

  • +
  • Import profiles/TeachingStreamingv3/

  • +
  • Import scenes/TeachingStreamingZoomv3.json

  • +
+
+
+
+

Set up the remote control

+
    +
  • Create a Python environment and install it: pip install https://github.com/coderefinery/obs-cr/archive/refs/heads/master.zip

  • +
  • Run it: python obs_cr/control.py localhost:4445 TOKEN --broadcaster

  • +
  • There are more options but let’s not cover them yet… and leave +this for a hands-on session.

  • +
+
+
+

Setup before each course

+
    +
  • Re-confirm audio

  • +
  • Re-confirm each scene

  • +
  • Test everything

  • +
  • rkdarst has a rather long +checklist, +but each individual step is short.

  • +
+
+
+

Q&A

+

We’ll answer audience questions.

+
+

Keypoints

+
    +
  • Most of our configuration has been OBS may seem complicated, but it’s a graphical application and most +pieces make sense once you know how it works.

  • +
+
+
+
+
+

What’s next?

+
+

Objectives

+
    +
  • Know next steps if you want to do streaming

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 5 min

  • +
  • Q&A 5 min

  • +
+
+

What comes next?

+
    +
  • We talked a lot about theory, and gave demonstrations.

  • +
  • Hands-on is very different. We recommend working with someone to +put it in practice.

  • +
  • +
+
    +
  • Work with someone who can show you the way

  • +
  • Use it for smaller courses with a backup plan

  • +
+
+

See also

+
+

Keypoints

+
    +
  • These lessons about streaming have been the theoretical part of +streaming training.

  • +
+
+
+
+
+
+
+

Collaborative notes archives from workshops

+
+

August/September 2024

+
+

Day1: Session 1 (13.08.24) - About lesson design, deployment and iterative improvement

+
+
:calendar: Schedule
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 10.00

Lesson design and development

10.15 - 11.00

8.15 - 9.00

10.00 - 10.15

Break

11.00 - 11.15

9.00 - 9.15

10.15 - 11.00

Lessons with version control

11.15 - 12.00

9.15 - 10.00

11.00 - 11.15

Break

12.00 - 12.15

10.00 - 10.15

11.15 - 12.00

How we collect feedback and measure impact

12.15 - 13.00

10.15 - 11.00

+
+
+
:icecream: Icebreaker
+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :Decaffed … and going strong …

  • +
  • :coffee: 🤔

  • +
  • :100: (ironically!) :coffee: intake happening

  • +
  • :smile:

  • +
  • :tired_face:

  • +
  • :coffee: :party:

  • +
  • :coffee: :happy:

  • +
  • 😪

  • +
  • just got zoom installed / before my coffee

  • +
  • :smil-

  • +
  • :sweat_smile: (+)

  • +
  • :yawning_face:

  • +
  • :is it morning already?

  • +
  • :smile:

  • +
  • :yawning_face:

  • +
  • :nerded_face:

  • +
  • 🥵

  • +
  • :smile:

  • +
  • :sleeping:

  • +
  • :sleepy: :coffee: :smiley_cat:

  • +
  • 🥳

  • +
  • :coffee:

  • +
  • :coffee:

  • +
+
+
+
Introduction in breakoutrooms.
+
    +
  • Name / Affiliation / Location

  • +
+
+
+
About teaching
+

What is the hardest thing about teaching for you?

+
    +
  • Knowing how “it’s going”, whether learners are happy or not (especially when teaching online) :+1:

  • +
  • The preparation the night before. It is always much more that I would hope, no matter how prepared I want it to be :+1: :+1:

  • +
  • Managing groups with vastly different academic backgrounds

  • +
  • Teaching wide spectrum of skill level at the same time. :+1: :+1: :+1: :+1:

  • +
  • Time management! (Knowing how much can fit in a sessions) :+1: :+1:

  • +
  • General preparation time, how to fit it into the regular work schedule, and estimate how much time is needed for prep.

  • +
  • How to reduce too much text into just the right amount

  • +
  • Preparation of the session material and estimating the right amount of time for each section

  • +
  • Getting learners to take the first step: sign up for and attend a workshop, when they don’t think programming is a skill they can learn

  • +
  • Getting learners to take the second step: translating what they’ve learned in a workshop into something they can apply

  • +
  • preparation and time management

  • +
  • Engaging with the students which was much easier for me when I used to coach

  • +
  • Finding the right depth for an unknown audience for “my topic”

  • +
  • education background of participants and their learning objectives

  • +
+

What is the best thing about teaching for you?

+
    +
  • Seeing when learner gets interested/curious about something and takes inspiration from the course. :+1:

  • +
  • Seeing it works and someone can do something new.

  • +
  • Motivated students grasping new stuff

  • +
  • Students picking up and running with the matertial and skills I give them and using it for their own work. :+1:

  • +
  • The “ah-ha!” moment when a student gets it! :+1::100: :+1:

  • +
  • Learning from students who know about some topic more than you do. :+1:

  • +
  • Being able to help people reach their goals, by showing them something new.

  • +
  • Teaching is optimism acted out in the hope of making a difference both ways I suppose.

  • +
  • The feeling of accomplishment when you see learning grow and implement the learnings :book:

  • +
  • mutual learning and impact on learners :+1:

  • +
  • Results and feedbacks / Mutual interests and interesting discussions

  • +
  • mutual learning and I can also learn lots of things and new ideas from participants

  • +
+
+
+
+
:question: Questions
+
+
General / Practicalities
+
    +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms? I’m not in a place where I can talk, so if we’re going to talk a lot I’ll need to move offices

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    +
  • +
  • +
+
+
+
Episode 1: Lesson design and development
+

Materials: https://coderefinery.github.io/train-the-trainer/lesson-development/ +Discussion:

+
    +
  • When you start preparing a new lesson or training material, where do you start?

    +
      +
    • I look at existing materials on the same topic, but chose/refine topics based on the perceived needs/interests of the presumed audience

    • +
    • Outline of structure and Material collection for a new lesson :+1:

    • +
    • What material I have already? (what other material is already out there?)

    • +
    • Start by looking for related resources (documents, videos, courses, etc) to have a base data and better understanding of what have been done around the topic

    • +
    • Know your audience

    • +
    • Review existing material

    • +
    • Think about learning objectives (to keep focus on essential things)

    • +
    • Think of three things simple enough that they will be remembered the next day. Design around that.

    • +
    • I write down the thoughts that I have and then go back and structure it.

    • +
    +
  • +
  • What tricks help you with “writer’s block” or the empty page problem?

    +
      +
    • Write anything down that comes to mind, sometimes draw something, looking out the window :)

    • +
    • Do a mind map - what concepts do I want to get across?

    • +
    • Starting small, for example a list of headings and then building around it. :+1:

    • +
    • What does one know about the target audience and why should they be spending longer than 1 minute listening to what they will eventually get to hear?

    • +
    • Get some inspiration from another source.

    • +
    • Start with the three things above

    • +
    • Start with the plan and the overview design

    • +
    • Some kind of outline / main message(s)

    • +
    • Start with three things. Three supporting points for each of these.

    • +
    +
  • +
  • Maybe you haven’t designed training material yet. But how do you start when creating a new presentation?

    +
      +
    • Think about the learning objectives and try to break them down into steps

    • +
    • Title, Objectives, target audience and Plan

    • +
    • Some kind of outline / main message(s). Get as many images as I can, instead of words

    • +
    • Draft an outline and use chatgpt to fill in details

    • +
    • Example of how the teaching content is applied in a real-world context

    • +
    +
  • +
  • If your design process has changed over time, please describe what you used to do and what you do now instead.

    +
      +
    • I look more at existing materials and try to get more information about the audience. Unfortunately getting information about the audience before the event is hard

    • +
    • I used to start from the begginning and get from there but that often meant a very polished start and a rushed end. Now I try an overview first, then fil out sparsed details at every section

    • +
    • Updating the data and tweak the presentation

    • +
    • If I am teaching a small group (or one to one) talk to them before hand - find out what they know already, what they want to learn.

    • +
    +
  • +
  • What do you know now about preparing lessons/training/presentations that you wish you knew earlier?

    +
      +
    • less is more. It’s better to have 2-3 main messages rather than trying to show everything in one go :+1: :+1: :+1: :+1:

    • +
    • how much practice time the learners need to master what’s taught

    • +
    • Don’t worry about something going wrong. It often makes the lesson (and thus the material) more presistent in memory. :+1:

    • +
    • Try and remove everything except what you want the person to learn

      +
        +
      • That’s a very tough part for me in the sense that I never know how much of an underlying “black box” is still ok….

      • +
      +
    • +
    • Designing intermediate materials is hard, and requires putting some “gatekeeping” making sure that learners are directed to appropriate courses

    • +
    • When I see a cool graphic, concept, slide, etc., download it and save it in my ‘new-materials’ folder to use later on!

    • +
    • I have come to the conclusion that perhaps a more “agile” approach to developing materials (try to do design/teaching iterations quickly) might be the best way to go, but there are risks with this approach too

    • +
    +
  • +
+

Questions

+
    +
  • From zoom chat: Can you expand on what a learner persona is?

    +
      +
    • A defined example person described in terms of the materials you are preparing, making up a story about the background and interest of t

    • +
    • Answer from chat: A learner persona is a blackbox which has a very simple algorithm inside: GIGO.

    • +
    • Answer from chat: I think it’s the same as ICP (Ideal customer persona) where you describe the learner as a customer

    • +
    • Answer from chat: I’m a big fan of “How Learning Works” by Ambrose et al https://bookshop.org/p/books/how-learning-works-eight-research-based-principles-for-smart-teaching-michele-dipietro/18640868?ean=9781119861690

    • +
    • See also book: Teaching tech together

    • +
    +
  • +
+
+

CodeRefinery lessons: https://coderefinery.org/lessons/

+
+
    +
  • From chat: Do you have an example of an instructor guide?

    + +
  • +
  • From zoom chat: Do you have a “measure” of how better are the new lesson compared to the old ones? Does it make sense to talk about measurements here?

    +
      +
    • So far we only have daily feedback that we collect at the end of the day and we can compare that to earlier daily feedbacks. More about that in the last episode of today. But measuring this is indeed not easy and it also takes time to capture the effect during longer-term surveys. Some of the changes were more leap-of-faith than based on data.

    • +
    • I guess that sometimes one can use “compelling arguments” instead of data to justify a decision

    • +
    +
  • +
  • Software Carpentry does teach using the command line, and gives a session on the command line before. What do you think about this approach? Are you stating that a 3-hour lesson about CLI is not sufficient to make people comfortable enough to use that for version control?

    +
      +
    • Yes, good question. For CR we consider it a more advanced step: we do think people should learn command line, but it’s for a different course. We accept some people might not know it or want to know it so adapt to that.

    • +
    • In general, we’ve found the “you need X, but have to learn A, B, and C first” approach should be avoided if possible: people are busy, try to reach people where they are.

    • +
    +
  • +
+
+

Exercise in breakoutrooms

+
+
    +
  • Room 1

    +
      +
    • Research data management

    • +
    • Objectives

      +
        +
      • Research life cycle

      • +
      • FAIR principles (Findable, Accessible, Interoperable, Reusable)

      • +
      +
    • +
    • Exercise

      +
        +
      • develop a data management plan (DMP) that outlines how their research data will be handled throughout its lifecycle.

      • +
      +
    • +
    +
  • +
  • Room 2: What is the difference between eating breakfast and sitting through a lecture? (Tip: Start by listing the similarities …)

  • +
  • Room2 : Making papers in LaTeX +- What is LaTex and how is it different from editors like Word +- Basic Structures +- How to find and use a template +- Including figure & table +- How to use references and labels +- Exercise: to create a new LaTeX document & edit it +- Excercise: common error messages: can you find the error in this code? +- Exce

  • +
  • Room 3

    +
      +
    • GPU Programming (1 hour intro)

    • +
    • Learning objectives:

      +
        +
      • What is GPU programming.

      • +
      • When is it usable, beneficial to use GPU programming?

      • +
      • What are technologies to do GPU programming?

      • +
      • [What are and how to manage typical issues]

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • Git / Figures / Project management / data cleaning

    • +
    • Chose data cleaning

    • +
    • Three learning objectives:

      +
        +
      1. What do we mean by “clean”? How to identify it?

      2. +
      3. Identify some common problems in a dataset

      4. +
      5. Identifying and handling missing values/fields

      6. +
      +
    • +
    • Exercise

      +
        +
      1. Discuss problems, find the most common ones

        +
          +
        • In small groups

        • +
        • What problems have you run into with datasets you’ve worked with?

        • +
        • What problems can you imagine, or have you heard about from colleagues/news/social media?

        • +
        • Report back, instructor collects all problems into a list

        • +
        +
      2. +
      3. Have a dataset to clean; a clean and a messy example

        +
          +
        • (identifying) Using a visualisation or overviewing tool?

        • +
        +
      4. +
      +
    • +
    +
  • +
  • Room 5

    +
      +
    • Jupyter Notebooks

    • +
    • Learning Objectives

      +
        +
      • Can setup an enviroment you can reuse / can share with others / a project.

      • +
      • The order you run the commands in needs to match the order of the code in the Notebook - otherwise you end up in a pickle.

      • +
      • Why use a Jupyter Notebook? What are the advantages? Easy to use environment.

      • +
      +
    • +
    • Exercise

      +
        +
      • Print variable assignments from different cells - show that the order you run the code is important.

      • +
      • hand out a domain specific notebook that does some calculations and visualization to run and modify, to show that you can share easily

      • +
      • show !pip install to add dependencies/features

      • +
      +
    • +
    +
  • +
  • Room 6

    +
      +
    • Using GitHub without the command line

    • +
    • Learning Outcomes:

      +
        +
      • Be able to discuss changes before merging changes into the main repository.

      • +
      • Publish a personal repository page ( I think its called intro repository)

      • +
      • Share their script/notebook/code/small data on GitHub

      • +
      • Homepage using GitHub pages or the README that becomes the “index page” of the GitHub user account page

      • +
      +
    • +
    • Learner personas:

      +
        +
      • Check the Personas of the learners

        +
          +
        • Somebody who has seen/heard of GitHub but hasn’t used it yet

        • +
        • Someone using it for their own work but struggling with collaboration

        • +
        +
      • +
      +
    • +
    • Exercises:

      +
        +
      • Upload/share an example dataset or script

      • +
      • Review another collaborators pull request.

      • +
      • Take part in the discussion on a pull request.

      • +
      +
    • +
    +
  • +
  • Room 7 +Linux shell basics: why do we want to teach them? +(this took most of the time for the discussion)

    +
      +
    • Learning objectives:

      +
        +
      1. Filesystem: Directory (CLI) - Folder (GUI) analogy

      2. +
      3. Basic commands (which commands are basic? make a survey of shell histories and get the most common ones)

      4. +
      5. Basic constructs (e.g., for loops, pipes, while loops… which ones are basic? See above)

      6. +
      +
    • +
    +
  • +
+
+

Note from chat: Zoom timer: https://support.zoom.com/hc/en/article?id=zm_kb&sysparm_article=KB0068677

+
+
+
+
Episode 2: Lessons with version control
+

Materials: https://coderefinery.github.io/train-the-trainer/lessons-with-git/

+

Poll options: I want to hear about:

+
    +
  • A: Why use version control for teaching materials

  • +
  • B: Different template options

  • +
  • C: How CodeRefinery does it; CodeRefinerys lesson template

  • +
+

Poll vote (multi-select): add a o to your answer +- A: ooo +- B: oooooo +- C: oooooooo :ghost:

+

Question to audience: if someone wants to make a tiny fix to your material, how hard is it?

+
    +
  • If my material is only in pdf format which is not online, then it is hard.

  • +
  • I hope it is easy - my material is in GitHub. Nobody has ever done that though!

  • +
  • Slides: hard to find, easy to edit; Git repos somewhat easy, unless they have to be built locally or with an action; HackMD easiest to edit.

    +
      +
    • if you use something like google slides they are not that difficult to find

    • +
    • known permanent address. Google docs et al fail on that/same for many pads.

    • +
    +
  • +
  • For this material today - very easy! e.g. https://github.com/coderefinery/train-the-trainer/pull/128

  • +
  • Template with an edit button in the HTML pointing to the source-code in the repo.

  • +
+

Questions/Discussion topics

+
+

Upcoming CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/ +Please share with your networks, and let us know if you would like to co-teach a lesson (to support@coderefinery.org or in our Zulip chat)

+
+
    +
  • Changes to the material are sometimes not just tiny fixes. For example, one wants to present a slightly different selection of topics, but maybe some topics are “coupled” (perhaps naturally or perhaps just because of how they are presented), or change the general “theme” (e.g., life sciences vs theoretical physics) while keeping the actual topics the same. How could a lesson be developed to avoid having to do a huge rewrite?

    +
      +
    • You can try to modularize your material and keep non topic specific parts non themed. E.g. where you explain the functionality, don’t make reference to the example (not simple), so the example can be changed depending on the audience.

    • +
    +
  • +
  • What are the pros/cons of renaming a course / changing a repo name in GitHub?

    +
      +
    • It should be relatively unproblematic since GitHub will forward to the new name.

      +
        +
      • How long does Github keep the “old” name linked? Is there a max time it’s blocked, or changed as soon as a new one appears with the name?

        +
          +
        • in my experience it forwards “forever” until I create a new repo with the old name which will break the forward

        • +
        +
      • +
      +
    • +
    +
  • +
  • what should be in the readme for the git repo? (canonical address? contact points? license!)

    +
      +
    • https://coderefinery.github.io/mini-workshop/2/documentation/#often-a-readme-is-enough-checklist

      +
        +
      • I miss the url to the (main) repo in the readme

        +
          +
        • Do you mean the link to the rendered (lesson) page?

        • +
        +
      • +
      +
    • +
    • Link to rendered page: We often have this in the “about” section of the readme (see up right: https://github.com/coderefinery/train-the-trainer)

    • +
    • this gets lost in a fork, doesn’t it? so 20 folks forking and or reuploading the repo somewhere means the url gets lost?

      +
        +
      • True, but they might want to have their own version rendered?

        +
          +
        • yes, I have had issues finding and contributing to the “master” repo so all benefit. Else it gets cluttered. Both is valid

          +
            +
          • Good point though, the link to rendered page should probably also be included in the readme for completeness; ah and the link to the repository too, yes

            +
              +
            • so realistically we need a content folder and some more next to the readme as a best practice. sounds good!

            • +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • Is myst (markdown renderer) enabled by default in sphinx now?

    +
      +
    • to my knowledge no. we add the “myst_parser” extension to conf.py.

    • +
    +
  • +
+
+

Cicero: https://cicero.readthedocs.io/ +Sphinx documentation: https://www.sphinx-doc.org/en/master/ +Carpentries workbench for creating Carpentries lessons: https://carpentries.github.io/workbench/ +This is the testing lesson Richard showed: https://coderefinery.github.io/testing/ +And the corresponding repository: https://github.com/coderefinery/testing +You can lean back and watch, exercise coming in a bit :) +Richard will now edit our train the trainer material repository: https://github.com/coderefinery/train-the-trainer +The Sphinx extension for CodeRefinery lessons: https://github.com/coderefinery/sphinx-lesson +Empty lesson template to build your own lesson: https://github.com/coderefinery/sphinx-lesson-template

+
+

More questions

+
    +
  • Does the coderefinery.org page built on sphinx?

    +
      +
    • It’s built also from markdown but it uses https://www.getzola.org/ (which is more optimized to render websites, but we could do teaching also with Zola or create the project page using Sphinx)

    • +
    +
  • +
  • Is there a way to build and preview CR lessons without the command line?

    +
      +
    • The GitHub workflow we use creates HTML from all branches. This means that one can push a branch to GitHub, preview it there, and then open a pull request. One thing that would be nice but we don’t have yet is if a bot automatically posts the link to the preview to a pull request.

    • +
    +
  • +
  • For VCS-2, for the Carpentries Linux shell example, Lesson, Github repo, to me it seemed as though the Sandpaper setup they have makes a very nice interface, complicates the relationship between source and output. E.g on the soucre page https://github.com/swcarpentry/shell-novice/blob/main/index.md I could only see to ‘Prerequisits’ and not ‘Download files’ on the page https://swcarpentry.github.io/shell-novice/. Perhaps I have missed something?

    +
      +
    • I am sorry I don’t know the new Sandpaper setup well enough to answer this question.

    • +
    +
  • +
  • Do we have the instructions to build the lessons available somewhere to try out later?

    +
      +
    • https://github.com/coderefinery/sphinx-lesson

    • +
    +
  • +
+
+

Exercise VCS-1 (and VCS-2 (if time)) (https://coderefinery.github.io/train-the-trainer/lessons-with-git/#exercises) in breakoutrooms until xx:05

+

then short summary in main room and then break.

+

Use the notes below. Collect a list of lesson formats and discuss what you like about each of them.

+
+
    +
  • PDF slides by a presentation program

  • +
  • pdf slides with beamer in latex under source control.

  • +
  • Markdown slides via Github

  • +
  • CodeRefinery template

  • +
  • Carpentries template

  • +
  • Google Slides

  • +
  • git-book

  • +
  • Jupyter Book - allows creating a structured reference website using RST/Markdown, including Jupyter Notebooks to show result of running code

  • +
  • mdbook - create simple/minimal website using Markdown

  • +
  • Binder - allows learners to run their own live version of a github repository with Jupyter Notebooks, with only a web browser

  • +
  • Jupyter notebooks and jupyterhub platform

  • +
  • Jupyter + Nbviewer and custom css (read only) + Binder link (hands on)

  • +
  • RMarkdown

  • +
  • Quarto Slides

  • +
  • Reveal.js - write slides in HTML (also supports markdown)

    +
      +
    • Example: https://bl-presentations.erambler.co.uk/2024-02-21-idcc24/

    • +
    +
  • +
  • Remark.js - write slides in markdown

    +
      +
    • Example: https://bl-presentations.erambler.co.uk/2024-02-19-idcc-pids-workshop/

    • +
    +
  • +
+

Room discussions:

+
    +
  • Room 1

    +
      +
    • (https://smc-aau-cph.github.io/SPIS/README.html)

    • +
    • CodeRefinery template

    • +
    • Shared notes & blogs

    • +
    +
  • +
  • Room 2

    +
      +
    • demo the exercise

    • +
    +
  • +
  • Room 3

    +
      +
    • Mix of JupyterLab, Terminal within that, and traditional slides

    • +
    • Jupyter + RISE (benefit: slides that are editable and executable live)

    • +
    • Challenges

      +
        +
      • present code in an interactive way

      • +
      • handle lots of images/ figures without too much additional overhead when setting up the material

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • Material and tools depend on instructors

    • +
    • Some slide building tools

      +
        +
      • https://revealjs.com/

      • +
      • https://remarkjs.com/

      • +
      • https://github.com/rust-lang/mdBook

      • +
      +
    • +
    • Using flat git repos without fancy styling to make it easier to edit but still version controlled

    • +
    +
  • +
  • Room 5

    +
      +
    • Using R as a GIS: https://github.com/nickbearman/intro-r-spatial-analysis

      +
        +
      • Workbook: RMarkdown, Slides: Quarto

      • +
      • No continuous intergration

      • +
      +
    • +
    • Having a jupyter nbinder link to test the notebook

    • +
    • repo lives on codeberg in this example

    • +
    +
  • +
  • Room 7

    +
      +
    • Ex 1:

      +
        +
      • Sphinx, similar to CR

      • +
      • Sometimes pdfs generated with beamer package (or from pptx and odt), but blows up repository size if in version control

      • +
      +
    • +
    • Ex 2:

      +
        +
      • Content

        +
          +
        • CR: Content commonly found int the content folder

        • +
        • SC: Mostly under episodes

        • +
        +
      • +
      +
    • +
    • Question that came up:

      +
        +
      • is CR/Sphinx approach mostly for technical topics? What about language.

      • +
      • I guess by our nature it’s focused there. But probably could be used for others (I guess it it’s much easier to use git in a technical audience.)

      • +
      +
    • +
    +
  • +
+
+
+
Episode 3: How we collect feedback and measure impact
+

Materials: https://coderefinery.github.io/train-the-trainer/feedback-and-impact/

+

Questions to audience

+
    +
  • What tricks/techniques have you tried in your teaching or seen in someone else’s teaching that you think have been particularly effective in collecting feedback from learners?

    +
      +
    • preparing a survey and emailing it to participants as soon as the event ends (usually get <50% of answers but it’s a representative enough sample)

    • +
    • do engage with the audience, give them the time to get the courage to speak up

    • +
    • Be the audience yourself

      +
        +
      • yes! some problems/issues I don’t notice as instructor, only as listener

      • +
      +
    • +
    • Have time (e.g. 5 min) in the session to fill out the feedback form

    • +
    • If the course/workshop has several days/sections do a couple questions every change, then a full one afterwards

    • +
    • “Traffic light” feedback (e.g. for pacing or progress on exercises): give each learner two different coloured post-it notes for in-person, or use emoji for online, to indicate a current status

    • +
    +
  • +
  • Can you give tips or share your experiences about how to convert feedback into changes or actionable items?

    +
      +
    • ask questions about things you know you don’t know

    • +
    • “Don’t let the noise of others’ opinions drown out your own inner voice.” — Steve Jobs

    • +
    +
  • +
  • When people ask questions / get stuck with a specific step. Is there a typo I can change there and then in the workbook?

    +
      +
    • Being able to fix small things on the fly helps sometimes, otherwise open issues if working on github

    • +
    • If multiple people have the same question, then this is an indication that I should look at this in more detail

    • +
    +
  • +
  • How do you measure the impact of your teaching? Any tips or experiences about what you have tried or seen other courses do?

    +
      +
    • “How likely are you to recommend this workshop to others? (0/5)”

    • +
    • Check the ‘Garbage Out’ bin, what you find there will be what went across. The rest will be history…

    • +
    +
  • +
  • Anybody knows of good resources on survey design? Please link them here.

    +
      +
    • “Our job is to figure out what they’re going to want before they do… Our task is to read things that are not yet on the page.” - Steve Jobs

    • +
    +
  • +
+

Questions/Discussion points

+
    +
  • Feedback is necessary to design good lessons. Improvement can only be done iteratively. So the faster the iteration (design/teach), the better. But on the other hand, I cannot constantly bomb our community with training event emails. So I would like to try proposing a course many times a year, but I don’t want to spam everybody many times a year.

    +
      +
    • :+1:

    • +
    • With CR we also have a calendar that can be imported to different calendar applications, where we add all workshops: https://github.com/coderefinery/calendar/

    • +
    +
  • +
  • Does an even split of too fast / too slow mean speed is about right?!

    +
      +
    • I take it to mean “it’s roughly where it should be”. Would be better to accomdate the sides better though… (we do try to design for a broad audience: some easy stuff, some advanced stuff, so people can make their own path)

    • +
    • It could also indicate that the prerequisites/scope are not well defined :+1:

      +
        +
      • Based on long term surveys we also know though that even though the workshop might have been to fast, people appreciate having “heard things before and know where to find them later”

      • +
      +
    • +
    • perhaps the even split between too fast/too slow is ok only if the majority of votes goes for “just right” :+1:

    • +
    +
  • +
  • One of the most important disciplines in journalism is to challenge your working premises. (Bill Keller) This applies equally to learning as well.

    +
      +
    • Participants can be encouraged to write some posts on LinkedIn. If it is helpful some blurbs can be created for pre and post-workshop to generate more traction for Code Refinery and future participation.

    • +
    • Ask participants if they use Dev.to, hashnode etc to blog their work or use twitter etc to have a memory of their work.

    • +
    +
  • +
  • Do you have any suggestions for prerequisites? I try to make them clear, but occasionally people attend who clearly do not meet them. :+1:

    +
      +
    • I guess it depends how much it matters for the workshop itself. If you have group exercises etc, it probably matters? , lecture style maybe not so much?; important is that the participants themselves know that prerequisites exist and if they meet them

    • +
    • Sometimese people that do not meet the prerequisites join to get to “know what they don’t know”, find out where to find information on topics they might get interested in future etc

    • +
    • Other suggestions? Viewpoints? :)

    • +
    • Thank you - things for me to think about there :-)

    • +
    • With CR’s latest ideas, we try to make the prerequisites clear, but there is no capicity limit: it’s OK if people drop by and are less than prepared: it’s livestream, anyone can come. We try to have something for these people, too: learn what you are missing, why you might want to study more in the future.

    • +
    • Any thoughts on applying this to a more practical focused course, with a total capacity limit (i.e. not like CodeRefinery).

    • +
    +
  • +
  • Everytime you do a course on CodeRefinery, think of it as trying to bake a new cake with an old recipe with no idea about the individual taste preferences of the one you bake the cake for. Then, you will not experience too many surprises. Fine-tuning the recipe for one cohort still remains the ‘old recipe’ as far as the next ‘new cohort’ will be concerned. C’est la vie.

    +
      +
    • nice analogy!

    • +
    +
  • +
  • Question from chat: For examples 2 & 4, would you also consider using something like a Likert scale? E.g. Rate how well you agree with the statement “My code is more reusable as a result of attending a CodeRefinery workshop” (from 1 Strongly disagree to 5 Strongly agree)

    +
      +
    • Thanks! I am new to Likert scale and will read up on it. In my experience numbered answers can be useful for reporting. But I also like questions where we ask for what actually to change.

    • +
    +
  • +
  • Comment from chat: Richard, your point crowns the point of having CodeRefinery, With Radovan’s and Samantha’s acquiescence assured, I would like to suggest you wear a crown going forward, especially for the CodeRefinery session. Do we have a deal ?

    +
      +
    • I don’t quite understand this

    • +
    • I think it’s a tongue-in-cheek-comment (joke) but I am not sure…..

    • +
    +
  • +
  • What is the ideal way to allow people to interact while course is going on in the main online session, i.e. without a breakout room? Taking a pause or discussion in the background?

    +
      +
    • I’ve had some success with WhatsApp groups for a course - particually ones that run over 4 (or 2) sessions.

    • +
    • A quick survey/quiz

    • +
    • Question to the audience that we take time to answer but it helps to show the answers

    • +
    +
  • +
+
+
+
+
+
+

Wrapup

+
    +
  • Thank you for active participation :)

    +
      +
    • We’ll continue answering questions after the workshop and make the cleaned up (no names etc) available from the materials

    • +
    +
  • +
  • Next session Tuesday August 20, 9 CEST: Tools and techniques adopted in CodeRefinery workshops

    +
      +
    • we will talk about on-boarding, install help, roles, screensharing, sound, collaborative notes

    • +
    +
  • +
  • All workshop materials will stay available (after the full workshop also on Zenodo :tools:)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • If you want to co-teach with us in the upcoming (or next) CodeRefinery workshop (https://coderefinery.github.io/2024-09-10-workshop/); or just want to learn more about this opportunity: Send your name and e-mail address to support@coderefinery.org; we will contact you!

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • Lesson design approach

  • +
  • I liked the backwards lesson design, gives a name to a practice I’ve already been doing :+1: :+1:

  • +
  • Lessons from code refinery on lesson design. Learning about Sphinx.

  • +
  • Collaborative notes and anonymized archive of notes.

  • +
  • it’s nice to have a community to discuss these kinds of problems

  • +
  • Hearing the variety of tools people use for slides (PDF, Quarto, Beamer etc.)

  • +
  • Good intro of the tools, the jargon and the pedagogical philosophy of teaching tech.

  • +
  • The absolute openess in having everything publicly available - materials ofc but also questions, discussions, feedback, …

  • +
  • Thinking about all content being available publicly and as a git repo

  • +
  • Thanks for explaining the HedgeDoc interface, with view and edit options

    +
      +
    • Is there anyway to come back to this document later (e.g. tomorrow) and see what has changed since now? So I can see if any other questions have been asked/answered?

      +
        +
      • There is a “revision” point under “Menu” up right, which shows you different versions of this document

      • +
      +
    • +
    +
  • +
  • Modesty: the gentle art of enhancing your charm by pretending not to be aware of it. - Oliver Herford

  • +
  • +
+

What one thing would you improve about this session?

+
    +
  • Perhaps some more interactivity but can be hard to plan and time

    +
      +
    • We’ll see what we can do.

    • +
    +
  • +
  • Maybe mix the breakout groups up for each breakout session (although there are advantages to consistency too) :+1:

    +
      +
    • yes, pros and cons! For me, having consistency worked well this time.

    • +
    • Likely we will have different participants next week, and a bit of mixing will happen naturally.

    • +
    +
  • +
  • The pace of the presentations could be a little tighter (the pace is good for a discussion though)

  • +
  • Richard’s voice was only 80% audible

    +
      +
    • Sorry to hear that. It seemed fine on my end. Will check better for next session.

    • +
    +
  • +
  • Hands on simulation and collaborative notes

  • +
  • I found it difficult to follow the presentation and the collaborative notes at the same time

    +
      +
    • We will highlight the collaborative notes more in the next session. Our strategy usually is to say to focus on the “teaching part” and use the notes only when needed. Since you can go back and also check the notes later.

      +
        +
      • My problem is that I want to follow both since I don’t want to miss out on anything. As such, I have both windows (zoom and the notes) open side-by-side. Since there is near-constant real-time typing in the editor, and as such visible movement on screen, I get constantly distracted. This makes following the event quite exhausting.

      • +
      +
    • +
    +
  • +
  • Heads up to participants on using the break out rooms on voice interaction and screen sharing.

    +
      +
    • Do you mean that we should have mentioned it more clearly in the pre workshop email?

    • +
    +
  • +
  • I found it hard to follow with so many things going on at once…

    +
      +
    • A collaborative document being changed at the same time as…

    • +
    • Someone speaking and explaining content at the same time as…

    • +
    • Chat in a different application at the same time as…

    • +
    • Content changing in a termin application.

      +
        +
      • Thank you for the feedback. We will remove the Zoom chat out for the next session and explain the use of the collaborative notes more.

      • +
      +
    • +
    +
  • +
  • Make more use of defining and then making sure the learning objectives are met

    +
      +
    • True we did not talk about them much, will pick that up better for next session.

    • +
    +
  • +
  • UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. - Dennis Ritchie. You need to do a lot to prove that to be wrong, simply put.

  • +
  • Allocate some time for learners to type in the answers so that we don’t have to listen and type at the same time.

  • +
+

Any other comments?

+
    +
  • It’s great to hear other people’s experience

    +
      +
    • Good to hear :)

    • +
    +
  • +
  • Looking to meet you onsite if there are any events and get more emails from you :)

    +
      +
    • We will keep you informed :)

    • +
    +
  • +
  • Thanks for putting this together, I got a lot of inspiration for my own courses

    +
      +
    • Good to hear :)

    • +
    +
  • +
  • I didn’t know where to ask questions. It would work best for me to do it in zoom chat as that’s the application that I’m watching in..

    +
      +
    • Sorry for that, just to figure out why: Did you join a bit late?

      +
        +
      • No. Perhaps I just missed that or it was too quick for me or something?

        +
          +
        • Ok, sorry. Will try to make this more clear in next session.

        • +
        +
      • +
      • Perhaps also because there were so many things going on and jumping around. For me, the zoom chat is the constant (and obvious) place to ask questions while watching a shared screen, trying to find the right place in a moving collaborative document is difficult. It tears my attention into too many pieces. :+1:

      • +
      +
    • +
    +
  • +
  • Had a lot of content that assumed extant knowledge that I didn’t have. This wasn’t in the pre-requisites.

    +
      +
    • Do you have examples?

      +
        +
      • Yes! The code refinery templates and even just the way of doing that. I was expecting more on “when designing a lesson you should think about these steps” rather than this is how we do it and this is our tool for doing it. I guess I should have read the pre-workshop content better?

      • +
      • Ok, thank you for your feedback. You are right that we actually had some content that for sure would have been easier to follow for people with background knowledge about a certain topic.

      • +
      • “If you are in CodeRefinery TTT, you probably know what version control is and why it is important.” - extant knowledge, why not just add a sentence or two?

        +
          +
        • Please can you update in preparation for the next workshops so that I can decide whether or not they will be right for me?

          +
            +
          • Yes, we will think more thoroughly about this and send the info in the next email going out Wed/Thu

            +
              +
            • Thank you!

            • +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • Lots of the content was relevant to code refinery but not the wider topic (e.g. it was how to design a code refinery lesson and not how to design a lesson as stated in the session title)

    +
      +
    • We thought of the content of showing one way of doing things, ie “what we have learned”, if you have suggestions on how we could make that more clear on the event page, please let us know :)

      +
        +
      • “in a code refinery lesson” in the lesson/workshop description?

      • +
      +
    • +
    +
  • +
  • When you have pre-written “thank you for your active participation” it feels fake!

    +
      +
    • He, that is true, did not think about that. Thank you for the feedback. I would not have added it if Radovan and Richard would not have provided good feedback from circling the rooms.

    • +
    +
  • +
  • I found it vague and disorganised and difficult to follow. It felt like the instructors were presenting the content for the first time and didn’t know what to do next.

    +
      +
    • Thank you for your feedback. This is not the first time we have this training, but it is the first time in this constellation/way. The way of teaching may also sometimes make it seem new to instructors.

    • +
    +
  • +
  • I really liked the active exchange with other participants, but I also would have enjoyed a bit more technical content in the presentations. In a sense it felt less like a ‘training’ and more like a get-together :+1:.

    +
      +
    • Thank you for your feedback. We thought the name “workshop” would combine the training and exchange nature of this event. But maybe it didn’t do so enough? Do you have suggestions on how to clarify it on the event page?

      +
        +
      • Well, the ‘train the trainer’ title created the anticipation of being trained ;) don’t get me wrong, I liked the exchange, but I felt that the training aspect fell a little short. imho the workshop would benefit from a little more (instructional) content that is presented in a more structured way by the instructors (as opposed to ‘crowd-sourced knowledge’ that is collated in a loose collection of questions, notes and links)

      • +
      • Other than that, you could add another section on the main page, sth like ‘Workshop structure: we aim for a mix of modular presentations and work in small groups. The latter will be done in breakout rooms - be prepared to switch on your camera and have a fruitful exchange with fellow participants!’

        +
          +
        • Thank you for the suggestions, will add something like this :tools:

          +
            +
          • +

            Added : https://github.com/coderefinery/train-the-trainer/commit/03308595436e636b3bb37ed9d1f0dee39eeccd0f

            +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • My understanding (so far) of what (unlike the competition) CodeRefinery DOES NOT seek to exemplify - +https://images.ctfassets.net/rxqefefl3t5b/2k45BFtw4sBMlBfjr1OZ90/5c6ecd3628a43b0cdc79815f665e224a/Screenshot_2023-05-02_at_09.35.23.png?fl=progressive&q=80

  • +
  • My understanding of what (unlike the competition) today’s session of CodeRefinery DID exemplify - Definition of ‘Workshop’ from the Oxford dictionary of the English language “a period of discussion and practical work on a particular subject, in which a group of people share their knowledge and experience”

  • +
  • In my experience, even for the most seasoned Programmer coding, by its very nature, is nothing trivial, this being a simple straightforward fact just like there is no such thing as an egg which is a cube. I mean there is a reason why not just about everybody is a poet either. But, other minds have pointed this out without having to first explain why the universe is what it is in a way that could be understood without effort … https://i.pinimg.com/originals/7b/7e/c4/7b7ec4b91d2cf9d8e1b064678d205467.jpg

  • +
  • The inclusive environment feels very welcoming. Keep up the good work!

  • +
+

Thank you all for your feedback! Highly appreciated!

+
+
+
+

Day 2 : Session 2 (20.08.24)- Tools and techniques adopted in CodeRefinery workshops

+
+
:calendar: Schedule
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 9.25

About CodeRefinery workshops

10.15 - 10.25

8.15 - 8.25

9.25 - 9.55

Collaborative notes and interaction

10.25 - 10.55

8.25 - 8.55

9.55 - 10.10

Break

10.55 - 11.10

8.55 - 9.10

10.10 - 10.45

Workshop overview, roles, onboarding

11.10 - 11.45

9.10 - 9.45

10.45 - 11.05

Sound

11.45 - 12.05

9.45 - 10.05

11.05 - 11.20

Break

12.05 - 12.20

10.05 - 10.20

11.20 - 11.50

How to prepare a quality screen-share

12.20 - 12.50

10.20 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+
:icecream: Icebreaker
+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :-)

  • +
  • https://media.istockphoto.com/id/148421550/vector/bored-emoticon.jpg?s=612x612&w=0&k=20&c=uo5KBTqdJZbBQb_Xldhzuovx5t08fHfGR7dw7TCk90I=

  • +
  • :saluting_face:

  • +
  • :sleepy:

  • +
  • :coffee:

  • +
  • :umbrella:

  • +
  • :cocktail: :coffee:

  • +
  • :seedling:

  • +
  • :tired_face:

  • +
  • :sun_with_face:

  • +
  • 🥴 (:woozy_face: not converted?)

  • +
  • :coffee:

  • +
  • :sunflower: :book:

  • +
  • :satisfied:

  • +
  • :coffee:

  • +
  • :coffee:

  • +
  • 🥱:tired_face:

  • +
  • :bread: - I am baking bread today so I have been kneading dough while listening!

  • +
+
+
+
Introduction in breakoutrooms
+

Name / Affiliation / Location

+
+
+
Teaching
+
    +
  • Do you teach and organize teaching alone or with others? What would you prefer and why?

    +
      +
    • Coming together is a beginning; keeping together is progress; working together is success. – Edward Everett Hale

    • +
    • These days always with others. Alone is easier to prepare but almost always is harder during it.

    • +
    • Teaching with very diverse partners, it can be challenging to find a common language with people very different than you.

    • +
    • I teach alone, in the future there will be more collaboration with multiple team members. Both approaches have their pros and cons.

    • +
    • Both has its own distinct advantages

    • +
    • Most of my teaching is on my own, as a freelancer its more expensive to work with colleagues than to deliever a course on my own.

    • +
    • Teaching together, learns from each other, feedbacks to improve

    • +
    • Not formally taught yet, only given presentations actually .

    • +
    • collective teaching would benefit the teachers with collaborative curriculumn and experiences sharing.

    • +
    +
  • +
  • If applicable, have you seen any challenges when teaching together and how to overcome them?

    +
      +
    • It actually requires preparation,

    • +
    • Is it about teaching or about inspiring ? Discover the answer and get inspired …

    • +
    • It’s like being in a band: you might be great at improvising and your band-partners might be great at improvising too, but a bit of rehearsing makes even the impro gig much better

    • +
    • Need to plan before session, difficult if people don’t ‘plan’ in the same way, e.g. with the same time frame.

    • +
    • Heterogeneity in learners make it impossible to get the same result from everyone.

      +
        +
      • In fact, the same applies to teachers :D

      • +
      +
    • +
    • Teaching together requires to have similar opinions on how to teach. I share vews only with ~40% of my colleagues I think.

    • +
    +
  • +
  • No Teaching experience but it is good to give the outline of the lessons beforehand and learning goals.

  • +
+
+
+
+
+
:question: Questions
+
+
General / Practicalities
+
    +
  • What is this document for?

    +
      +
    • Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts)

    • +
    +
  • +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms?

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    • BR 1 : The Zoom chat does not work for the breakout room so we should take note of that. No webcam/mic = expect silence.

      +
        +
      • Thanks for notifying! This was not intended. Turned the chat back on.

      • +
      +
    • +
    +
  • +
+
+
+
+
+
Episode 1: CodeRefinery
+

Materials: https://coderefinery.github.io/train-the-trainer/coderefinery-intro/

+
    +
  • (questions continue here)

  • +
  • Is there the plan to build capacity / be paid to deliever courses?

    +
      +
    • We’ve discussed it but right now we don’t have many people who could accept money to do this (and maybe shouldn’t, because of their jobs). But, we would encourage others to use our materials as “independents” to deliver paid courses

    • +
    • One idea we have had is that paid courses could be delivered through the DRA (link below), who we know. Basically, DRA could find instructors and handle the money transfers (If someone wanted a paid course, we could help find someone to do it through DRA or independently)

    • +
    • :smile:

    • +
    +
  • +
  • Have you come across DRA, https://digital-research.academy/, Heidi Seibold, Joyce Kao who are doing similar work? I can connect you if you like.

    +
      +
    • Yes we have been discussing about possible future collaborations and are already sending possible clients their way (we, as a project cannot take money) :+1:

      +
        +
      • Excellent! :-D :smile:

      • +
      +
    • +
    +
  • +
  • .

  • +
+
+
+
Episode 2: Collaborative Notes
+

Materials: https://coderefinery.github.io/train-the-trainer/collaborative-notes/

+
    +
  • So anyone can type anonymously?

    +
      +
    • Yes, as long as you do not log in, you are Guest XXX

    • +
    • And at least in our hedgedoc case you cannot log in so you will always be anonymous. You can do [name=xxx], to add your name to a comment

    • +
    +
  • +
  • Test of +1

    +
      +
    • +1 :+1: :+1:

    • +
    • :-1: a test

    • +
    +
  • +
  • You are hosting your own version of HedgeDoc, and Hackmd.io is a similar (free) option. What are the limitations of the free hackmd.io? Should each center install their own HedgeDoc instance?

    +
      +
    • It seems the free version of HackMD has gotten worse lately. It works still well enough with a few people editing at the same time.

    • +
    +
  • +
  • Have there every been problems with the anonymity and CoC?

    +
      +
    • We haven’t had any issues so far.

    • +
    • With a different anonymous tool in a bachelor course, we had issues with anonymous participants (participants were posting slurs and unsafe links). The course organiser decided to stop allowing anonymous tools.

    • +
    +
  • +
  • Why not google documents?

    +
      +
    • Google documents are actually setting a hard limit for simultaneous writing, no more than 100 concucurrent editors. I am unsure if microsoft onedrive word documents would allow more users writing at the same time.

    • +
    +
  • +
  • What’s the most people you have every had on HackMD / Hedgedoc?

    +
      +
    • I believe about 200 active participants?

    • +
    +
  • +
  • What are your thoughts on using the build-in Zoom Q&A?

    +
      +
    • We haven’t tried this, in part because the way we do streaming now (you’ll see in session 4), participants aren’t in Zoom so don’t have access to that. The doc-format works pretty well though, when we keep it in this limited “write at end” format.

    • +
    +
  • +
  • How do you see what has changed? e.g. if leave the session at the end, can I come back tomorrow and see X has been added? e.g. a diff for this maybe?

    +
      +
    • In the menu up right there is revision, it does show the document and changes at different time step :+1: Thanks!

    • +
    • We recommend people only write at the bottom (and since we answer things live), so as a first level approximation you find where you were and read below that. Think of it more like chat than a full document. (Yes, we do revise questions at the end)

    • +
    +
  • +
  • How about flinga boards or similar tools?

    +
      +
    • My take is that the simplicity of a simple text document wins over free-form in-person-workshop-like tools.

    • +
    • There’s miro, can be a bit confusing though

    • +
    +
  • +
  • How does this work with small groups, e.g. 10-15 people?

    +
      +
    • Good question: it can be hard if people aren’t rigorous about it, people start only using chat/voice. So there seems to be some lower bound in size but we haven’t tested this much

    • +
    • And if the instructors never screenshare it to show what goes on it, then seems to be less used.

    • +
    • And if there aren’t other people to read/answer it during the session (perhaps less likely in a small course), it seems to be less used.

    • +
    +
  • +
+
+

Breakoutrooms until xx:55

+

Exercise/discussion: https://coderefinery.github.io/train-the-trainer/collaborative-notes/#exercise

+
+
    +
  • Breakout room 1:

    +
      +
    • Use of etherpad for collaborative discussion.

    • +
    • Use of slido for polling and quizzing.

    • +
    • Presemo as a slido alternative (https://www.aalto.fi/en/services/presemo-a-fully-web-based-classroom-participation-system)

    • +
    • Use of text based approach for questions rather than live can be helpful if there is a language barrier issue.

    • +
    +
      +
    • A good teaching session which had many questions coming spontaneously to the teacher is a non-entity of sorts. If the overall flow of feedback / questions increases it could indicate that the session will not prove to be a helpful experience. A signal that generates noise is, well, noise, if calling a spade a spade signals anything. Note that the ‘overall’ bit and the ‘to the teacher’ aspect are important. Both the best and the worst teaching session have two things in common: a teacher, and the fact that NO Materials of any kind are used, ie speech is the only channel of communication via a common language. The only difference is that it is not the same teacher, at least not in the same session at the same time.

    • +
    +

    Another less mentioned, but perhaps more relevant indicator of a great session is the simple fact that at the end of the session EVERYONE feels empowered, NOT tired. This is not an easy to quantify thing, but screams out the quality of the experience loud. More often then not, such sessions differ little from each other, apart from in terms of the theme / topic and the participant mix. It ends up being the ‘keep your cake and eat it too,’ of sorts, not quite the far less amusing post-bombardment devastation scenario in the wake of a take it or leave it go at anything.

    +
      +
    • profanity in collaborative documents where people can add content anonymously could be a problem (happens very rarely, fortunately and somewhat surprisingly)

    • +
    +
  • +
  • Breakout Room 2:

    +
      +
    • Good experiences with Zoom polls

    • +
    • Handling questions in hybrid setups: all participants (on-site and online) ask questions in written form

    • +
    • Collaborative notes can be challenging when conducting a course alone (without teaching assistants) :+1:

    • +
    • Providing a method to ask questions anonymously can make asking easier for shy participants

    • +
    • Questions can give valuable feedback on how the course is going

    • +
    • Online collaborative whiteboarding platforms such as Miro

      +
        +
      • Large monitors are useful for this not to have to drag a “periscope” around

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • good experience with whatsapp chat for questions. since most learners have the app already and one thing less to install and set up

      +
        +
      • reply to question is a way to handle multiple questions at the same time but it works well for smaller groups

      • +
      +
    • +
    • experience with collaborative docs in in-person workshops: voice questions might “win” over the document

    • +
    • “seeding” questions may help to not have an empty document

    • +
    • it can help somebody to start and create a structure which helps others to see and follow

    • +
    • we discussed the Carpentries sticky notes system (red sticky note: signal tech issues and use for feedback, green sticky note: signal that exercise worked and for positive feedback)

      +
        +
      • Nice summary of sticky notes system: https://teachtogether.tech/en/#s:classroom-sticky-notes :+1:

      • +
      +
    • +
    • What is the success rate of in-person workshops after COVID? Discussion: Teachers prefer in person and learners prefer remote or recorded to spool back and relearn.

    • +
    +
  • +
  • Room 5

    +
      +
    • Good experience with Collaborative tools as HackMD and HedgeDoc while teaching with no bad feedback

      +
        +
      • When used with smaller groups works best as one-way, like sharing links with students and so on

      • +
      • Needs to be done as a team, quite difficult if teaching alone

      • +
      • Most useful when online/hybrid

      • +
      +
    • +
    • Anonymisity is important for transparent feedback and no biasis in classrooms

    • +
    • Not very collaborative but useful to share history or jupyter notebooks live https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush

    • +
    • Used Flinga before that seems like Figma and also onsite teaching using sticky notes

      +
        +
      • There’s miro.com but can be a bit confusing, more for brainstorming than for teaching

      • +
      +
    • +
    • Using quizzes apps like Kahoot is beneficial while teaching to have more engaging students

    • +
    • +
    +
  • +
  • Room 6

    +
      +
    • teaching teenagers (in presence) but using shared pad becomes quickly very chaotic, so only usable for short moments when answering very precise questions

      +
        +
      • Yeah, I can imagine. For CR we try to keep it in this very limited format (all questions bullet points, only add to the end) and I think that helps.

      • +
      +
    • +
    • using shared notepad for small workshop (5-10 people) to explore common thematic (mainly technical) to keep a shared notes and condense aftwerward (and publish on wiki to archive)

    • +
    • Difference between teaching in person and online. Some people prefer in-person and sometimes you have no option but to organise it online.

    • +
    • There are sometimes cultural differences and learners feel shy to ask / question the knowledge of the Teacher, so shared notes are a good way to safely ask questions.

    • +
    +
  • +
+

Questions continue:

+
    +
  • Have we demonstrated how we do polls in HedgeDoc? Add your vote by adding an o

    +
      +
    • yes: oooo (in session 1)

    • +
    • no:

    • +
    • :smile:

    • +
    • not sure: o

    • +
    +
  • +
+
+
+
Episode 3: One workshop, many perspectives
+

Materials: https://coderefinery.github.io/train-the-trainer/overview/ +Next CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/

+
+

Exercise until xx:39

+

https://coderefinery.github.io/train-the-trainer/overview/#discussion

+
+
    +
  • Room 1

    +
      +
    • Send pre-workshop email with pre-requisite instructions on what should be set-up beforehand.

      +
        +
      • But, also mention that if help is needed for set-up, we will be ready before the session officially starts.

      • +
      +
    • +
    • Discussion on whether we push to work in a pre-ready environment (e.g. Binder, Colab) or in their own environment.

    • +
    • Lots of help needed both before and after.

    • +
    • Installations: as much as we can provide ready made environments for the learners, maybe installations will be something that the learners will face sooner or later. Maybe one should teach more about installations?

    • +
    • My only cherished role in a teaching-learning session is the that of one who is living the moment as if there were no tomorrow. What cuts all ways really is that “By failing to prepare, you are preparing to fail.” ― Benjamin Franklin. A helpful motto: “When one teaches, two learn.” — Robert Heinlein. The best experience cannot be given, it can only be allowed to flow its way, so get out of its way.

    • +
    +
  • +
  • Room 2

    +
      +
    • Frequently, a single person fills all the roles for a single or multi-day workshop

    • +
    • Collaboration with different centers/ universities can be challenging

    • +
    • Preparing participants: it’s essential for the instructor to go through the demos and be sure that they will work (no unpleasant surprises live). This can be extended to advance-prep for participants.

    • +
    • Best experience is to hear (live or in feedback notes) some positive things directed at you :)

    • +
    • Fully prepared environments (eg self-hosted JupyterHub) can make preparation for participants easy

    • +
    +
  • +
  • Room 3

    +
      +
    • Some students have problems with setuping the environment. Maybe having a step by step instructions could help. But some students don’t want to “start” the course before hand.

    • +
    • Preparing the environemnt before hand ensures everyone is onboard from day 1. The same thing happend in CSC training sessions and another session Peng attended.

    • +
    • Had experience in attending as teacher and student in previous workshops

    • +
    +
  • +
  • Room 4

    +
      +
    • knowing the background of the audience is helpful

      +
        +
      • Try and ask in advance of the background of the audience. Do a poll at the start of the workshop. In person one can do it interactive.

      • +
      +
    • +
    • among co-instructors: discuss topics and flow

    • +
    • if more people are involved, it can help changing roles from time to time to see different perspectives

    • +
    • preparation is key

    • +
    • Circulate instructions beforehand

      +
        +
      • Do a poll before session: Have you installed (QGIS) successfully?

      • +
      • Push hard to do this in the welcome email

      • +
      +
    • +
    • communicate clearly to the participants

    • +
    • +
    +
  • +
  • Room 5

    +
      +
    • We’ve all taken most roles

    • +
    • How to prepare in advance?

      +
        +
      • Meet and discuss once or twice

      • +
      • Make a pre-survey to check for interest and background

      • +
      • Going through the materials

      • +
      • Checking the toolkit (zoom)

      • +
      • Agree on the reponsibilities and back-up plans (bit of scenarios planning)

      • +
      +
    • +
    • How to prepare trainings in advance?

      +
        +
      • Collect resources and prepare the workshop plan

      • +
      • Having the material readily available online ans sharing it

      • +
      • Making a pre-survey

      • +
      +
    • +
    • What was the best workshop experience for you as learner, helper or instructor? What made it great?

      +
        +
      • learner

        +
          +
        • Engaging and practical workshop with more exercices and follow-up theoretical part explanations

        • +
        +
      • +
      • helper

        +
          +
        • When the instructor is well prepared and as helper ther’s only typos to fix and interesting questions to answer

        • +
        • Assist the instructor, coordinate the collaborative notes, and make sure that the time is respected

        • +
        +
      • +
      • instructor

        +
          +
        • I have a colleague whom I’ve ran the same workshop a few times already, goes quite smoothly now and we’ve made a few changes. Hard to reach that point with new colleagues but getting there

        • +
        • Students/participants were engaging with the material and many good feedback collected even some of them asked for the next workshop

        • +
        +
      • +
      +
    • +
    +
  • +
  • Room 6

    +
      +
    • What has made a great experience for you as a learner/helper/instructor?

    • +
    • Common ground between learners & teachers

      +
    • +
    • Motivation

      +
        +
      • Teaching is much more enjoyable when the learners want to be there

      • +
      • I spend a lot of time at the start of a workshop making sure learners feel that the content is possible for them to understand and master

      • +
      +
    • +
    +
  • +
+

Poll: I have joined a CodeRefinery workshop before: (add an o for your answer)

+
    +
  • yes (within last 2 years): ooooooo

  • +
  • yes (longer time ago): oo

  • +
  • no: oooooooo

  • +
  • +
+

(questions would continue below:)

+
    +
  • What is the motivation / advantages of streaming workshop versus using zoom?

    +
      +
    • We’ll cover this more in week 4, but roughly: zoom became unmanageable and essentially quiet once things got big. Streaming allowed “one to many” communication with no limit, and collab notes allowed better interaction anyway. By separating the rooms, it was more pleasant to teach. Videos could be released immediately since there was no risk of privacy of participants. There could still be in-person/online small groups who have “watching parties.”

    • +
    +
  • +
  • What are the blue red and green font colors here, does it symbolify anything or just a convention HedgeDoc uses?

    +
      +
    • Visual separation of formatting, mostly. (It helps to quickly realize you’ve missed/ mistyped a control Markdown symbol etc.)

    • +
    • Yeah, it’s bascically “code highlighting” for markdown. No special meaning but quite convenient for us.

    • +
    +
  • +
  • Is this next workshop only for team leads or also open for helpers and coordinators?

    +
      +
    • You mean the next session of this workshop or the upcoming “CodeRefinery workshop”(this one: https://coderefinery.github.io/2024-09-10-workshop/)?

      +
        +
      • The upcoming workshop coordinators are alredy working, but can be joined if you are interested

      • +
      • As helper roles we currently only have “collaborative notes helper”, which is all about helping to answer questions in the collaborative notes

      • +
      • We do have some co-teaching slots open :)

      • +
      • If interested: join the discussion in our chat: https://coderefinery.zulipchat.com/#narrow/stream/316508-coderefinery-tools-workshop/topic/Fall.202024.20CodeRefinery.20workshop

      • +
      +
    • +
    +
  • +
  • Can a person have multiple roles in a workshop as a helper and a teacher?

    +
      +
    • Yes, many teachers also contribute to the rest of the workshop by answering questions in collaborative notes. :+1:

    • +
    • Some teachers also host a local classroom in week one and do their teaching in week two of the workshop

    • +
    • Roles that do not go well together are broadcaster/director/host and instructor (goes well until there is a problem; co-teaching solves that partly)

    • +
    +
  • +
+
+
+
Episode 4: Sound
+

https://coderefinery.github.io/train-the-trainer/sound/

+
    +
  • To me, Richard is a bit quieter than the other two :+1: :+1: :+1:

    +
      +
    • to elaborate: I think that the audio coming from him is missing some mids

    • +
    • Do you have any links about this kind of evaluation and adjustment?

    • +
    +
  • +
  • Do you suggest / recommend a specific headset(s) with mounted microphone?

    +
      +
    • in our experience headsets with a microphone will almost always be better than a separate microphone sitting on the desk or in the monitor

    • +
    • +
    +
  • +
  • Speakers have different tones of voice and speaking styles, is there a recommendation or experience from CR workshops for how this is adjusted and catered to environemnts for listeners?

    +
      +
    • Yeah, people’s voices are different and we haven’t gone as far as voice training or improving.

    • +
    +
  • +
  • How to change the volume for speakers? Tried Zoom settings and system settings and didn’t help.

    +
      +
    • From linux I can use different pulsemixers pavucontrol, pulsemixer to set the gain to above 100%. I’m not sure the equivalent on other OSs but

    • +
    +
  • +
+
+
+

Exercise until xx:10 +https://coderefinery.github.io/train-the-trainer/sound/#exercises

+
+
    +
  • room 1

    +
      +
    • Practically, no typical headset is designed or can capture the technical purity of human voice within its natural environment. But one needs to understand the polar pattern of the (specific) microphone or how much of the signal will be picked up by the microphone from different directions, a sine qua non when it comes to mitigating unwanted sound sources to bleed into the signal.

    • +
    +
  • +
+

For best results, keep the right direction & distance to your (directional) mic. Usually, that’s between 15-30 cm to get get a natural sound. A microphone records everything it can, also silence, so check the headphone output BEFORE adjusting the gain, in some specific cases aim for a dry sound, ie the influence of the room or how audible the room is on the recording ! Finally, adjust the mix between dry and room sound, or change the frequency response in tandem using a compressor to reduce the dynamic range of a signal for a more consistent listening experience = the quietest parts of your signal will appear louder by reducing the loudest parts.

+

It is all about one thing and one thing only - love your voice, let people fall in love with the acoustic quality of your charm. So remember: GIGO, it matters!

+
    +
  • Room 3

    +
      +
    • Had different headsets and we could see the difference (bluetooth low quality)

    • +
    • How to change the volume?

      +
        +
      • It’s surprisingly hard to get more control than the basic slider you see in the apps! You need to look.

      • +
      +
    • +
    +
  • +
  • room 4

    +
      +
    • headset is probably better listening experience but they can be uncomfortable to wear during long meeting days :+1:

      +
        +
      • Yeah. Luckily only instructors

      • +
      • Therefore breaks are non-negotiable

      • +
      +
    • +
    • loud keyboard can be an issue

    • +
    • if one has a silent room that does not echo, it can be ok to teach without headset

    • +
    • on Linux I am using pulsemixer to adjust levels and pavucontrol to change outputs/sources

    • +
    • mic modes on mac

    • +
    • check default microphone for zoom.

    • +
    +
  • +
  • room 5

    +
      +
    • Most tricks help tuning yourself but hard to do it as a group. Perhaps doing a short recording.

      +
        +
      • Yeah. Some independent recording/playing aronud, but also asking for advice. I would do small group/one-on-one things.

      • +
      +
    • +
    • Background noises cancellation tools or wise choice of quiet environments

    • +
    • Audio check with colleagues or through the app with the audience saying numbers for example

    • +
    • Zoom or Teams have sound checks but work different in the app than the browser. They also work different across Operating systems

    • +
    • Some sound issues might be related to network speed or stability, also to RAM available. Worthwhile to try and control those as well

    • +
    • Make it welcoming for the audience to give you feedback on the audio and other settings, give reminders

    • +
    +
  • +
+
+
+
Episode 5: How to prepare a quality screen-share
+

Materials: https://coderefinery.github.io/train-the-trainer/screenshare/

+
    +
  • If your Zoom does not support “share portion of screen”, sharing a tab and resizing it to portrait for yourself is a possible workaround (this at least works when joining the call from Chromium browser)

    +
      +
    • Another workaround is to use an editor/IDE that displays multiple panels in one window and can show a web page, code files and terminal session +10

    • +
    +
  • +
  • Is ‘share a portion of your screen’ where you draw a box in Zoom to share a section?

    +
      +
    • yes :+1:

    • +
    +
  • +
  • When using zsh, one can run something like this in a terminal

    +
    tail -n $NLASTCOMMANDS -f ~/.zsh_history | sed 's/^.............../LAST COMMAND:/g'
    +
    +
    +

    (I place this in a window under the main terminal, I use i3)

    +
  • +
  • I am a bit confused on what platform you are putting this code?

    +
      +
    • Radovan is using Linux with (I think) the “i3 window manager”. It can be quite involved and there is lots of personal customization here.

    • +
    +
  • +
  • When teaching with a custom prompt, is it worth starting with the default (that your learners will see) and explicitly mentioning “I change these things to make it clearer when teaching”

    +
      +
    • One should always comment on what may be different. Thing is “default” may look different for many people :+1:

    • +
    • “I am not going to teach you how to customise your prompt, but here’s an online tutorial, be prepared to lose several days of your life…” :laughing:

    • +
    +
  • +
  • Now I can’t see the last line in the terminal

    +
      +
    • Yep, that’s a problem. It can be good to keep a buffer on the bottom of the screen.

    • +
    • If you move your mouse outside the Zoom window, the controls should go away. But still a good note.

      +
        +
      • My mouse was on another screen.

      • +
      • Ok, thanks.

      • +
      +
    • +
    • I think one can also make the zoom bars not auto-hide (then it won’t display under), but that is annoying also since it wastes space.

    • +
    +
  • +
  • Does anybody still use shellshare? Does it work?

    +
      +
    • We in CR haven’t used it much but we have seen it.

    • +
    +
  • +
  • Does the stacking of the screens work on windows?

    +
      +
    • Don’t know unfortunately

    • +
    +
  • +
+
+

Exercises (done together) +https://coderefinery.github.io/train-the-trainer/screenshare/#exercises

+

Write your cool tips and ideas below. +Stay after xx:00, to

+
+
    +
  • To be safe, I have created on my computer an account that I use only for teaching, so I do not need to do any manual set up

  • +
  • share history or jupyter notebooks live (5-10 secs refresh rate) into a git repo. Share the link with the learners so they can catch up https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush

  • +
+
+
+
+
+

Wrapup

+
    +
  • Next session Tuesday August 27 9 CEST: About teaching & cool things we all would like to share

  • +
  • All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • Cool gems session: If you want to share something, please edit your registration and fill it in there (link to modify in registration confirmation); or e-mail to support@coderefinery.org

  • +
  • If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14:00 (Europe/Stockholm time)

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • Sound and screen share optimization as well as relevant tools and good practices for online instruction. “While you may be unable to control your users’ mindset, you can anticipate it, and make sure that your user experience caters to it.” - Jonathan Cherki

  • +
  • Nice opportunity to (re)think about my online teaching setup :+1: :+1: :+1:

  • +
  • Other ways to display command history :+1:

  • +
  • Did not know that bluetooth gear had so much latency! :+1:

  • +
  • A good reminder about headsets with microphones

  • +
  • Nice and friendly teaching. Thank you!

  • +
  • Screen share with command history and terminal customisation

  • +
  • Really useful tips on sound and screen sharing :+1:

  • +
  • Nice experience share

  • +
  • very useful and practical tips!

  • +
  • Easy to follow along and filled with useful tips on sound, video etc.

  • +
  • +
+

What one thing would you improve about this session?

+
    +
  • Just digging to find something: I have read some of the things you have talked about here already in some blog posts, so perhaps these sessions are not as shokingly full of new content as I imagined (but actually sharing experiences is something I can’t do by reading a blog post)

    +
      +
    • Perhaps: could you link some blog posts or other sources for what you have discussed so far? If it makes sense. Not sure.

    • +
    +
  • +
  • Talking about interface optimization approaches, which applies to sound as much as to visuals or any other aspect either for that matter, it might offer a perspective to bear in mind the concept of introducing asymptotic complexity increment. The latter would mean the goal is measuring how fast the effort of engaging, on one or more of the three parallel levels of interaction, must change to reach higher levels of partial certainty on the correctness of the implementation of the method in question, in this case the pedagogical paradigm. For the former, lower is better I guess, or in this case, in the intended sense, slower is faster. Let us consider an abstract example: People liked using the search engine Google (a Google session to put it in a fancy way) in the early days because it was as simple as it could get, a literally featureless entry point with no bells and whistles. That was the level of its visible complexity, or rather Google set a bar as low as it one could have, and then any higher point of VISIBLE complexity that was to be introduced, such a move would only be on the path of an asymptotic curve curving towards the set bar, never reaching it, as far as the entry point is concerned. We still see the same level of complexity when we fire up google and we never feel distracted to start with, except for the rather forgivable nuisance of the GDPR conformity pop-up notice which appears only AFTER the first move has been made, and thankfully it works plain and simple from there on (unless one starts feeling lucky, pun intended). Now, think about Youtube … the user experience complexity is a totally different matter, the same company today (unfortunately) yet one now has a steadily worsening engagement experience. Good learning sessions tend to be more of the Google search engine experience and a far cry from the current Youtube trend I would opine. Or, to sum it up and keep it sweet and simple, it helps to identify the limits of human-human and human-technology interaction, within the framework of any applicable technology-technology interaction and joy is the result of respecting those limits. Wishful thinking ?

  • +
  • Bring the cat back!

    +
      +
    • I wish it came, but it’s been resting all morning! I don’t bother it or stage apperances…

    • +
    +
  • +
  • Maybe having a digest/ summary of previous iterations of this session might be interesting. I feel a lot of experiences have been exchanged and a lot of techniques/ tools have been mentioned. Spending some time in compiling this into a selected list and adding it as content to the course itself might be worthwhile.

    +
      +
    • Good idea! We will write a blog post about this workshop and will include a summary of all discussions there :)

    • +
    +
  • +
  • Possibly have some command line examples from Windows rather than (just) *nix? I will look at the screenshots after the session. :+1: :+1:

    +
      +
    • Also, a thought if you do do breakout sessions with this work, do one for Unix, one for Windows, one for Mac as an option.

    • +
    +
  • +
  • I could not follow the part Radovan showed codes (Radovan is using Linux with (I think) the “i3 window manager”.)

  • +
  • ..

  • +
+

Any other comments?

+
    +
  • Looking forward to the topics of following sessions.

  • +
  • Looking forward to the next sessions!

  • +
  • Thank you!

  • +
  • Relax, nothing else matters, live a life and have fun ! If you obey all the rules you may end up missing all the fun. ‘The best way to predict your future is to create it.’ - Abraham Lincoln :+1:

  • +
+
+
+

Day 3 : sessiion 3 (27.08.24) - “About teaching and cool things we all would like to share”

+
+
:calendar: Schedule
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 9.45

Computational thinking

10.15 - 10.45

8.15 - 8.45

9.45 - 10.00

Break

10.25 - 11.00

8.25 - 9.00

10.00 - 10.30

Teaching philosophies

11.00 - 11.30

9.00 - 9.30

10.30 - 11.00

Co-teaching

11.30 - 12.00

9.30 - 10.00

11.00 - 11.15

Break

12.00 - 12.15

10.00 - 10.15

11.15 - 11.50

Sharing teaching gems (voluntary)

12.15 - 12.50

10.15 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+
:icecream: Icebreaker
+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • +
  • :sleeping:

  • +
  • :coffee:+2

  • +
  • :robot:

  • +
  • Still little sleeppy :)

  • +
  • 🥴 (:woozy_face: still not converted 🤷‍♂️)

  • +
  • Our planet could be a cube. It has six sides to it. It must be a cube. A cube it is, this Blue Planet … just wondering …

  • +
  • 🦾

  • +
  • :sweat_smile:

  • +
  • computer says no :-) some network trouble

  • +
  • running late, and participating from a :train2:

  • +
+
+
+
Introduction in breakoutrooms
+

Name / Affiliation / Location

+
+
+
Best classroom experiences
+

As a learner or teacher; what was the best workshop/lesson/seminar you have attended? What made the experience great?

+
    +
  • Room 1

    +
      +
    • First summer HPC streamed workshop (as a teacher). Somehow the first felt the best

    • +
    • CSC HPC summer workshop

    • +
    • story telling teaching approach

    • +
    +
  • +
  • Room 2

    +
      +
    • NVIDIA DLI Course on Deep Learning

      +
        +
      • very enthusiastic instructor

      • +
      • intuitive and very accessible way of showing technical details and fostering deeper understanding

      • +
      • a lot of hands-on material and smaller coding exercises

      • +
      +
    • +
    • Anything as long as its interactive and somehow enjoyable from both teacher and learner sides

    • +
    +
  • +
  • Room 4:

    +
      +
    • EPCC MPI Distributed training workshop.

      +
        +
      • Lots of hand on coding / experience gained.

      • +
      • Very interactive instructor who also discussed ideas for more personalised cases of distributed computing.

      • +
      +
    • +
    • Coderefinery RSE course

      +
        +
      • relevance of topic to my current work.

      • +
      • Dynamic / friendly / positive teaching style.

      • +
      • Modular Code Development; very instructive

      • +
      +
    • +
    • Some CSC courses / LinkedIn learning courses

      +
        +
      • up to date materials and topics.

      • +
      • Good way to merge theory with practicalities without making learner feel bored (Example: Jonathan Reichental)

      • +
      • Challenging information to learn more and research about the topic

      • +
      • Trainers are the experts in the field

      • +
      +
    • +
    +
  • +
+
+

Episode on teaching gems

+

If you want to share or demo something about tools and techniques you have found helpful in your teaching, please add your name/initials and rough topic below for smooth transition.

+
+

Note: It does not have to be your tool or your idea, this episode is meant to share experiences and discover new things. You also do not need any slides or materials, a story will do fine :) +Length of the stories will be depending on interest, but be prepared to fit it into 3 min (shortest possible).

+
+ +
+
+
+
+
+
+

:question: Questions

+
+
General / Practicalities
+
    +
  • What is this document for?

    +
      +
    • Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts)

    • +
    +
  • +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms?

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    +
  • +
+
+
+
+
Episode 1 : Computational thinking
+

Materials: https://coderefinery.github.io/train-the-trainer/computational-thinking/ (Link to slides in the middle of material)

+
+
Questions to audience
+

How might breaking down a complex problem into smaller parts change your approach to problem-solving in your current projects?

+
    +
  • Avoids cognitive overload

  • +
  • I used to give an example about this in workshops of cutting long tree into pieces from top to avoid that it falls and destroy a house bloc.

  • +
  • Easier to start on something small

  • +
  • Each individual part is familiar and can take existing solutions.

  • +
  • Only focus on the new things

  • +
  • One can lose oversight of where is supposed to be getting to due to problems with summation of biases introduced during the solving of the parts.

  • +
  • .

  • +
+

Can you think of a research project where identifying patterns in your data led to new insights or breakthroughs?

+
    +
  • Multi-targeted drug design where you need to identify both chemical and biological pathways/patterns

  • +
  • Distilling complex physics problems into simpler 1D statistics is very often done.

  • +
  • I used to do bioinformatics, pretty much everything in biology is about patterns in strings of charachters (DNA, proteins). Finding those patterns and using them is the way to go

  • +
  • Pattern recognition DOES NOT lead to new insight, it is new insight which allows for the recognition of a ‘pattern’, the latter being an allocation of possible bias.

  • +
  • +
  • ..

  • +
+

What challenges do you face when trying to simplify complex concepts in your field, and how do you decide which details to focus on?

+
    +
  • Absence of a terminology / jargon to describe a new idea. :+1:

  • +
  • Similar to above, when teaching often students know what they want to achive, but don’t have the termonology to express it, so working through what they want is helpful, after teaching them some termonology.

  • +
  • Whatever is most useful to the learner first?

  • +
  • I work with researchers in different fields. I don’t always fully understand their domain knowledge but I can take the basiscs or generalities and get code that works for them

  • +
  • A very practical problem is trying to resist going for a coffee in the midst of taking a shot at a complex concept, in the hope that the true details are to be found in the coffee.

  • +
  • not all information is easy to find or a lot of conflicting information or even sometimes imformation explosion

  • +
+

How do you determine the priority of tasks when designing algorithms for your academic projects, and what criteria do you use to ensure that the most critical tasks are addressed first?

+
    +
  • Working chronologically when going through a problem - start at the beginning.

  • +
  • What gives the more insight with the least effort can be a nice start

  • +
  • Talk to colleagues and Subject matter experts to understand various perspective to decide and prioritize.

  • +
  • Logic will get you from A to B. Imagination will take you everywhere. - Albert Einstein.

  • +
  • ..

  • +
+
+
+
Questions from the audience
+
    +
  • About the 4 core concepts, is this based on the model of how human brain works and perceives vision / abstract ideas?

  • +
  • I don’t know if it’s based on how the brain works, but it’s related to creating a framework for solving programming programs that has been extrapolated to solve any other problem as well.

  • +
  • Devil’s advocate question: cooking (by recipe) actually employs all four principles outlined here and has done so since before the advent of computers. Why then is this concept presented as “computational”?

    +
      +
    • Random aside, this is an interesting connection to our “cooking metaphor to HPC”

    • +
    +
  • +
  • Devil’s answer to the Devil’s advocate: Great question, cooking, as far as the act happens in the Devil’s kitchen, does not employ numerical algorithms. The Devil introduced the computer precisely to make man lose apetite for that what is cooked in the Devil’s kitchen to be served to all. Only then can the Devil eat the cake and keep it too …

    +
      +
    • Well, an algorithm without numbers is still an algorithm, i.e. a set of rules :)

    • +
    +
  • +
  • Are there other names for this technique? I may have missed something crucial, but it strikes me as ‘logical thinking’ in a way.

    +
      +
    • Yes, you could also just see it as problem solving. Most people know how to do it and if you’ve worked with programming, you’ve probably applied it. It can be the case that it’s very obvious to some, but not to others.

    • +
    +
  • +
  • Any chance we can ge a link to the slides?

    +
      +
    • They are in the course material: https://coderefinery.github.io/train-the-trainer/computational-thinking/ :thumbs_up:

    • +
    +
  • +
+
+
+
Exercise questions to discuss
+
    +
  1. Conceptually would the strategies provided by computational thinking help you in completing tasks more efficiently?

  2. +
+
    +
  • Room 1:

    +
      +
    • divide and conquer technique

    • +
    • We discussed what happens if you don’t use these, since they are so natural

    • +
    +
  • +
  • Room 2:

    +
      +
    • in some cases yes, if the task is not too small

    • +
    • not sure if more efficiently but it does help at least getting strted

    • +
    • Computational thinking is an extension of what others have called solutionism: the belief that any given problem can be solved by the application of computation. Whatever the practical or social problem we face, there is an app for it. - James Bridle

    • +
    +
  • +
  • Room 3:

    +
      +
    • Helps in starting the task.

    • +
    • For many it is the normal way to do problem solving. Also in Agile & Scrum methodlogies.

    • +
    +
  • +
  • Room 4:

    +
      +
    • Yes, it helped me during my scientific research to manage multiple projects and research publications simultaneously.

    • +
    • +
    +
  • +
+
    +
  1. Do you think that the effectiveness of computational thinking depends on the person’s personality type?

  2. +
+
    +
  • Room 1:

    +
      +
    • yes, we agree it’s quite different. But good vision and motivation this can be effective

    • +
    +
  • +
  • Room 2:

    +
      +
    • yes, laying out all the steps necessary to achieve an overall goal can be very daunting; some people are not good at/ comfortable with following fine-grained instructions

    • +
    • once the problem is broken down, different personalities might choose different ways to tackle the parts

    • +
    • The degree to which something, that is a result of what one means by ‘Computational Thinking,’ is successful in producing a desired result, that is success, cannot be a function of personality.

    • +
    +
  • +
  • Room 3:

    +
      +
    • Yes. Different people have different ways to communicate.

    • +
    • Online tools vs pen and paper

    • +
    +
  • +
  • Room 4:

    +
      +
    • We are all agree that it depends on the personality type but it could be learned and trained

    • +
    +
  • +
+
    +
  1. Would this type of thinking be an option for you to integrate into your current workflow?

  2. +
+
    +
  • Room 1:

    +
      +
    • Yes; we didn’t know the name explicitly; but we use it

    • +
    • It’s quite important for

    • +
    +
  • +
  • Room 2:

    +
      +
    • I’m already doing it implicitly :smile: :+1: :+1:

    • +
    • Writing a program is like writing a song, its all about the tune, lyrics are merely the necessary nuisance a coder needs to put up with. The latter can, if so written, result in a lot of noise.

    • +
    +
  • +
  • Room 3:

    +
      +
    • Easy if you are working alone. But different team may have their own ways of working (inertia). One way would be then to gradually show the rest of the team its effectiveness.

    • +
    • https://teamtopologies.com/key-concepts

    • +
    +
  • +
  • Room 4:

    +
      +
    • We are using it in our daily life so it’s already an option for us, only the terminologies are a bit new.

    • +
    +
  • +
+
+
+
+
Episode 2 : Teaching philosophies
+

Materials: https://coderefinery.github.io/train-the-trainer/teaching-philosophies/

+

Questions to discuss:

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+
Breakout Room exercise
+
    +
  • Room1

    +
      +
    • Motivation

      +
        +
      • For best practices in teaching, learning from each other, collaboration

      • +
      +
    • +
    • Learning applied tech is like an apprecentiship: there is theory, but real learning happens by co-working with others.

    • +
    • Worse is better: teach what can be used more quickly and it can be improved later

    • +
    • +
    • I think there are two bits of teaching - teach the basics and terminology so people know what they want to know, and then teaching how to find out how to do things like Richard said - how to find answers yourself.

    • +
    • Using Jupyter notebooks - good for learning a technique, but not for learning the basics.

    • +
    • Possibly command line usage has a branding problem - “programming other programs”?

    • +
    • the skills we learn in CR training are expected to stay , it is not exam oriented

    • +
    +
  • +
  • Room 2

    +
      +
    • State objectives clearly and repeat them a few times

    • +
    • Try to keep it informal, interactive, flexible

    • +
    • Helps when having practical tasks in mind for the materials taught

    • +
    • Leave some reasoning to the learner, not always giving full answers

      +
        +
      • How to deal with frustration though: try some personal approaches, more clues…

      • +
      +
    • +
    • The mediocre teacher tells. The good teacher explains. The superior teacher demonstrates. The great teacher inspires. — William Arthur Ward

    • +
    • Teaching kids to count is fine, but teaching them what counts is best. –Bob Talbert

    • +
    +
  • +
  • Room 4

    +
      +
    • Question 1: What is your motivation for taking this training?

      +
        +
      • Currently do instruction, wanting to improve as an instructor and helper when conducting software carpentries.

      • +
      • Planning to start some side hustles providing online courses and why not joining the CR in the near future

      • +
      +
    • +
    • Question 2: How structured or informal are your own teaching needs?

      +
        +
      • More recently, follow software carpentries, but look into what aspects can be tailored to keep to different time slots.

      • +
      • I used to be more informal in the past, repetetive practice sessions. Would like to be more structured given the teaching tools.

      • +
      • I’ve done life-coaching and some teaching but I feel i’m both of them

      • +
      +
    • +
    • Question 3: What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

      +
        +
      • Smaller size, and more targetted.

      • +
      • Collaborative tools and targeted audience working with small groups

      • +
      • Academic probably focuses on an audience with a more focused/narrow background, while this style encompasses a wider audience.

      • +
      • Academic teaching keeps theory and practical lab sessions very separate, whereas carpentries combine both.

      • +
      +
    • +
    • Question 4: What other skills need to be taught, but academic teaching isn’t the right setting?

      +
        +
      • Public speaking, collaborative meeting skills

      • +
      • Industrial cases and related work skills

      • +
      +
    • +
    +
  • +
+
+
+
Episode 3: Co-teaching
+

Materials: https://coderefinery.github.io/train-the-trainer/co-teaching/

+
    +
  • In general: Co-teaching is a beast with at least two personalities each of which

    +
      +
    • demand higher preparation requirements

    • +
    • face remarkable complexity in terms of coteacher coordination

    • +
    • in the virtual component face shortcomings related to the technical equipment and the failure of the human factor

    • +
    +
  • +
+
    +
  • Co-teaching requires the framework of co-operative learning. Team teaching does not by default translate into parallel learning, and vice versa.

  • +
+
    +
  • Re: CodeRefinery in-person beginnings – I agree with the “didn’t work so well in-person”, I’m not sure if it’s that we weren’t as ready for it, or that the different characteristics made it not work so much

  • +
  • How do the downsides compare to a single instructor monologuing?

    +
      +
    • That’s a great question! The main difference is that a single instructor can teach himself to be good (i.e. not just boring monologuing) alone, while for teams of 2+ to work well, everyone needs to be baseline-competent. So the effort to avoid downsides gets reduced if (and only if) all team members share it.

    • +
    +
  • +
+
+

Exercise/Discussion: https://coderefinery.github.io/train-the-trainer/co-teaching/#exercise

+

Questions:

+
    +
  • Have you already tried this or similar model in your teaching?

  • +
  • Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best?

  • +
  • Have you tried or seen a different model for two instructors to present? Please share with us how it works.

  • +
+
+
    +
  • room 1

    +
      +
    • We have tendend to do presenter/interviewer more

    • +
    • challenges are co-teaching with different personalities

    • +
    +
  • +
  • room 2

    +
      +
    • Main challenge: finding enough personell :smile:

    • +
    • It’s not always possible/feasible to have colleagues co-teaching

    • +
    • A combination of both, but presenter and interviewer could be difficult to plan an to follow

    • +
    • Guide and demo-giver with technical / non-technical roles could be nice

      +
        +
      • How to plan the guide and demo-giver

        +
          +
        • First guide, then demo

        • +
        • Demo, then guide describes

        • +
        +
      • +
      +
    • +
    • Alternative model: main presenter + ‘technical expert’

      +
        +
      • main presenter introduces concepts from a birdseye view and passes on to the technical expert for additional details, experiences and answers to questions from the audience

      • +
      +
    • +
    • We frequently do a classical division: on person in presenting, one or more are answering questions in the chat; there is rarely any interaction between them however

    • +
    +
  • +
+
    +
  • As has been pointed out by Paolo Freire, in general, ‘education is suffering from narration sickness’ … ‘The outstanding characteristic of this narrative education, then, is the sonority of words, not their transforming power’. Perhaps one approach could be to rephrase the question after having the answer: It is not apriori about the model implemented, it is about whether that what was implemented was judged aposteriori to have succeeded in becoming, or at least could pretend to have done so, the intended context matched model implementation it probably was computed to be.

  • +
+
    +
  • room 4

    +
      +
    • the co-teaching approach does not seem to be widely practiced

    • +
    • it can be interesting to see “mistakes” which are less likely to happen in solo-teaching?

    • +
    • co-teaching can be nicer for audience but maybe more stress/anxiety for instructors to prepare? more stress in terms of not knowing all the questions in advance. less stress worrying about forgetting something.

    • +
    +
  • +
+
+
+
Teaching gems
+

(scroll up to find the green box “Episode on teaching gems”)

+

What’s your favorite way of teaching? Any nice tools you use?

+

Has anyone found a nice online tool to draw?

+
    +
  • I love this tool suite https://excalideck.com/

    +
      +
    • For drawing https://excalidraw.com/

    • +
    +
  • +
  • I have seen Miro …

  • +
  • I think the Code Refineries use something for their graphics that looks a bit ‘cartoony’ - but I cannot remember what it is called!

    +
      +
    • Drawn on remarkable and then coloured and tidied up in Inkscape. :+1:

    • +
    +
  • +
  • I am a big fan of remarkable. I think sharing option is fairly good. Unfortunately bit expensive tool.

    +
      +
    • true, for me it was worth it already for the pdf annotation for research papers, cannot read on computer screen

    • +
    +
  • +
  • https://webwhiteboard.com/

  • +
  • https://www.youtube.com/watch?v=4-l8MY5kYGc

  • +
  • Figma and Kahoot are useful as well

  • +
+

Screenkey: Screenkey for showing keyboard shortcuts

+
    +
  • Is there a Windows version people can recommend?

    +
      +
    • I found this list of alternative for windows users like me: https://alternativeto.net/software/screenkey/ :+1:

    • +
    +
  • +
  • I sometimes use the on-screen keyboard already provided by the OS :+1:

  • +
+
+
+
+

Wrapup

+
    +
  • Next session Tuesday September 3rd 9 CEST: About teaching & cool things we all would like to share

  • +
  • All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14 CEST

  • +
  • Preparations for next week will be sent out by e-mail

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • The co-teaching lesson and experiences from others

  • +
  • Discussions were quite good, had a nice group

  • +
  • Breakout rooms and collaborative tools

  • +
  • Computational thinking and co-teaching are interesting ideas! I have seen it before, but never knew or even recognized it was a method.

  • +
  • Thanks for group discussions working with my chat only interaction! :smile:

  • +
  • ..

  • +
+

What one thing would you improve about this session?

+
    +
  • Minor point - it would be useful to have the teaching gmes box at the bottom of the document rather than the top - tricky to scroll between! In the end I opened two windows which was easier.

    +
      +
    • Thanks, yes agree. Also had that problem, but did not want to move it in between.

    • +
    +
  • +
  • The meaning of teaching “philosophy” wasn’t very clear, felt more like teaching “styles”

    +
      +
    • Thank you, we will take that into consideration

    • +
    +
  • +
  • Some prepared slides to present for an intro about the topics

    +
      +
    • You mean in addition to the materials? To use in the beginning of each session?

    • +
    +
  • +
  • The instructor views segment could be named as additional material, if it was not meant to be discussed within the course.

    +
      +
    • Thank you, we will take that into consideration

    • +
    +
  • +
+

Any other comments?

+
    +
  • Keeping it short and sweet: If at first you don’t succeed in teaching, try to explain it like you’re talking to a room full of cats. Caveat: In a room full of computational thinkers maybe if you tell students that the brain is a computational device that is forbidden, they might get excited and start using it.

  • +
+
+
+

Day4: Session 4 (3.09.24) - Streaming and video editing

+
+
:calendar: Schedule
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 10.00

Why we stream & Behind the scenes

10.15 - 11.00

8.15 - 9.00

10.00 - 10.15

Break

11.00 - 11.15

9.00 - 9.15

10.15 - 10.35

Video Editing

11.15 - 11.35

9.15 - 9.35

10.35 - 10.55

Exercise: Video Editing

11.35 - 11.55

9.35 - 9.55

10.55 - 11.10

Break

11.55 - 12.10

9.55 - 10.10

11.10 - 11.30

Open Broadcaster Software(OBS) introduction

12.10 - 12.30

10.10 - 10.30

11:30 - 11:50

OBS setup & what next

12.30 - 12.50

10.30 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+
:icecream: Icebreaker
+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :coffee: +

  • +
  • :runner:

  • +
  • :tired_face: Tired!

  • +
  • :nerd_face:

  • +
  • +
  • :cloud: :tea:

  • +
+
+
+
Introduction in breakoutrooms
+
    +
  • Name / Affiliation / Location

  • +
+

What’s the most number of people you have taught to?

+
    +
  • 20 at a time, with 1 asleep, 2 fidgiting with some silly device and the rest were… well… staring at their good luck… straight ahead it was of course, right before them.

  • +
  • ~35

  • +
  • ~80 in a lecture in a previous (lecturer) role, 26 in a training course setting

  • +
  • ~30

  • +
  • ~50 in training spaces and more than 100 for public audience talk

  • +
  • 35 (software carpentry)

  • +
  • CodeRefinery answer: The biggest ones are maybe 200-300 people. “small” for a stream is ~100 people.

  • +
+

What’s the most number of people you have taught with?

+
    +
  • 5 or so

  • +
  • 2 or 3 in total

  • +
  • 3, as in three, none of them smiling. I wish I could figure out why… it was such fun really…

  • +
  • 7

  • +
  • 2 or 3

  • +
  • 3 (helpers, not really co-teaching)

  • +
  • CodeRefinery answer: our biggest workshops are something like 10-20 people helping out in many different roles.

  • +
+

How can you divide teaching into separate independent tasks?

+
    +
  • By content blocks, having roles like main and assistant…

  • +
  • Having responsibility for different sections of the course.

  • +
  • Wow, now thats what we call a question… bravo… indeed, how does one separate sleeping and snoring into separate independent tasks…

  • +
  • Course, exercices, resources, tools and forms.

  • +
  • Different people teach different topics

  • +
  • CodeRefinery answer: the big logical blocks are instructors, in-person and breakout room helpers, and Notes-questions answers.

  • +
+

What’s the most interesting or useful thing you’ve learned from an online workshop, and how have you applied it/planning to apply in your life or work

+
    +
  • Having breaks every hour or so

  • +
  • New approach to screensharing, using the ‘portrait’ approach

  • +
  • Manage breathing: reduce stress and use silence to let the audience grasp what you’re saying

  • +
  • Well, the most interesting or useful thing I’ve learned from online workshops is how not to conduct a workshop, or at least some elements of the same, and I have applied this understanding by engaging in the global effort to discover more about how not to conduct a workshop, or at least some elements of the same, with the motto: That’s one small step for a man, one giant leap for mankind..

  • +
+
+
+
+
:question: Questions
+
+
+
Why we stream
+
    +
  • If during streaming there is no interaction between the teacher and the audience, why don’t we just record the lectures and stream them? So one can do a better job, perhaps?

    +
      +
    • Streaming it making it a “thing” that’s a group experience. It feels good to be a part of it, so we hope that encourages people to actually attend. All the mass Q&A is fun, and the audience helps to make it easier to present. Still, this is a good question.

    • +
    • I really appriciate it being “a thing”. If it was just recorded, I would say I would watch it tomorrow, and then I never would.

      +
        +
      • But then you can just fake it, and still have all the breakout rooms and collaborative document and so on. I appreciate the value of having a proper “event”.

        +
          +
        • I think I follow you, but if you pre-recorded the talking bits, then the presentors couldn’t change what they do based on the feedback in the shared document.

          +
            +
          • true, but I assumed that the teachers were too busy to actually do that. The more (less )division of labor between the teachers and the helpers (or collaborative document editors), the more (less) sense it makes to pre-record - IMHO

          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • What interaction options do ‘streamers’ use, e.g. on Twitch/YouTube (not Code Refinary)?

    +
      +
    • I’m besides chat and things that happen in chat, I’m not sure. The Notes-doc is definitely unique to us.

    • +
    +
  • +
  • Streaming is a kind of exercise for the movie star type. If you cannot be one, act like one, pretend, fool the listener into thinking you are one, take their brains and emotions under control. And if they don’t leave the session with tears of love for learning running down their chubby cheeks you know who to kick for doing a job just that bit worse than it should have been necessary.

  • +
  • Have you kept track of streming stats? like how many people logged in and stayed troughout, how many interacted?

    +
      +
    • Yes please, it would be good to see the stats

    • +
    • Here is stats repo

    • +
    • Thanks, I get a 404 error, is it private?

    • +
    • No, I don’t think so. https://github.com/coderefinery/workshop-stats

    • +
    • Still get 404. Does it work for anyone else?

      +
        +
      • Yeah I think it’s private. We need to fix this…

      • +
      +
    • +
    +
  • +
  • How big is small (10-15), medium (~30-40)?

    +
      +
    • I would say below 50 is small.

    • +
    +
  • +
  • Have you considered scaling to more events instead of to a larger audience? I mean, this seems the opposite of scaling, but this kind of content would be more useful the more often is it taught (“I need to learn GIT/Python/* in December!”)

    +
      +
    • We would, but right now we simply don’t have enough time and people to do more small events. But yes, “scheduling conflict” is a big problem - the best we can do right now is written material+videos to follow up on (and hope it’s interesting enough)

    • +
    • Python for Scientific Computing 5-7/November/2024

      +
        +
      • This was just an example. I mean, if I am a PHD student that needs to start working on a topic on Month X which happens to be inconveniently placed in the year, I will not benefit as much from having a workshop at Month X+3

        +
          +
        • The materials are open and the videos are publically available on YouTube channel

          +
            +
          • What’s the ratio of people watching videos afterwards vs people attending the event? That ratio can give an idea of the popularity of the two possible approaches.

          • +
          +
        • +
        +
      • +
      +
    • +
    • The more you scale up the less interactive the course / workshop will need to be. It then becomes a question of priorities, and if teaching is a lower priority then learning than I guess there really should be no prizes for guessing which approach should reign the airwaves.

    • +
    +
  • +
  • I guess outside Europe / Africa, time zones could be a problem?

    +
      +
    • yes, that is true

    • +
    • +
    +
  • +
  • Sorry, I might have missed this: have you been rehearsing and/or doing dry runs?

    +
      +
    • With instructors I like to try to do a dry run. I often don’t do a live broadcast dry run these days since I’m confidente enough, but when you are just starting, it’s a good idea.

    • +
    +
  • +
  • Do you always use Zoom for the ‘presenter end’ or have you tried other things? Teams? Jitsi? etc.?

    +
      +
    • we use mostly zoom

    • +
    • It was first pioneered using Jitsi. You can probably use others, too.

    • +
    +
  • +
  • A comment: for deRSE24 we have been using the GWDG streaming service and OBS, it worked quite well (with a 20s delay or so)

    +
      +
    • Cool! Yes, there is plenty of livestreaming options. Twitch+our OBS config gives us 2-3s of latency (which is low enough for live Notes interaction). You might be able to tune this if needed.

    • +
    +
  • +
+
+
+
Behind the stream
+
    +
  • Does OBS take a lot of RAM or CPU? what are the specs on your machine?

    +
      +
    • Richard have a relatively powerful computer with 8 AMD CPUs.

    • +
    • 4 CPUs are relatively enough for a good OBS setup, most important is a stable internet connection (ideally wired).

    • +
    • An extra monitor is recommended for the setup

    • +
    • See the hardware notesrecommendation here

    • +
    +
  • +
  • Do you do a screenshare from Zoom -> OBS or OBS -> Zoom?

    +
      +
    • Instructors share to Zoom, OBS captures Zoom, OBS sends to the world.

    • +
    • When I am using OBS sfor a single-person presentation recording, I go the other way: OBS captures my desktop/camera, OBS generates the preview window, and then Zoom captures and broadcasts the preview window.

    • +
    +
  • +
+
+
+
Video editing
+
+
Poll
+
    +
  • Have you tried video editing? Add ano as answer below

    +
      +
    • yes: ooooo

    • +
    • no :

    • +
    • Video editing makes all the difference. I have never known a way to avoid this sacred of steps, so to speak. In short, no recording can ever be production ready by default in the books of the wiser among the streamers. In fact, during the editing one can considerably refine and improve the learning experience in great ways. But then one would need to invest both time and effort.

    • +
    +
  • +
  • If yes Which are the tools you use?

    +
      +
    • Windows Movie Maker / ClipChamp

    • +
    • (raw stream from Zoom)

    • +
    • I think it was shotcut - I did only basic trimming

    • +
    • Kdenlive

    • +
    • Clipchamp, OpenShot, Sony Vegas

    • +
    • also ffmpeg from command line to cut beginning and end

    • +
    +
  • +
+
+
+
Questions
+
    +
  • What is Whisper?

    +
      +
    • Open-source model from OpenAI that converts speech to text transcripts.

    • +
    • this one? https://openai.com/index/whisper/

    • +
    • curious if anyone has tried it with languages other than english

    • +
    • I heard that one of my spanish colleague try it with another software. I don’t remember the tool. But with AI bloom there are many licensed tools that can do it with fifferent language

    • +
    +
  • +
  • What do you use to crop the videos?

    +
      +
    • I see now, ffmpeg

    • +
    +
  • +
  • how to merge multiple parts in one? I asked because you edited only the icebreaker part?

    +
      +
    • you can manage it in input part, see ffmpeg-editlist readme.

    • +
    +
  • +
  • Do you generate custom thumbnails for the video?

    +
      +
    • no, because of the time, but its good to have. If we had a volunteer to manage that, then we should!

    • +
    +
  • +
  • Does anyone recommend any other (GUI) tools that work well? ffmpeg is very new to me!

    +
      +
    • if you want a basic trimming and editing , you can use Quicktime player/imovies on mac

    • +
    • Clipchamp as the Microsoft video editor

    • +
    • Thanks :smile:

    • +
    +
  • +
  • How do subtitles get uploaded to YouTube?

    +
      +
    • You upload the video and subtitles as part of upload.

    • +
    • :+1:

    • +
    +
  • +
  • How does codewhisperer compare against youtube’s automatically generated subtitles?

    +
      +
    • by experience, whisper was better couple of years ago. We haven’t compared it recently

    • +
    • I guess and advantage is that you can edit whisper subtitles in case something is odd or whatever, probs cannot do that in YouTube

    • +
    +
  • +
+
+
+
+
Open Broadcaster Software (OBS) introduction & setup
+
    +
  • Are the profiles public?

    +
      +
    • Yes, you can see it here

    • +
    +
  • +
  • Does it work in Linux+Wayland?

    +
      +
    • I think everything we do with OBS would.

    • +
    +
  • +
+
+
+
+

Wrapup

+ +
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • ffmpeg seems great, will give a try for fun!

  • +
  • great to see everything in practice!

  • +
  • Very insightful to see what happens behind the scenes.

  • +
+

What one thing would you improve about this session?

+
    +
  • Some more interactivity would’ve been nice but since most the group preferred demo instead of exercise perhaps it’s only a personal opinion

  • +
  • It would have been good to share the OBS profiles repo beforehand in the setup email - so I could have had it to hand. (https://github.com/coderefinery/obs-config)

    +
      +
    • +1 good idea, we should do this next time

    • +
    +
  • +
  • Perhaps a simpler starter OBS setup?

    +
      +
    • Good idea… I should have, but basically ran out of time to prepare.

    • +
    +
  • +
+

Any other comments?

+
    +
  • Cool to see the switch from RSE to trainer to AV guy, impressive!

  • +
+
+
+
+
+

Instructor guide

+
+

Target audience

+
    +
  • Everyone teaching online workshops about computational topics or interested in teaching.

  • +
  • Previous and future instructors and helpers of CodeRefinery workshops.

  • +
+
+
+

Timing

+

Session 1

+
    +
  • 15 min: Intro

  • +
  • 45 min: Lesson design and development

  • +
  • 15 min: Break

  • +
  • 45 min: Lesson template

  • +
  • 15 min: Break

  • +
  • 30 min: How we collect feedback and measure impact

  • +
  • 10 min: Outro and feedback

  • +
+

Session 2

+
    +
  • 15 min: Intro

  • +
  • 10 min: About the CodeRefinery project and CodeRefinery workshops in general

  • +
  • 30 min: Collaborative notes and interaction

  • +
  • 15 min: Break

  • +
  • 35 min: Workshop overview, roles, onboarding/installation, helpers

  • +
  • 20 min: Sound

  • +
  • 15 min: Break

  • +
  • 30 min: Screenshare

  • +
  • 10 min: Outro and feedback

  • +
+

Session 3

+
    +
  • 15 min: Intro

  • +
  • 30 min: Computational thinking

  • +
  • 15 min: Break

  • +
  • 30 min: Teaching philosohies

  • +
  • 30 min: Co-teaching

  • +
  • 15 min: Break

  • +
  • 35 min: Sharing teaching tips, tricks, tools etc

  • +
  • 10 min: Outro and feedback

  • +
+

Session 4

+
    +
  • 15 min: Intro

  • +
  • 10 min: Why we stream

  • +
  • 20 min: Behind the stream

  • +
  • 15 min: Video editing (part 1)

  • +
  • 15 min: Break

  • +
  • 25 min: Video editing (part 2, exercise)

  • +
  • 20 min: OBS introduction

  • +
  • 15 min: Break

  • +
  • 30 min: OBS setup

  • +
  • 15 min: What’s next?

  • +
+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright CodeRefinery project.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/singlehtml/objects.inv b/branch/cff/singlehtml/objects.inv new file mode 100644 index 0000000..e7d370e Binary files /dev/null and b/branch/cff/singlehtml/objects.inv differ diff --git a/branch/cff/sound/index.html b/branch/cff/sound/index.html new file mode 100644 index 0000000..040b61f --- /dev/null +++ b/branch/cff/sound/index.html @@ -0,0 +1,366 @@ + + + + + + + Sound — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Sound

+
+

Objectives

+
    +
  • Understand that sound quality is very important

  • +
  • Evaluate your and others sound quality and know how to improve it

  • +
  • Test tips and tricks for achieving good sound quality

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Exercises: 10 min

  • +
+
+
+

The importance of audio

+
    +
  • Pleasing audio quality makes events much more enjoyable

  • +
  • Audio is one of the most important things you can control

  • +
  • Things that can go wrong:

    +
      +
    • Too quiet

    • +
    • Too loud

    • +
    • Instructors’ volumes imbalanced

    • +
    • Background noise

    • +
    • Low-quality/breaking up audio hard to hear.

    • +
    • “Ducking” (first words lower volume, or lower volume other times)

    • +
    +
  • +
+
+
+

Tips for good sound quality

+
    +
  • Have a headset with mounted microphone

    +
      +
    • Even if you have a professional external microphone, it doesn’t +matter if your room has bad acoustics.

    • +
    • The close pickup can’t be beat with normal tools.

    • +
    • As long as it’s headset mounted, price doesn’t seem to matter +that much.

    • +
    +
  • +
  • Don’t use Bluetooth

    +
      +
    • Bluetooth can have too much latency (300-500ms)

    • +
    • This may seem small but for interactive work, it’s a lot

    • +
    • Use a wired headset, or wireless with a non-Bluetooth USB plug +(like gaming headsets have). These have much lower latency.

    • +
    • Bluetooth 5 can have much lower latency, but you probably +shouldn’t count on that without testing.

    • +
    • It can also have lower sound quality on some devices due to +bandwidth limitations.

    • +
    +
  • +
  • Once you have a headset, turn input noise cancellation to low +(wherever it might be: headphone, meeting software, etc.).

  • +
+
+
+

Balancing and dynamic adjustment

+
    +
  • It’s important that instructors volumes match.

  • +
  • An exercise will go over a systematic procedure for matching +volumes.

    +
      +
    • Practice so that you can do this quickly.

    • +
    +
  • +
  • May need re-adjusting when instructors swap out or start getting +excited.

  • +
  • An exercise below will demonstrate our procedure.

  • +
+
+
+

Speak up when there are problems

+
    +
  • If you notice someone with audio issues, let them know right away +(voice if bad, or chat/notes if less urgent).

  • +
  • Take the time to fix it as soon as practical.

  • +
  • Make a culture of speaking up, helping, and not suffering.

  • +
+
+
+

Recommendations

+
    +
  • Procure some reasonable headset.

  • +
  • Low/medium-priced gaming-type headsets have worked well for us.

    +
      +
    • (gaming headsets usually aren’t Bluetooth, because gaming needs +low latency.)

    • +
    +
  • +
  • Show this page to your workplace (if you have one) and call a good +headset work equipment.

  • +
+
+
+

Exercises

+
+

Sound-1: Evaluate sound quality

+

It’s important to be able to discuss with others the quality of their +audio. They can’t hear themselves, after all.

+
    +
  • Within the teams, discuss each person’s audio quality and what kind +of setup they have.

  • +
  • Be respectful and constructive (and realize that people came +prepared to listen, not teach).

  • +
  • Consider, for example

    +
      +
    • Volume

    • +
    • Clarity

    • +
    • Background noise

    • +
    • Noise cancellation artifacts

    • +
    • “Ducking”: first words at lower volume or missing

    • +
    +
  • +
  • Discuss how to bring this up during other courses and meetings.

  • +
+
+
+

Sound-2: Adjust volume up and down

+

In addition to individual quality, it is important that sound is +balanced among all instructors. Have you ever been to a event when +one person is too quiet and they can’t make themselves any louder? +And they can’t adjust it?

+

You should ensure that you have a range of volumes available to you. +You might have to look into several different locations in order to +make the full adjustment ().

+
    +
  • Go to your sound settings

  • +
  • One by one, each person

    +
      +
    • Adjusts their microphone volume so quiet that they can’t be heard.

    • +
    • Adjusts their microphone volume so that it is extremely loud (this +may require going beyond 100% if possible).

    • +
    +
  • +
  • Basically, make sure you aren’t so close to either end that you have +no potential to make an adjustment in that direction.

  • +
  • Everyone tries to set the volume to something reasonable, in +preparation for the next exercise.

  • +
+

Once you know where these settings are , you won’t be panicked when the +volume is too low or high during a course.

+
+
+

Sound-3: Do a balance check

+

It’s important that instructor audio is balanced (the same volume). +But how can you do this?

+
    +
  • Pick a leader.

  • +
  • The leader decides the order (“I am first, then [name-1] and +[name-2]”)

  • +
  • The leader says “one”. Everyone else says “one” in the order +specified.

  • +
  • The leader says “two”. Everyone else says “two” in the order.

  • +
  • The leader asks for opinions on who they think is louder or softer. +If there are more than three people, you can figure it out +yourselves. With less than two, you have to ask someone in the +audience.

  • +
+

Example:

+
    +
  • Leader: Let’s do a sound check. I am first, then AAA and BBB.

  • +
  • Leader: One

  • +
  • AAA: One

  • +
  • BBB: One

  • +
  • Leader: Two

  • +
  • AAA: Two

  • +
  • BBB: Two

  • +
  • Leader: Three

  • +
  • AAA: Three

  • +
  • BBB: Three

  • +
  • Leader: How did that sound to everyone?

  • +
  • [Someone else]: Leader and BBB were pretty similar but AAA is a bit +lower.

  • +
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Audio quality is important and one of the most notable parts of the +workshop.

  • +
  • Improving audio isn’t hard or expensive, but does require preparation.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/streaming-whats-next/index.html b/branch/cff/streaming-whats-next/index.html new file mode 100644 index 0000000..916e18c --- /dev/null +++ b/branch/cff/streaming-whats-next/index.html @@ -0,0 +1,202 @@ + + + + + + + What’s next? — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

What’s next?

+
+

Objectives

+
    +
  • Know next steps if you want to do streaming

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 5 min

  • +
  • Q&A 5 min

  • +
+
+

What comes next?

+
    +
  • We talked a lot about theory, and gave demonstrations.

  • +
  • Hands-on is very different. We recommend working with someone to +put it in practice.

  • +
  • +
+
    +
  • Work with someone who can show you the way

  • +
  • Use it for smaller courses with a backup plan

  • +
+
+

See also

+
+

Keypoints

+
    +
  • These lessons about streaming have been the theoretical part of +streaming training.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/streaming/index.html b/branch/cff/streaming/index.html new file mode 100644 index 0000000..54c786f --- /dev/null +++ b/branch/cff/streaming/index.html @@ -0,0 +1,274 @@ + + + + + + + Behind the stream — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Behind the stream

+
+

Objectives

+
    +
  • Take a first look at the broadcaster’s view.

  • +
  • Get to know what happens “behind the stream” of a workshop

  • +
  • See what the “broadcaster” sees and what they need to do.

  • +
  • Not yet: learn details of how to do this.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Q&A 10 min

  • +
+
+

In this episode, you’ll see an end-to-end view of streaming from the +broadcaster’s point of view. It’s a tour but not an explanation or +tutorial.

+
+

Who does what

+

We have certain role definitions:

+
    +
  • Broadcaster: Our term for the person who manages the streaming.

  • +
  • Director: Person who is guiding the instructors to their +sessions, changing the scenes, calling the breaks, etc.

    +
      +
    • Could be the same as broadcaster.

    • +
    +
  • +
  • Instructor: One who is teaching. They don’t have to know +anything else about how streaming works.

  • +
+

This lesson describes what the Broadcaster/Director sees.

+
+
+

Window layouts

+

What does the broadcaster see on their screen?

+
    +
  • What are the main windows you see?

  • +
  • What do each of them do?

  • +
  • Which ones do you need to focus on?

  • +
  • How do you keep all this straight in your head?

  • +
+
+
+

CodeRefinery control panel

+
    +
  • A custom application that controls scenes

  • +
  • Based on OBS-websocket (remote control connection for OBS - we’ll +learn about this later)

  • +
  • Can also work remotely, so that you can have a remote director

  • +
+
+
+

How scenes are controlled

+

What has to be done during a course?

+
    +
  • How do you start the stream?

  • +
  • How do you change the view?

  • +
  • How do you adjust things based on what the instructors share?

  • +
  • How do you coordinate with the instructors?

  • +
  • How do you know when to change the view?

  • +
+
+
+

Getting it set up

+
    +
  • How hard was it to figure this out?

  • +
  • How hard is it to set it up for each new workshop?

  • +
+
+
+

What can go wrong

+
    +
  • What’s the worst that has happened?

  • +
  • What if you need to walk away for a bit?

  • +
  • Someone broadcasts something unexpectedly

  • +
+
+
+

Alternatives

+
    +
  • Youtube vs Twitch

  • +
  • Zoom stream directly to YouTube/Twitch

  • +
  • Direct streaming platform, e.g. streamyard

  • +
+
+
+

Q&A

+

Q&A from audience

+
+

Keypoints

+
    +
  • The broadcaster’s view shouldn’t be so scary.

  • +
  • There is a lot to manage, but each individual part isn’t that hard.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/teaching-philosophies/index.html b/branch/cff/teaching-philosophies/index.html new file mode 100644 index 0000000..155b81a --- /dev/null +++ b/branch/cff/teaching-philosophies/index.html @@ -0,0 +1,314 @@ + + + + + + + CodeRefinery teaching philosophies — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CodeRefinery teaching philosophies

+
+

Objectives

+
    +
  • Get to know the teaching philosophies of CodeRefinery instructors

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Discussion: 20 min

  • +
+
+
+

Introduction

+

During this episode we split into breakoutrooms and discuss own teaching philosophies. +Collect your teaching philosophies in the collaborative document. We will be going through +these and the end of the lesson.

+
+

Ice-breaker in groups (20 minutes)

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+
+

Instructor views

+

Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops.

+

It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us.

+
+

Video recordings

+

We have recorded some of the below as videos: https://www.youtube.com/playlist?list=PLpLblYHCzJAAHF89P-GCjEXWC8CF-7nhX

+
+
+

Bjørn Lindi

+

My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this “BLOB” (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the “BLOB”, to be able to share it with others.

+

In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic.

+

When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson.

+

Tools that I find useful in preparing a lesson is concept maps and Learner Personas (though I have developed too few of them):

+ +
+
+

Radovan Bast

+

My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos.

+

My goal for a lesson is to spark curiosity to try things after the lesson, both +for the novices (“This looks like a useful tool, I want to try using it after +the workshop.”) and the more experienced participants (“Aha - I did not know +you could do this. I wonder whether I can make it work with X.”). I like to +start lessons with a question because this makes participants look up from +their browsers.

+

Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise.

+

For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate the +answer.

+

I try to avoid jargon and “war stories” from the professional developers’ +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid “customer”, +“production”, also a lot of Agile jargon is hard to relate to.

+

Less and clear is better than more and unclear. Simple examples are better than +complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +“simply”, “just”, “easy”. If participants take home one or two points from a +lesson, that’s for me success.

+

I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don’t want to be +surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or slide. +This allows me to skip and distill the essence and not read bullet point by +bullet point.

+

I try to never deviate from the script and if I do, be very explicit about it.

+

A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel listening to me.

+

I very much like the co-teaching approach where the other person helps +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson.

+
+
+

Sabry Razick

+

My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case.

+
+
+

Richard Darst

+

Like many people, I’ve often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I’ve realized long ago that my most important lessons weren’t +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I’ve realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds.

+

My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I’m often start at the +very basics, because this is what I see missing most often.

+

When teaching, I like lots of audience questions and don’t mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don’t have to know everything perfectly, just show how +you’d approach a problem.

+
+
+

Stepas Toliautas

+

I aim for my learners to understand things (concepts, techniques…), instead of just memorizing them. The phrase I use from time to time when teaching information technology topics (be it hardware or software) is “there is no magic”: everything can be explained if necessary. While CodeRefinery also emphasizes usefulness/ immediate applicability of the content, often having the correct notions actually helps to start using them sooner and with less mistakes.

+

I try to guide my audience through the presented material with occasional questions related to previous topics and common knowledge – to help them link the concepts already during the lesson. I’m also fully aware that waiting for someone to answer is quite uncomfortable in-person and doubly so in an online environment, especially if no one uses their cameras :)

+

And if I get the question I don’t have the answer for (or material to show it) at the moment, in university classes I prepare and come back to it next time. While with one-off workshops there might not be a “next time”, open-source material used by CodeRefinery allows to have the same outcome: the latest and greatest version stays available for self-study afterwards.

+
+
+
+

Summary

+
+

Keypoints

+
    +
  • People have different viewpoints on teaching.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/video-editing/index.html b/branch/cff/video-editing/index.html new file mode 100644 index 0000000..bdf96d4 --- /dev/null +++ b/branch/cff/video-editing/index.html @@ -0,0 +1,606 @@ + + + + + + + Video editing — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Video editing

+
+

Objectives

+
    +
  • Get to know ways of quick video editing to be able to provide +accessible videos

  • +
  • Learn how video editing can be distributed and done the same day.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 20 min

  • +
+
+

Video recordings could be useful for people watching later, +but also are (perhaps more) useful for immediate review and catching +up after missing a day in a workshop. For this, they need to be +released immediately, within a few hours of the workshop. +CodeRefinery does this, and you can too.

+

Hypothesis: videos must be processed the same evening as they were +recorded, otherwise (it may never happen) or (it’s too late to be +useful). To do that, we have to make processing good enough (not +perfect) and fast and the work distributeable.

+
+

Primary articles

+ +
+
+

How this relates to streaming

+
    +
  • If you stream, then the audience can not appear in the recorded +videos

  • +
  • This allows you to release videos very quickly if you have the +right tools.

  • +
  • When you have a large audience, the videos start helping more +(review a missed day, catch up later, review later)

  • +
  • Thus

    +
      +
    • If you would never want videos, there may never be a benefit to +streaming

    • +
    • If you want videos, it gives motivation to stream.

    • +
    +
  • +
+
+
+

Summary

+
    +
  • Basic principle: privacy is more important than any other factor. +If we can’t guarantee privacy, we can’t release videos at all.

    +
      +
    • Disclaimers such as “if you don’t want to appear in a recording, +leave your video off and don’t say anything”, since a) accidents +happen especially when coming back from breakout rooms. b) it +creates an incentive to not interact or participate in the course.

    • +
    +
  • +
  • Livestreaming is important here: by separating the instruction from +the audience audio/video, there is no privacy risk in the raw +recording. They could be released or shared unprocessed.

  • +
  • Our overall priorities

    +
      +
    1. No learner (or anyone not staff) video, audio, names, etc. are +present in the recordings.

    2. +
    3. Good descriptions.

    4. +
    5. Removing breaks and other dead time.

    6. +
    7. Splitting videos into useful chunks (e.g. per-episode), perhaps +equal with the next one:

    8. +
    9. Good Table of Contents information so learners can jump to the +right spots (this also helps with “good description”.)

    10. +
    +
  • +
  • ffmpeg-editlist +allows us to define an edit in a text file (crowdsourceable on +Github), and then generate videos very quickly.

  • +
+
+
+

How we do it

+

The full explanation is in the form of the exercises below. As a +summary:

+
    +
  • Record raw video (if from a stream, audience can’t possibly be in +it)

  • +
  • Run Whisper to get good-enough subtitles. Distribute to someone for +checking and improving.

  • +
  • Define the editing steps (which segments become which videos and +their descriptions) in a YAML file.

  • +
  • Run ffmpeg-editlist, which takes combines the previous three steps +into final videos.

  • +
+
+
+

Exercises

+
+

Exercise A

+

These exercises will take you through the whole sequence.

+
+

Editing-1: Get your sample video

+

Download a sample video:

+ +
+

Editing-2: Run Whisper to generate raw subtitles and test video.

+

First off, install Whisper and generate the base subtitles, based +on the. Since this is probably too much to expect for a short +lesson, they are provided for you (above), but if you want you can +try using Whisper, or generating the subtitles some other way.

+

You can start generating subtitles now, while you do the next +steps, so that they are ready by the time you are ready to apply +the editlist. ffmpeg-editlist can also slice up the subtitles from +the main video to make subtitles for each segment you cut out.

+

Whisper is left as an exercise to the reader.

+ +
+
+
+

Editing-3: Create the basic editlist.yaml file

+

Install +ffmpeg-editlist and +try to follow its instructions, to create an edit with these features:

+
    +
  • The input definition.

  • +
  • Two output sections: the “Intro to the course”, and “From data +storage to your science” talks (Remember it said the recording +started at 11:35… look at the schedule for hints on when it +might start!). This should have a start/end timestamp from the +original video.

  • +
+

A basic example:

+
- input: day1-raw.mkv
+
+# This is the output from one section.  Your result should have two of these sections.
+- output: part1.mkv
+  title: something
+  description: >-
+    some long
+    description of the
+    segment
+  editlist:
+    - start: 10:00    # start timestamp of the section, in *original* video
+    - end: 20:00      # end timestamp of the section, in the *original* video
+
+
+ +
+
+

Discussion: what makes a video easy to edit?

+
    +
  • Clear speaking and have high audio quality.

  • +
  • For subtitle generation: Separate sentences cleanly, otherwise it +gets in a “stream of words” instead of “punctuated sentences” +mode.

  • +
  • Clearly screen-sharing the place you are at, including section +name.

  • +
  • Clear transitions, “OK, now let’s move on to the next lesson, +LESSON-NAME. Going back to the main page, we see it here.”

  • +
  • Clearly indicate where the transitions are

  • +
  • Hover mouse cursor over the area you are currently talking about.

  • +
  • Scroll screen when you move on to a new topic.

  • +
  • Accurate course webpage and sticking to the schedule

  • +
+

All of these are also good for learners. By editing videos, you +become an advocate for good teaching overall.

+
+
+

Editing-4: Run ffmpeg-editlist

+

Install ffmpeg-editlist: pip install ffmpeg-editlist[srt] (you +may want to use a virtual environment, but these are very minimal +dependencies).

+

The ffmpeg command line tool must be available in your +PATH.

+ +
+
+

Editing-5: Add more features

+
    +
  • Several chapter definitions.(re-run and you should see a +.info.txt file also generated). Video chapter definitions +are timestamps of the original video, that get translated to +timestamps of the output video.

    +
    - output: part1.mkv
    +  editlist:
    +  - start: 10:00
    +  - -: Introduction    #  <-- New, `-` means "at start time"
    +  - 10:45: Part 1      #  <-- New
    +  - 15:00: Part 2      #  <-- New
    +  - end: 20:00
    +
    +
    +

    Look at the .info.txt files that come out now. What is new in it?

    +
  • +
  • Add in “workshop title”, “workshop description”, and see the +.info.txt files that come out now. This is ready for +copy-pasting into a YouTube description (first line is the title, +rest is the description).

    +

    Look at the new .info.txt files. What is new?

    +
  • +
+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+
+
+

Editing-7: Generate the final output file.

+
    +
  • Run ffmpeg-editlist with the --reencode option: this +re-encodes the video and makes sure that there is no black point +at the start.

  • +
  • If you re-run with --check, it won’t output a new video file, +but it will re-output the .info.txt and .srt files. +This is useful when you adjust descriptions or chapters.

  • +
+
+
+

Discussion: how to distribute this?

+

Create a flowchat of all the parts that need to be done, and which +parts can be done in parallel. Don’t forget things that you might +need to do before the workshop starts.

+

How hard was this editing? Was it worth it?

+
+
+
+

Exercise B

+

This is a more limited (and older) version of the above exercise, +using an synthetic example video.

+
+

Use ffmpeg-editlist to edit this sample video

+

Prerequisites: ffmpeg must be installed on your computer +outside of Python. Be able to install ffmpeg-editlist. This is +simple in a Python virtual environment, but if not the only +dependency is PyYAML.

+ + +
+
+
+
+

See also

+ +
+

Keypoints

+
    +
  • Video editing is very useful for learning

  • +
  • Set your time budget and make it good enough in that time

  • +
  • Reviewing videos improves your teaching, too.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/cff/why-we-stream/index.html b/branch/cff/why-we-stream/index.html new file mode 100644 index 0000000..666d0cf --- /dev/null +++ b/branch/cff/why-we-stream/index.html @@ -0,0 +1,298 @@ + + + + + + + Why we stream — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Why we stream

+
+

Objectives

+
    +
  • Learn the general history of CodeRefinery streaming.

  • +
  • Discuss the benefits of streaming and recording

  • +
  • Discuss the downsides and difficulties

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 10 min

  • +
  • Q&A: 5 min

  • +
  • Exercises: 0 min

  • +
+
+

This is a general discussion of the topics of the day, focused on the +history of why we stream and record, how we got here, and how people +feel about it. We won’t focus on how anything is done.

+
+

Icebreaker questions

+
    +
  • What is the most people you have taught for?

  • +
  • What are the distinct parts of teaching, that can be +separated? (teaching, helping, etc)

  • +
+
+
+

What is streaming and recording?

+
    +
  • Streaming is mass communication: one to many

    +
      +
    • Interaction audience→presenters is more limited (but different)

    • +
    +
  • +
  • Using consumer-grade tools, normal people can reach huge audiences +by Twitch/YouTube/etc.

  • +
  • This isn’t actually that hard: people with much less training than +us do it all the time.

  • +
  • They reach huge audiences and maintain engagement for long events.

  • +
+

Recording and rapid video editing is useful even without +streaming.

+
+
+

History

+
    +
  • In-person workshops

    +
      +
    • 3 × full day, required travel, infrequent, one-shot

    • +
    +
  • +
  • Covid and remote teaching

    +
      +
    • Traditional “Zoom” teaching several times

    • +
    +
  • +
  • Mega-CodeRefinery workshop

    +
      +
    • 100-person Zoom teaching

    • +
    • Emphasis on teams

    • +
    +
  • +
  • Research Software Hour

    +
      +
    • Livestream free-form discussions on Twitch

    • +
    +
  • +
  • Streamed “HPC Kickstart” courses

  • +
+
+
+

Benefits and disadvantages

+

Benefits:

+
    +
  • Larger size gives more (but different) interaction possibility

    +
      +
    • “Notes” for async Q&A

    • +
    +
  • +
  • Recording (with no privacy risk) allows instant reviews

  • +
  • Stream-scale allows for many of the things you have learned about in +days 1-3.

  • +
+

Disadvantages:

+
    +
  • Requires training for using the tools

  • +
  • Requires a certain scale to be worth it

  • +
  • Coordination is much harder for big events

  • +
+

When would I recommend it?

+
    +
  • No: For small courses

  • +
  • Questionable: Medium sized courses with no videos

  • +
  • Yes: When you want the largest audience

  • +
  • Yes: When you want without registration required

  • +
  • Yes: When you want good reusability/fast videos

  • +
+
+
+

Future prospects (briefly)

+
    +
  • Streaming probably stays as a CodeRefinery tool

  • +
  • We can scale our courses much larger than they are now. Why don’t +we, together with others?

  • +
  • These tools are useful in other places too

    +
      +
    • I’ve used them to record my own talks to make videos of my +single-person presentations or record conference talks nicer than Zoom.

    • +
    +
  • +
+
+
+

Q&A

+

Q&A from audience

+
+

Keypoints

+
    +
  • Streaming optimizes a course for different things

  • +
  • The disadvantages can be compensated for

  • +
  • There are benefits and disadvantages

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/_images/BYOC.png b/branch/comms/_images/BYOC.png new file mode 100644 index 0000000..94702a1 Binary files /dev/null and b/branch/comms/_images/BYOC.png differ diff --git a/branch/comms/_images/CR_workshop_setup.png b/branch/comms/_images/CR_workshop_setup.png new file mode 100644 index 0000000..47b4502 Binary files /dev/null and b/branch/comms/_images/CR_workshop_setup.png differ diff --git a/branch/comms/_images/community.png b/branch/comms/_images/community.png new file mode 100644 index 0000000..ddd9a62 Binary files /dev/null and b/branch/comms/_images/community.png differ diff --git a/branch/comms/_images/hackmd--controls.png b/branch/comms/_images/hackmd--controls.png new file mode 100644 index 0000000..46a74c7 Binary files /dev/null and b/branch/comms/_images/hackmd--controls.png differ diff --git a/branch/comms/_images/hackmd--full-demo.png b/branch/comms/_images/hackmd--full-demo.png new file mode 100644 index 0000000..0988b6f Binary files /dev/null and b/branch/comms/_images/hackmd--full-demo.png differ diff --git a/branch/comms/_images/hackmd--questions2.png b/branch/comms/_images/hackmd--questions2.png new file mode 100644 index 0000000..a609199 Binary files /dev/null and b/branch/comms/_images/hackmd--questions2.png differ diff --git a/branch/comms/_images/history-landscape-dark.png b/branch/comms/_images/history-landscape-dark.png new file mode 100644 index 0000000..a1aef3c Binary files /dev/null and b/branch/comms/_images/history-landscape-dark.png differ diff --git a/branch/comms/_images/history-portrait-dark.png b/branch/comms/_images/history-portrait-dark.png new file mode 100644 index 0000000..2fc1fa6 Binary files /dev/null and b/branch/comms/_images/history-portrait-dark.png differ diff --git a/branch/comms/_images/history-portrait-light.png b/branch/comms/_images/history-portrait-light.png new file mode 100644 index 0000000..5f4361c Binary files /dev/null and b/branch/comms/_images/history-portrait-light.png differ diff --git a/branch/comms/_images/history-portrait.png b/branch/comms/_images/history-portrait.png new file mode 100644 index 0000000..28e18b0 Binary files /dev/null and b/branch/comms/_images/history-portrait.png differ diff --git a/branch/comms/_images/history-rsh.png b/branch/comms/_images/history-rsh.png new file mode 100644 index 0000000..1bbb1cc Binary files /dev/null and b/branch/comms/_images/history-rsh.png differ diff --git a/branch/comms/_images/instructor.png b/branch/comms/_images/instructor.png new file mode 100644 index 0000000..718f2a8 Binary files /dev/null and b/branch/comms/_images/instructor.png differ diff --git a/branch/comms/_images/landscape.png b/branch/comms/_images/landscape.png new file mode 100644 index 0000000..eda9d42 Binary files /dev/null and b/branch/comms/_images/landscape.png differ diff --git a/branch/comms/_images/learner-large.png b/branch/comms/_images/learner-large.png new file mode 100644 index 0000000..3b6d2cd Binary files /dev/null and b/branch/comms/_images/learner-large.png differ diff --git a/branch/comms/_images/learner-normal.png b/branch/comms/_images/learner-normal.png new file mode 100644 index 0000000..590135e Binary files /dev/null and b/branch/comms/_images/learner-normal.png differ diff --git a/branch/comms/_images/learner-small.png b/branch/comms/_images/learner-small.png new file mode 100644 index 0000000..5d5f421 Binary files /dev/null and b/branch/comms/_images/learner-small.png differ diff --git a/branch/comms/_images/portrait.png b/branch/comms/_images/portrait.png new file mode 100644 index 0000000..415799f Binary files /dev/null and b/branch/comms/_images/portrait.png differ diff --git a/branch/comms/_images/steps.png b/branch/comms/_images/steps.png new file mode 100644 index 0000000..6c978b5 Binary files /dev/null and b/branch/comms/_images/steps.png differ diff --git a/branch/comms/_images/survey-impact1.png b/branch/comms/_images/survey-impact1.png new file mode 100644 index 0000000..7dd0ddc Binary files /dev/null and b/branch/comms/_images/survey-impact1.png differ diff --git a/branch/comms/_images/survey-impact2.png b/branch/comms/_images/survey-impact2.png new file mode 100644 index 0000000..8771bff Binary files /dev/null and b/branch/comms/_images/survey-impact2.png differ diff --git a/branch/comms/_images/welcome.png b/branch/comms/_images/welcome.png new file mode 100644 index 0000000..302082c Binary files /dev/null and b/branch/comms/_images/welcome.png differ diff --git a/branch/comms/_sources/co-teaching.md.txt b/branch/comms/_sources/co-teaching.md.txt new file mode 100644 index 0000000..c197f10 --- /dev/null +++ b/branch/comms/_sources/co-teaching.md.txt @@ -0,0 +1,110 @@ +(co-teaching)= + +# Co-teaching + +:::{objectives} +- Get to know the principle of co-teaching: How we do it and how you can too. +- Learn the team teaching concept and how to tailor it to your situation. +::: + +:::{instructor-note} +- Teaching: 15 min +- Exercises: 10 min +- Discussion: 5 min +::: + + +## Overview + +CodeRefinery lessons benefit from the application of the concepts of **co-teaching**. + +:::{admonition} Co-teaching +[Co-teaching](https://en.wikipedia.org/wiki/Co-teaching) can be defined as "the division of labor between educators to plan, organize, instruct and make assessments on the same group of students, generally in a common classroom, and often with a strong focus on those teaching as a team complementing one another's particular skills or other strengths". +::: + +Co-teaching can be used in various forms, some of which are present in our workshops: +- **Teaching + support**, e.g. one of the teachers leading instruction while the other watches over and maintains the collaborative document (HackMD/HedgeDoc/...). +- Another similar example is **remote learning groups** that watch the streamed CodeRefinery lessons guided by the local instructors. +- Having open-source material and planning jointly allows **multiple instances** of a lesson to be held by multiple teachers: + - *parallel teaching*, to different audiences at the same time, + - *alternative teaching*, to different audiences at the same or different time, with potential content adjustments (for example, different installation procedures). +- **Team teaching**, where the lesson is presented by multiple (in most cases, two) teachers who actively engage in conversation with each other. The team-teaching concept is explained in more detail in the [CodeRefinery manual](https://coderefinery.github.io/manuals/team-teaching/). + +In reality, different forms are very often mixed or fused together, even within a single lesson. + +Co-teaching is not an online-only concept. However, it is very practical in online teaching due to larger number of instructors and learners potentially available to join a teaching session. + + +## Co-teaching and team teaching benefits + +- It **saves preparation time**. Co-teachers can rely on each other's strengths while creating/ revising the material as well as in unexpected situations during the lesson. +- It **helps with onboarding new instructors**. One of the co-teachers can be learning at the same time, either the subtleties of the material taught (in this case literally being the "voice of the audience") or the teaching process itself. +- Team teaching **looks more interactive and engaging** to the audience in many cases, without forcing the learners to speak up if they can't or don't want to do so. +- It also **ensures responsive feedback and less workload** by having more active minds. + + +### Are there any downsides? + +Not every learner and not every instructor might like the team-teaching approach. +- It might seem **less structured**, unprepared, and chaotic, even with preparation. + - It might create situations where instructors accidentally talk over each other or "interrupt" and change the flow of the lesson. + - For some instructors it can be stressful to not know in advance what questions they get asked from the co-instructor. + - Sometimes when an unexpected question is asked that throws the other instructor off, it can add to the feeling of chaos and unpreparedness. +- It can be interactive and engaging but it can also end up awkward if the co-teachers don't have a good synergy. + - Can sound awkward: Main instructor talking all the time and at the end asking co-instructor whether everything is clear and co-instructor only saying "yes". + - Possibly more engaging: Co-instructor asking questions which help with the flow and a common understanding of the material. + + +## Team teaching specifics + +- For successful team teaching, additional **coordination** is needed, first of all to agree on the teaching model (see below) and the person in control (the **director**) for the lesson or its parts. +- It's useful to keep track of the **lecture plan**. The discussion is a good way to make lesson more interactive and adjust to the audience, but deviating too much will become disorienting (for example, if someone dropped their attention for a minute and now is trying to catch-up by reading lecture notes). +- Experienced solo teacher might have a habit to keep talking (lecturing), while the co-teacher might not want to "interrupt". Therefore, it is important for the leading presenter to anticipate and **allow for remarks/ questions**, and this can be different from one's previous teaching style at first. + + +## Team teaching models + +We propose two basic models, but of course there is a constant continuum. + + +### Guide and demo-giver + +One person serves the role of **guide**, explaining the big picture and context of the examples. + +Another, the **demo-giver**, +- shows the typing and does the examples, +- might take the role of a learner who is asking about what is going on, to actually explain the details, or to comment occasionally. + +Hands-on demos and exercises work especially well like this. + + +### Presenter and interviewer + +In this case, one is the **presenter** who is mostly explaining (including demos or examples), and trying to move the forward through the material. + +Another, the **interviewer**, +- serves as a learner or spotter, +- fills in gaps by asking relevant questions, +- tries to comment to the presenter when things are going off track. + +This can be seen as closer to classical teaching, but with a dedicated and prepared "voice of the audience". + + +### Exercise + +:::{exercise} Discuss the models of team teaching (10 min) +While in breakout rooms, discuss one of the basic team-teaching models presented here: +- Have you already tried this or similar model in your teaching? +- Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best? + +Write your comments in the collaborative document. +::: + + +## Summary + +:::{keypoints} +- Co-teaching focuses on complementing individual skills and strengths in teaching process. +- Co-teaching may save time, reduce teachers' workload and make lessons more interactive/ engaging. +- Team teaching requires some adjustments in lesson preparation and delivery. +::: diff --git a/branch/comms/_sources/coderefinery-intro.md.txt b/branch/comms/_sources/coderefinery-intro.md.txt new file mode 100644 index 0000000..50d108c --- /dev/null +++ b/branch/comms/_sources/coderefinery-intro.md.txt @@ -0,0 +1,116 @@ +# About the CodeRefinery project and CodeRefinery workshops in general + +:::{objectives} +- Discuss what CodeRefinery is and how we got here +- Understand about the challenges to define our target audience +::: + +CodeRefinery is a +[Nordic e-Infrastructure Collaboration (NeIC)](https://neic.no/) +project that has started in October 2016 and is currently +funded until February 2025. We are working on the continuation plans. + +The funding from 2022-2025 is designed to keep this project active +beyond 2025 by forming a support network and building a community of +instructors and contributors. + + +:::{discussion} History +The CodeRefinery project idea grew out of two [SeSE](http://sese.nu) courses given at KTH Stockholm in 2014 and 2016. +The project proposal itself was submitted to NeIC in 2015, accepted in 2015, and started in 2016. + +We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form. +::: + + +## Goals + +- Develop and maintain **training material on good enough software development practices** for researchers that write code/scripts/notebooks. +- Our material addresses all academic disciplines and tries to be as programming language-independent as possible. +- Provide a [code repository hosting service](https://coderefinery.org/repository/) that is open and free + for all researchers based in universities and research institutes from Nordic countries. +- Provide **training opportunities** in the Nordics using (Carpentries and) CodeRefinery training materials. +- Evolve the project towards a **community-driven project** with a network of instructors and contributors. + + +## Community + +```{figure} img/community.png +Image showing the key areas of the CodeRefinery community: Workshops, chat inlcuding help channel, online meetings and co-working, +other collaborative training, eg on High Performance Computing topics. +``` + +CodeRefinery is not just workshops, we are community and want you to be part of it! + +There are many different levels of involvement, from the occasional commenter in chat, +CodeRefinery ambassador (people who like the project and workshops and help us spreading the word) or lesson issue creators and lesson contributors to +local host, co-instructor or co-organizer. + +Best **first step** in any case is to join the [CodeRefinery Zulip chat](https://coderefinery.zulipchat.com) +or let us know about your interest at support@coderefinery.org. + + +## Target audience + +One common question we get is how do we relate to [the Carpentries](https://carpentries.org). +This section describes how we see it: + + +### Carpentries audience + +The Carpentries aims to teach computational **competence** to learners through an applied approach, +avoiding the theoretical and general in favor of the practical and specific. + +**Mostly, learners do not need to have any prior experience in programming.** +One major goal of a Carpentries workshop is to raise awareness on the tools researchers can learn/use to speed up their research. + +By showing learners how to solve specific problems with specific tools and providing hands-on practice, +learners develops confidence for future learning. + +:::{admonition} Novices +We often qualify Carpentries learners as **novices**: they do not know what they need to learn yet. +A typical example is the usage of version control: the Carpentries lesson +[Version Control with Git](https://swcarpentry.github.io/git-novice/) +aims to give a +very high level conceptual overview of Git but it does not explain how it can be used in research projects. +::: + + +### CodeRefinery audience + +In that sense, CodeRefinery workshops differ from Carpentries workshops as we assume +our audience already writes code and scripts and we aim at teaching them **best software practices**. + +Our learners usually do not have a good overview of **best software practices** but are aware of the need to learn them. +Very often, they know of the tools (Git, Jupyter, etc.) we are teaching +but have difficulties to make the best use of them in their software development workflow. + +Whenever we can, we direct learners that do not have sufficient coding experience to Carpentries workshops. + +:::{admonition} Competent practitioners +We often qualify CodeRefinery learners as **competent practitioners** because they already have an understanding of their needs. +::: + +:::{discussion} Challenges related to defining our target audience +We often get the feedback "I wish I would have known X earlier!" +*Competent practitioners* have run into issues with **not** caring (or not fully understanding) +about version control, documentation, modularity, reproducibility before, so they are easily motivated to learn more. + +For a *novice* these topics may seem unnecessary and "too much" and the workshop may feel too difficult to follow. +However, the materials are designed so that one can always revisit a topic, when needed. +The important part is that you know that "X" exists, and where to find more information, which is also beneficial for novices. +::: + +--- + +:::{keypoints} Keypoints: CodeRefinery +- Teaches intermediate-level software development tool lessons +- It is difficult to define "best practices", we try to teach **"good enough" practices** +- Training network for other lessons +- Publicly-funded discrete projects (3 projects actually) transitioning towards an open community project +- We have online material, teaching, and exercise sessions +- Our main target audience are competent practitioners, but also novices and experts can get something out of the workshops +- We want more people to work with us, and to work with more people +::: diff --git a/branch/comms/_sources/collaborative-notes.md.txt b/branch/comms/_sources/collaborative-notes.md.txt new file mode 100644 index 0000000..15f84b3 --- /dev/null +++ b/branch/comms/_sources/collaborative-notes.md.txt @@ -0,0 +1,333 @@ +(collaborative-notes)= + +# Collaborative notes + +:::{objectives} +- Be able to provide a highly interactive online workshop environment with collaborative documents +::: + +:::{instructor-note} +- Teaching: 10 min +- Exercise: 15 min +- Questions & Answers: 5 min +::: + +## Introduction + +The Collaborative document is how you interact with the participants. +The participants can ask questions and give feedback through the collaborative +document. During a CodeRefinery session there can be a large a volume of questions. +A dedicated person, a Collaborative document-manager, is needed to answer and edit the collaborative document. +Let us see how the collaborative document is used, then discuss the role of +the editor or collaborative document-manager. + +## Collaborative document mechanics and controls +Technologies that can be used as a collaborative document are [Hackmd](https://hackmd.io), [HedgeDoc](https://hedgedoc.org), +or [Google Docs](https://www.google.com/docs/about/) + +[Hackmd](https://hackmd.io) or [HedgeDoc](https://hedgedoc.org/) are real-time text editor online. We use it to: +* As a threaded chat, to **answer questions and provide other information** without + interrupting the main flow of the room. +* provide everyone with a **more equal opportunity to ask questions**. +* **create notes** which will be archived, for your later reference. + +You do not need to login/create an account to be able to edit the document. + +### Basic controls + +```{figure} img/hackmd--controls.png + +This may look slightly different on mobile devices and small windows. +``` + +- At the top (left or right), you can switch between **view**, + **edit**, and **split view and edit** modes. + +- You write in [markdown](https://commonmark.org/help/) here. Don't + worry about the syntax, just see what others do and try to be like + that! Someone will come and fix any problems there may be. + +- Please go back to view mode if you think you won't edit for a + while - it will still live update. + + +### Asking questions + +**Always ask questions and add new sections at the very bottom**. +You can also answer and comment on older questions, too. + +```{figure} img/hackmd--questions2.png + +Questions and answers in bullet points +``` + +Since we plan to publish the questions and answers later as part +of the workshop page, we recommend to not use any names. You can indicate +your own name to make it easier to discuss more during the workshop but +then always use this form: `[name=Myname]`. This makes it easier for +us to automatically remove all names before publishing the notes. + +Other hints: + +- Use `+1` to agree with a statement or question (we are more likely + to comment on it). + +- Please leave some blank lines at the bottom + +- NOTE: Please don't "select all", it highlights for everyone and adds a + risk of losing data (there are periodic backups, but not instant). + +- It can be quite demanding to follow the collaborative document closely. Keep an eye + on it, but consider how distracted you may get from the course. For + things beyond the scope of the course, we may come back and answer + later. + + +### Don't get overwhelmed + +There can be a flood of information on the collaborative document. Scan for what is +important, then if you would like come back later. But it is +important to keep checking it. + + +### Privacy + +- Assume the collaborative document is **public and published: you never + need to put your name there**. + +- The collaborative document will be **published on the website afterwards**. We will + remove all non-instructors names, but it's easier if you don't add + it there in the first place. + +- Please keep the link private during the workshop, since since + security is "editable by those who have the link". + +- You can use `[name=YOURNAME]`, to name yourself. We *will* remove + all names (but not the comments) before archiving the notes (use + this format to make it easy for us). + +## Exercise + +:::{exercise} Discuss how to collaborate and handle questions (15 min) +Write down your conclusions in the shared document. Items to discuss are: +- What is your experience with questions and discussions while teaching? +- How do you deal with them? +- What kind of technologies do you prefer: chat, shared document, or voices + and discussion raised during instruction? And why? +::: + +## Collaborative Document Manager + +We have one person who is a "Collaborative Document helper". This isn't the only +person that should edit and answer, but one person shouldn't have too +much else on their mind so can focus on it. They also make sure that +the collaborative document is updated with exercise, break, and other meta-information to +keep people on track. + +Below, (*) = important. + +### Before the workshop + +* Create a new collaborative document for the workshop +* make sure that **editing is enabled for anyone without login** +* Add workshop information, links to the workshop page and material +and an example question and answer to the top of the collaborative document(see below) + +### Most things to edit (everyone) + +Make it easy to post after the course and consistent to follow: + +* Tag all names with `[name=XXX]` (so they can be removed later), + remove other personal data or make it obvious. +* Add in information on exercises (new section for them, link, end + time, what to accomplish) +* Make a logical section structure (`#` for title, `##` for sections, + `###` for episodes, etc. - or what makes sense) + + + +### General Collaborative Document practices + +```{figure} img/hackmd--full-demo.png +:align: right + +A live demo of a Collaborative Document during a Q&A time. The two instructors are +discussing some of the import answers. Multiple learners have asked +questions, multiple answers, and some remaining to be answered +``` + + + +Keep it formatted well: + +- (*) Tag names you see with `[name=XXX]` so that we can remove it + later. +- Heading level `#` is only the page title +- Add a new `##` heading when a new *lesson* or similar thing is + started (introduction, icebreaker, break between lessons, etc) +- Add a new `###` heading when a new *episode*, *exercise*, *break* + (within exercise session) +- Ensure people are asking questions at the bottom, direct them there + if they aren't. +- (*) Ensure each question is a bullet point. Each answer or follow-up + should be a bullet point below. + - Should you use more deeply nested bullet points, or have only one + level below the initial question? It depends on the context, but + if a conversation goes on too long, try not to let it go too + deep. + + +Update with meta-talk, so that learners can follow along easily: + +- Add Icebreaker and introductory material of the day. Try to talk to + people as they joined to get them to open the collaborative document and answer. +- Anything important for following along should not be only said via + voice. It needs to be in the collaborative document, too. +- New lessons or episodes, with links to them. +- For exercises, link to exercise and add the duration, end time, + goals. If these are unclear, bring it up to the instructor by voice. +- Add a status display about breaks. + + +Screenshare it when necessary: + +- During breaks and other times, share the collaborative document(including the + notification about break, and when it ends). +- It is nice if the arrangement allows some of the latest questions to + be seen, so people are reminded to ask there. +- Someone else may do this, but should make sure it happens. + +Answer questions + +- If there is an question that should be answered by the instructor by + voice, bring it up (by voice) to the instructor immediately. +- How soon do you answer questions? Two points of view: + - Answer questions right away: can be really intense to follow. + - Wait some so that we don't overload learners: reduces the info + flow. But then do people need to check back more often. + - You need to find your own balance. Maybe a quick answer right + away, and more detailed later. Or delay answers during the most + important parts of the lecture. +- Avoid wall-of-text answers. If reading an answer takes too long, it + puts the person (and other people who even try to read it) behind + even more by taking up valuable mental energy. If an answer needs a + wall of text, consider these alternatives: + - Progressive bullet points getting more detailed (first ones + useful alone for basic cases) + - Don't be worried to say "don't worry about this now, let's talk + later." + - Figure out the root problem instead of answering every possible + interpretation + - Declare it advanced and that you will come back later. + +Ensure it can be posted quickly: + +- The collaborative document gets posted to the workshop webpage. For this, it needs some + minimal amount of formatting (it doesn't need to be perfect, just + not horrible). +- All names and private information needs to be stripped. This is why + you should rigorously tag all names with `[name=XXX]` so they can be + removed (see above). + - Learner names can be completely removed. CR staff names can be + `[name=CR]` or something similar. + - There may be other private URLs at the top or bottom. + +- If possible, send the PR adding the collaborative document to the workshop webpage + (though others can do this, too). + + + +### Collaborative document format example + +``` +# Workshop, day 1 + + +## Lesson name +https://coderefinery.github.io/lesson/ + +### Episode name +https://coderefinery.github.io/01-episode/ + +- This is a question + - Anwser + - More detailed answer +- question + - answer + +### Exercises: +https://link-to-exercise/.../.../#section +20 minutes, until xx:45 +Try to accomplish all of points 1-3. Parts 4-5 are optional. + +Breakout room status: +- room 2, need help with Linux permissions +- room 5, done + +### Break +:::danger +We are on a 10 minute break until xx:10 +::: + + +## Lesson 2 +https://coderefinery.github.io/lesson-2/ + +``` + +### Posting the collaborative document to the website + +The collaborative document should be posted sooner rather than later, and hopefully the +steps above will make it easy to do so quickly. You could wait a few +hours, to allow any remaining questions to be asked an answered. + +- Download as markdown +- Remove any private links at the top +- Adjust headings so that they are reasonable +- Look for private info and remove it + - Search document for `[name=???]` (change to `[name=staff]` or + `[name=learner]`) + - Any names not tagged with `[name=]` + - usernames in URLs + - private links + +### Feedback template + +`````` +## Feedback, day N + +:::info +### News for day N+1 +- . +- . +::: + +### Today was (multi-answer): +- too fast: +- just right: +- too slow: +- too easy: +- right level: +- too advanced: +- I would recommend this course to others: +- Exercises were good: +- I would recommend today to others: +- I wouldn't recommend today: + +### One good thing about today: +- ... +- ... + +### One thing to be improved for next time: +- ... +- ... + +### Any other comments: +- ... +- ... +`````` +:::{keypoints} +- Having a collaborative document improves communication and interaction. +- Answering questions requires a dedicated person - A Collaborative Document Manager. +- The collaborative document should be posted on the web site as soon as possible. +::: diff --git a/branch/comms/_sources/comms.md.txt b/branch/comms/_sources/comms.md.txt new file mode 100644 index 0000000..cdcc4de --- /dev/null +++ b/branch/comms/_sources/comms.md.txt @@ -0,0 +1,271 @@ +# Communications with participants + +**Before the workshop** + +Hei, + +thank you for your interest in the CodeRefinery train the trainer workshop! + +We are excited to start the workshop next week and wanted to share some information with you: + +Connection details + +Zoom: XX + +Collaborative notes + +This document will be used during the course and contains all information around the workshop as well as the place to collect questions and answers: XX + +Materials + +Our materials are a work in progress, but will appear and also later remain available here: https://coderefinery.github.io/train-the-trainer/ + +Workshop plan + +The workshop is split in four interactive sessions (9-12 CEST each Tuesday) which are independent from each other, so you may join all or just the ones that interest you or suit your schedule: + + Session 1: About lesson design, deployment, and iterative improvement (Aug 13) + Session 2: Tools and techniques adopted in CodeRefinery workshops (Aug 20) + Session 3: About teaching & cool things we all would like to share (Aug 27) + Session 4: Workshop streaming practices and post-workshop tasks (Sep 3) + +Registration info + +You can adapt your registration following the link in the registration confirmation e-mail. + +Preparations + +In general you will only need your brain for the exercises and discussions, but some will have the option to go deeper, which may require some accounts or tools to be set-up. We will inform about these things the week before each session. + +For Session 1 we recommend to have a GitHub account (https://coderefinery.github.io/installation/github/#github). There will be an optional exercise where you can build a lesson locally. This requires a basic Python environment (https://github.com/coderefinery/sphinx-lesson-template/blob/main/requirements.txt), but do not worry if you cannot or do not want to set up these, there will be plenty of other exercises. + +Questions? + +If you have any questions, ideas, or suggestions, please contact us at support@coderefinery.org + +We are looking forward to learning with you! + +Kind regards, +XX on behalf of CodeRefinery + +--- + +**Morning before Day 1** + +Good morning, + +the first session of the CodeRefinery train the trainer workshop will start at 9 CEST (Berlin, Stockholm time) / 10 EEST (Helsinki time) / 8 BST (British time) / 7 GMT+0 , i.e. in about 35 min. +Please join a bit early if you can, so that we can get started with the practicalities and introductions in time :) + +And no worries if you cannot join today, but want to join other sessions: Each session is self contained, and the materials will stay available. + +Zoom link: XX + +Lesson materials: https://coderefinery.github.io/train-the-trainer/ + +Collaborative notes: XX + +Looking forward to meeting you all! + +Kind regards, +XX on behalf of CodeRefinery + +--- + +**After Day 1 before Day 2** + + + +Email: Sent to all currently registered participants on 16.8 at 14.20 EEST: + +Hei, + +If you joined us last week, we hope you enjoyed last weeks session. In any case we hope you will join us for the next session on next weeks +Tuesday August 20th at 9-12 Central European Summer Time (CEST, UTC+2). + +The connection details stay the same: + +Zoom: XX + +We will also use again and learn more about our Collaborative notes : XX +One change to the previous session is that we will turn off Zoom chat and focus the discussion to the notes. + +The materials are and will stay available: https://coderefinery.github.io/train-the-trainer/ + +As mentioned before, all our workshop sessions are independent of each other and of interactive nature. +In this upcoming session we will discuss "Tools and techniques adopted in CodeRefinery workshops": + + Brief introduction to the CodeRefinery project and its history. + Collaborative notes in general as a tool to keep an online workshop interactive. + Current CodeRefinery workshop setup, what roles we have, what tools we use, who and how we onboard and why this might be useful for you too outside of CR workshops. + General discussion and practice about topics related to sound in online workshops. + General discussion and practice about screenshare for online and streamed workshops. + +Preparations + +In general you will only need your brain for the exercises and discussions. To get the most out of this workshop day we recommend that you join the session with the same computer, display and microphone setup as you would usually use for teaching/ presenting. It may also help to get familar with the different options your computer and Zoom setup provides for screenshare and audio adjustments. +But it is not a must. + +Questions? + +If you have any questions, ideas, or suggestions, please contact us at support@coderefinery.org + +We are looking forward to learning with you! + +Kind regards, +XX on behalf of CodeRefinery + +--- + +**Morning before Day 2** + +Good morning, + +the second session of the CodeRefinery train the trainer workshop will start at 9 CEST (Berlin, Stockholm time) / 10 EEST (Helsinki time) / 8 BST (British time) / 7 GMT/UTC+0 ; all AM; i.e. in about one hour. +Please join a bit early if you can, so that we can get started with the practicalities and introductions in time :) + +And no worries if you cannot join today, but want to join other sessions: Each session is self contained, and the materials will stay available. + +Zoom link: XX + +Lesson materials: https://coderefinery.github.io/train-the-trainer/ + +Collaborative notes: XX + +Looking forward to meeting you all! + +Kind regards, +XX on behalf of CodeRefinery + +--- + +**After Day 2 before Day 3** + +Hei, + +If you joined us any of the last weeks, we hope you enjoyed those sessions. In any case we hope you will join us for the next session on next weeks +Tuesday August 27th at 9-12 Central European Summer Time (CEST, UTC+2). + +The connection details stay the same: + +Zoom: XX + +We will use our Collaborative notes for sharing links, notes and ask and answer questions : XX +We kindly ask everyone to focus the discussion to the notes. + +The materials are and will stay available: https://coderefinery.github.io/train-the-trainer/ + +As mentioned before, all our workshop sessions are independent of each other and of interactive nature. +In this upcoming session we will discuss "About teaching and cool things we all would like to share": + + Introduction to computational thinking and how this relates to teaching computational topics + Teaching philosophies: Personal stories and discovering your own + Co-teaching: What it is, why we do it and challenges we have encountered + Cool gems we all would like to share: Kinda "open mic" session for everyone to share some cool tool that you like to use when teaching/preparing materials or a nice anecdote from teaching, reports from the best course you ever visited, etc. + +Preparations + +In general you will only need your brain for the exercises and discussions. If you want to share some "cool gem" in the last episode of this workshop day, please update your registration (link to edit can be found in the registration confirmation e-mail sent by support@coderefinery.org or noreply@neic.org). This is very low barrier, you do not have to be the developer of a tool or technique to share with the group what makes it useful for you; and it does not even have to be cool, sometimes the small "normal" things are the best. You can check out some topics that have been proposed so far in this GitHub issue (#90), you can also comment there if you want to add or change your topic. These will be lightning talk length, so something between 2-5 min depending on how many are interested to share something, but we can collect them all in the collaborative notes for further exploration/reading. +But it is not a must. + +Questions? + +If you have any questions, ideas, or suggestions, please contact us at support@coderefinery.org + +We are looking forward to learning with you! + +Kind regards, +XX on behalf of CodeRefinery + +--- + +**Morning before Day 3** + +Good morning, + +the third session of the CodeRefinery train the trainer workshop will start at 9 CEST (Berlin, Stockholm time) / 10 EEST (Helsinki time) / 8 BST (British time) / 7 GMT/UTC+0 ; all AM; i.e. in about 75 min. + +Please join a bit early if you can, so that we can get started with the practicalities and introductions in time :) + +And no worries if you cannot join today, but want to join other sessions: Each session is self contained, and the materials will stay available. + +Zoom link: XX + +Lesson materials: https://coderefinery.github.io/train-the-trainer/ + +Collaborative notes: XX + +For the last episode of today, if you want to share some story or demo about any tools or techniques you like using when teaching, please add your name/initials and topic the collaborative notes: https://notes.coderefinery.org/TTT24?view#Teaching-gems . + +Looking forward to learning with you today! + +Kind regards, +XX on behalf of CodeRefinery + +--- + +**After Day 3 before Day 4** + + + +Email sent to all registered participants on 29.8 at 18 EEST: + +Hei, + +If you joined us any of the last weeks, we hope you enjoyed those sessions. In any case we hope you will join us for the next session on next weeks Tuesday September 3rd at 9-12 Central European Summer Time (CEST, UTC+2). + +The connection details stay the same: + +Zoom: XX + +We will use our Collaborative notes for sharing links, notes and ask and answer questions : XX +We kindly ask everyone to focus the discussion to the notes. + +The materials are and will stay available: https://coderefinery.github.io/train-the-trainer/ + +As mentioned before, all our workshop sessions are independent of each other and of interactive nature. + +This upcoming session (session number 4) will cover the technical aspects of CodeRefinery-style online teaching. These topics have never before been covered in this much detail, so if it's interesting to you, don't miss it. (You might also want to pass this on to others who are interested in technical production of online events; registration is still open!). + +First, we talk about why we stream (how we got here, advantages, disadvantages, how to be an instructor in a livestreamed workshop, and what it looks like from a broad level from the production side) + +Then, we show how we are able to release videos so quickly. This is useful far beyond CodeRefinery, and there are also some hands-on exercises. Come prepared to set up a Python environment and the ffmpeg command line tool if you want to try these. + +Finally, we see details about how to set up Zoom→Livestream environment for yourself. There isn't time to do this as a proper exercise, but it's the starting point and the instructor will offer help after the course for those interested. If you want to try this out during the session, install OBS Studio in advance. + +Questions? + +If you have any questions, ideas, or suggestions, please contact us at support@coderefinery.org . + +We are looking forward to learning with you! + +Kind regards, +XX on behalf of CodeRefinery + +--- + +**Morning before Day 4** + +Good morning, + +the fourth session of the CodeRefinery train the trainer workshop will start at 9 CEST (Berlin, Stockholm time) / 10 EEST (Helsinki time) / 8 BST (British time) / 7 GMT/UTC+0 ; all AM; i.e. in about one hour. + +Please join a bit early if you can, so that we can get started with the practicalities and introductions in time :) + +And no worries if you cannot join today, all materials will stay available. + +Zoom link: XX + +Lesson materials: https://coderefinery.github.io/train-the-trainer/ + +Collaborative notes: XX + +Kind regards, +XX on behalf of CodeRefinery + +--- + +**After workshop email** + +TBD + diff --git a/branch/comms/_sources/computational-thinking.md.txt b/branch/comms/_sources/computational-thinking.md.txt new file mode 100644 index 0000000..943d9c8 --- /dev/null +++ b/branch/comms/_sources/computational-thinking.md.txt @@ -0,0 +1,25 @@ +(computational-thinking)= + +# Computational thinking + + +:::{objectives} +- Explain what is computational thinking +- Get to know how the theory of computational thinking can be used in teaching +- Short exercise +::: + +:::{instructor-note} +- Teaching: 20 min +- Exercises: 10 min +::: + + +Materials available as [slides](https://github.com/coderefinery/train-the-trainer/blob/main/content/computational_thinking.pdf). + + +:::{keypoints} +- Computational Thinking consists of 4 main parts: decomposition, pattern recognition, abstraction and algorithmic design. +- How can this be a useful framework for solving problems? +- How can this be used practically? +::: diff --git a/branch/comms/_sources/cool-gems.md.txt b/branch/comms/_sources/cool-gems.md.txt new file mode 100644 index 0000000..a4a6f5c --- /dev/null +++ b/branch/comms/_sources/cool-gems.md.txt @@ -0,0 +1,16 @@ +(cool-gems)= + +# Sharing teaching gems + +:::{objectives} +- Our goal is to share our teaching tricks and tools and demonstrate them in + very short presentations/discussions. +::: + +:::{instructor-note} +- Demonstrations: 35 min +::: + +Here we encourage participants to take the screen share for 3 minutes and +demonstrate either some tool or trick they found useful for their teaching or +something from a course you liked. diff --git a/branch/comms/_sources/feedback-and-impact.md.txt b/branch/comms/_sources/feedback-and-impact.md.txt new file mode 100644 index 0000000..698de4a --- /dev/null +++ b/branch/comms/_sources/feedback-and-impact.md.txt @@ -0,0 +1,200 @@ +# How we collect feedback and measure impact + +:::{objectives} +- Discuss how one can collect feedback from learners ("what can we improve?"). +- Discuss how we convert feedback into actionable items. +- Discuss how we measure the impact of teaching ("did we achieve our goals?"). +- Discuss the "why". +- Get to know the reasons and sources of inspiration behind major lesson and workshop updates. +::: + +:::{instructor-note} +- Discussion: 20 min +- Exercises: 10 min +::: + + +## Asking questions before the workshop + +- Motivation: Know your audience. +- Until 2021 we had a pre-workshop survey: + - Data, questions, and notebook: + - Zenodo/DOI: +- After 2021 we incorporated some of the questions into the registration form. + - Easier registration experience for participants. + - After 5 years of running workshops, we had a good idea of what to expect. + + +## Collecting feedback as we teach + +- Each day we ask for feedback in the collaborative notes. + - One good thing about today. + - One thing to improve for next time. + - Any other comments? +- During the workshop we sometimes check in and ask about the pace, example: + ``` + How is the speed so far? (add an "o") + - Too fast: oooooo + - Too slow: ooo + - Just right: ooooooooooooooooooo + ``` +- We publish all questions, answers, and feedback. Example: +- How we follow up: + - Some problems we can fix already before the next workshop day. + - We convert feedback/problems into GitHub issues and track these close to the lesson material. + + +## Trying to measure impact with longer-term surveys + +- Motivation: Understand the long-term impact of our workshops. Have something to show to funders. +- 2024 post-workshop survey: + - Blog post: + - Questions, notebook, and figures: + - Zenodo/DOI: +- 2021 version: + - Data, questions, notebook, and figures: + - Zenodo/DOI: +- How we use the results: + - When reporting to funders. + - When planning future workshops and bigger picture changes. + + +## Lessons learned + +- Think about how to measure impact/success from the beginning. +- **Make the feedback and survey results public**. +- Make the results persistent and citable. +- Have a mechanism to follow-up on feedback. +- Anonymization is more than just removing or dissociating names. +- Take time designing your survey and collect feedback on the survey itself. + + +## Take time designing your survey + +We are not experts in survey design but we reached out to RISE Research +Institutes of Sweden to get feedback on our survey questions. They provided us +with a lot of valuable feedback and suggestions for improvements. +Below are few examples. + + +### Example 1 + +First version of our survey question about impact: +- "Do our workshops help to save time in future?" Please quantify in hours saved: ... + +Feedback: +- Difficult to answer. +- Since when? Until all eternity? + +```{figure} feedback-and-impact/survey-impact1.png +:width: 80% +:class: with-border +:alt: Screenshot of earlier version of the survey question about impact. + +Earlier version of the survey question about impact. +``` + +Feedback: +- The question "Do our workshops help to save time in future?" is unspecified, + unnecessary, and leading. +- "No time saving" does not match the wording "save time" in the question. + +```{figure} feedback-and-impact/survey-impact2.png +:width: 80% +:class: with-border +:alt: Screenshot of later version of the survey question about impact. + +Later version of the survey question about impact. +``` + +- The wording "have you saved" now matches "No time saved". + + +### Example 2 + +- Earlier version: + ``` + Would you judge your code to be better reusable/reproducible/modular/documented + as a result of attending the workshop? + + - More reusable + - More reproducible + - More modular + - Better documented + - None of the above + ``` +- Feedback: The question is not neutrally formulated and risks leading to + over-reporting of yes answers. Consider balancing so that the questions are + formulated more neutrally. +- Reformulated to: + ``` + After attending the workshop, would you judge your code to be + more reusable or not more reusable? + + - My code is more reusable + - My code is not more reusable + - Not sure + ``` + + +### Example 3 + +- Early version: + ``` + What else has changed in how you write code since attending the workshop? + + [free-form text field] + ``` +- Feedback: Leading and assumes that something has changed. +- Reformulated to: + ``` + Has anything else changed in how you write code for your research after + attending the workshop? + + [free-form text field] + ``` + + +### Example 4 + +- Earlier version: + ``` + Has it become easier for you to collaborate on software development with your + colleagues and collaborators? + + - Yes + - Not sure + - No + ``` +- Feedback: + - Leading question. + - Avoid "Yes" and "No" response options because respondents tend to answer + "Yes" if that option is available, leading to a risk of measurement error + (acquiescence bias). + - Do not place "Not sure" in the middle of the scale because it captures + participants who actually don't know and should therefore be placed at the + bottom instead of in the middle of the scale. +- Reformulated to: + ``` + After attending the workshop, has it become easier or not for you to + collaborate on software development with your colleagues and collaborators? + + - Collaboration is easier + - Collaboration is not easier + - Not sure + ``` + + +## Exercise: Group discussion (10 min) + +:::{exercise} Group discussion using the collaborative notes +- What tricks/techniques have you tried in your teaching or seen in someone + else's teaching that you think have been particularly effective in collecting + feedback from learners? +- Can you give tips or share your experiences about how to convert feedback + into actionable items? +- How do you measure the impact of your teaching? Any tips or experiences about + what you have tried or seen other courses do? +- Anybody knows of good resources on survey design? Please link them in + the collaborative notes. +::: diff --git a/branch/comms/_sources/guide.md.txt b/branch/comms/_sources/guide.md.txt new file mode 100644 index 0000000..3c956d8 --- /dev/null +++ b/branch/comms/_sources/guide.md.txt @@ -0,0 +1,91 @@ +# Instructor guide + + +## Target audience + +- Everyone teaching online workshops about computational topics or interested in teaching. +- Previous and future instructors and helpers of CodeRefinery workshops. + + +## Timing + +**Session 1** +- 15 min: Intro +- 45 min: Lesson design and development +- 15 min: Break +- 45 min: Lesson template +- 15 min: Break +- 30 min: How we collect feedback and measure impact +- 10 min: Outro and feedback + +**Session 2** +- 15 min: Intro +- 10 min: About the CodeRefinery project and CodeRefinery workshops in general +- 30 min: Collaborative notes and interaction +- 15 min: Break +- 35 min: Workshop overview, roles, onboarding/installation, helpers +- 20 min: Sound +- 15 min: Break +- 30 min: Screenshare +- 10 min: Outro and feedback + +**Session 3** +- 15 min: Intro +- 30 min: Computational thinking +- 15 min: Break +- 30 min: Teaching philosohies +- 30 min: Co-teaching +- 15 min: Break +- 35 min: Sharing teaching tips, tricks, tools etc +- 10 min: Outro and feedback + +**Session 4** +- 15 min: Intro +- 10 min: Why we stream +- 20 min: Behind the stream +- 15 min: Video editing (part 1) +- 15 min: Break +- 25 min: Video editing (part 2, exercise) +- 20 min: OBS introduction +- 15 min: Break +- 30 min: OBS setup +- 15 min: What's next? + +## Talking points for each sessions intro + +- Brief CodeRefinery intro +- Instructors intros +- Notes intro + - Check-in + - Icebreaker + - Participant intros in breakoutrooms (Random assign first, then same for whole session) +- Daily schedule, learning objectives +- Code of conduct +- Chat (please use collaborative notes) + +## Participant preparations for each session +Copied from e-mail communication with participants before each session. + +**Session 1:** +In general you will only need your brain for the exercises and discussions, but some will have the option to go deeper, which may require some accounts or tools to be set-up. We will inform about these things the week before each session. + +For Session 1 we recommend to have a GitHub account (https://coderefinery.github.io/installation/github/#github). There will be an optional exercise where you can build a lesson locally. This requires a basic Python environment (https://github.com/coderefinery/sphinx-lesson-template/blob/main/requirements.txt), but do not worry if you cannot or do not want to set up these, there will be plenty of other exercises. + +**Session 2:** +In general you will only need your brain for the exercises and discussions. To get the most out of this workshop day we recommend that you join the session with the same computer, display and microphone setup as you would usually use for teaching/ presenting. It may also help to get familar with the different options your computer and Zoom setup provides for screenshare and audio adjustments. +But it is not a must. + +**Session 3:** +In general you will only need your brain for the exercises and discussions. If you want to share some "cool gem" in the last episode of this workshop day, please update your registration (link to edit can be found in the registration confirmation e-mail sent by support@coderefinery.org or noreply@neic.org). This is very low barrier, you do not have to be the developer of a tool or technique to share with the group what makes it useful for you; and it does not even have to be cool, sometimes the small "normal" things are the best. You can check out some topics that have been proposed so far in this GitHub issue (#90), you can also comment there if you want to add or change your topic. These will be lightning talk length, so something between 2-5 min depending on how many are interested to share something, but we can collect them all in the collaborative notes for further exploration/reading. +But it is not a must. + +**Session 4:** +This upcoming session (session number 4) will cover the technical aspects of CodeRefinery-style online teaching. These topics have never before been covered in this much detail, so if it's interesting to you, don't miss it. (You might also want to pass this on to others who are interested in technical production of online events; registration is still open!). + +First, we talk about why we stream (how we got here, advantages, disadvantages, how to be an instructor in a livestreamed workshop, and what it looks like from a broad level from the production side) + +Then, we show how we are able to release videos so quickly. This is useful far beyond CodeRefinery, and there are also some hands-on exercises. Come prepared to set up a Python environment and the ffmpeg command line tool if you want to try these. + +Finally, we see details about how to set up Zoom→Livestream environment for yourself. There isn't time to do this as a proper exercise, but it's the starting point and the instructor will offer help after the course for those interested. If you want to try this out during the session, install OBS Studio in advance. + + diff --git a/branch/comms/_sources/index.md.txt b/branch/comms/_sources/index.md.txt new file mode 100644 index 0000000..6adb709 --- /dev/null +++ b/branch/comms/_sources/index.md.txt @@ -0,0 +1,122 @@ +# Train the trainer workshop + +::::{admonition} August/September 2024 CodeRefinery train the trainer workshop + +Do you teach the use of computers and computational tools? Are you curious about scaling your training and learn about tested and proven practices from CodeRefinery workshops and other trainers? Join us for the CodeRefinery train the trainer workshop: four self-contained sessions on tools and techniques for computational training offer a great chance to enhance your teaching skills and learn about new tools and practices. What you will learn is also used a lot outside CodeRefinery, whenever good beginner friendly training is needed. + +**Learning objectives:** +- Learn about tools and techniques and practice to create engaging online teaching experiences (screenshare, audio, etc.). +- Become mentally ready to be an instructor in a collaborative interactive online workshop (not only large workshops but in general). +- Learn how to design and develop lesson material collaboratively. + +**Target audience:** +- Everyone teaching online workshops about computational topics or interested in teaching. +- Previous and future instructors and helpers of CodeRefinery workshops. + +**Prerequisites:** +An interest in teaching. + +**Workshop structure:** +We aim for a mix of modular presentations and work in small groups. The latter will be done in breakoutrooms - +be prepared to switch on your camera and have a fruitful exchange with fellow participants! + +**Organizers and instructors:** + +The workshop is organized by [partner organizations of the CodeRefinery project](https://coderefinery.org/about/partners/). + +Facilitators and instructors: + +- Radovan Bast +- Richard Darst +- Bjørn Lindi +- Dhanya Pushpadas +- Jarno Rantaharju +- Stephan Smuts +- Stepas Toliautas +- Samantha Wittke + + +**Content and timing:** + +The workshop consists of four sessions every Tuesday between August +13th and September 3rd 2024, +{localtime}`09:00 13 August 2024 +02:00 (HH:mm)` to +{localtime}`12:00 13 August 2024 +02:00 (HH:mm z/zzz)`: + +- Session 1: About lesson design, deployment and iterative improvement (Aug 13) +- Session 2: Tools and techniques adopted in CodeRefinery workshops (Aug 20) +- Session 3: About teaching & cool things we all would like to share (Aug 27) +- Session 4: Workshop streaming practices and post-workshop tasks (Sep 3) + +You can join all sessions, or the just the ones that interest you. More details on each session will be shared later. + +The workshop is **free of charge for everyone**, please register below to get the Zoom link and other useful information for the workshop. + +The workshop is over and registration is closed now. + +If you have any questions, please write to . +:::: + +```{admonition} +You can find materials of previous similar trainings using the links below: + +- First version of the course in 2019 and then in 2020: + +- Reworked material for our summer workshop 2022 and +for the CarpentryCon 2022 workshop: + +``` + +```{toctree} +:maxdepth: 1 +:caption: Session 1 + +lesson-development +lessons-with-git +feedback-and-impact +``` + +```{toctree} +:maxdepth: 1 +:caption: Session 2 + +coderefinery-intro +collaborative-notes +overview +sound +screenshare +``` + +```{toctree} +:maxdepth: 1 +:caption: Session 3 + +computational-thinking +teaching-philosophies +co-teaching +cool-gems +``` + +```{toctree} +:maxdepth: 1 +:caption: Session 4 + +session-4-intro +why-we-stream +streaming +video-editing +obs +obs-config +streaming-whats-next +``` + +```{toctree} +:maxdepth: 1 +:caption: Resources + +notes-archive +guide +All lessons +CodeRefinery +Reusing +``` diff --git a/branch/comms/_sources/lesson-development.md.txt b/branch/comms/_sources/lesson-development.md.txt new file mode 100644 index 0000000..76e79bf --- /dev/null +++ b/branch/comms/_sources/lesson-development.md.txt @@ -0,0 +1,204 @@ +(lesson-design)= + +# Lesson design and development + +:::{objectives} +- We share our design processes for teaching material and presentations. +- Learn how to design lessons "backwards", starting from learning objectives + and learner personas. +- Learn good practices for improving existing material based on feedback. +::: + +:::{instructor-note} +- Discussion: 20 min +- Exercises: 35 min +::: + + +## Exercise: How do you design your teaching material? + +:::{exercise} We collect notes using a shared document (5 min) +- When you start preparing a new lesson or training material, where do you start? +- What tricks help you with "writer's block" or the empty page problem? +- Maybe you haven't designed training material yet. But how do you start when creating a new presentation? +- If your design process has changed over time, please describe what you used to do and what you do now instead. +- What do you know now about preparing lessons/training/presentations that you wish you knew earlier? +::: + + +## Creating new teaching material + + +### Typical problems + +- Someone creates a lesson, but they think about what is interesting to them, + not what is important for the learners. +- "I want to show a number of things which I think are cool about + tool X - how do I press these into 90 minutes?" +- Write down material you want to cover and then sprinkle in some exercises. +- Thinking about how I work, not how the learners work. +- Trying to bring learners to their level/setup, not trying to meet the learners + where they are. +- Not really knowing the learning objectives or the learner personas. + + +### Better approach + +Good questions to ask and discuss with a group of colleagues **from diverse backgrounds**: +- What is the expected educational level of my audience? +- Have they been already exposed to the technologies I am planning to teach? +- What tools do they already use? +- What are the main issues they are currently experiencing? +- What do they need to remember/understand/apply/analyze/evaluate/create + ([Bloom's taxonomy](https://en.wikipedia.org/wiki/Bloom%27s_taxonomy))? +- Define learner personas. +- It may be an advantage to share an imperfect lesson with others early to + collect feedback and suggestions before the lesson “solidifies” too much. + Draft it and collect feedback. The result will probably be better than + working in isolation towards a "perfect" lesson. + + +### The process of designing a lesson "backwards" + +As described in ["A lesson design process" in the book Teaching Tech +Together](https://teachtogether.tech/en/index.html#s:process): + +1. Understand your learners. +1. Brainstorm rough ideas. +1. Create an summative assessment to know your overall goal. + > [Think of the things your learners will be able to do at the end of the lesson] +1. Create formative assessments to go from the starting point to this. + > [Think of some engaging and active exercises] +1. Order the formative assessments (exercises) into a reasonable order. +1. Write just enough material to get from one assessment (exercise) to + another. +1. Describe the course so the learners know if it is relevant to them. + + +## Improving existing lessons + +:::{discussion} All CodeRefinery lessons are on GitHub +- Overview: +- All are shared under CC-BY license and we encourage [reuse and modification](https://coderefinery.org/lessons/reusing/). +- Sources are all on GitHub: +- Web pages are generated from Markdown using [Sphinx](https://www.sphinx-doc.org/) + (more about that in the episode {ref}`lessons-with-git`). +- We track ideas and problems in GitHub issues. +::: + +Collect feedback during the workshop: +- Collect feedback from learners and instructors ([Example from a past + workshop](https://coderefinery.github.io/2024-03-12-workshop/questions/)). +- Convert feedback about lessons and suggestions for improvements into issues + so that these don't get lost and stay close to the lesson material. + +Collect feedback before you start a big rewrite: +- First open an issue and describe your idea and collect feedback before you + start with an extensive rewrite. +- For things still under construction, open a draft pull/merge request to collect + feedback and to signal to others what you are working on. + +Small picture changes vs. big picture changes: +- Lesson changes should be accompanied with instructor guide changes (it’s like + a documentation for the lesson material). +- Instructor guide is essential for new instructors. +- Before making larger changes, talk with somebody and discuss these changes. + + +## Use case: our lessons + +As an example to demonstrate the process of designing and improving lessons, we +will have a look at one of our own lessons: [Introduction to version control +with Git](https://coderefinery.github.io/git-intro/). + +- Initial 2014-2016 version + - and + - Amazingly they are still findable! + - Format: Slides and live coding. + - Exercises were separate, during afternoon sessions. +- Some time in 2014-2015 attended Carpentries instructor training. +- 2016: CodeRefinery started. +- 2017: Started a new repository based on the Carpentries lesson template (at the time using Jekyll). + - Exercises become part of the lesson. + - We start in the **command line** and only later move to GitHub. +- 2019: A lot more thought about learning objectives and personas. + - Also license change to CC-BY. +- 2022: Convert lesson from Jekyll to Sphinx. + - Using the tools that we teach/advocate. + - We can have tabs and better code highlighting/emphasis. + - Easier local preview (Python environment instead of Ruby environment which we were not used to in our daily work). +- 2024: Big redesign. We move the lesson closer to where learners are. + - Start from GitHub instead of on the command line. + - Start from an existing repository instead of with an empty one. + - Offer several tracks to participate in the lesson (GitHub, VS Code, and command line) and learners can choose which one they want to follow. + - Blog post: [We have completely changed our Git lessons. Hopefully to the better.](https://coderefinery.org/blog/2024/04/19/git-lesson-rewrite/) +- Next steps? + - Making the lesson citable following + [our blog post](https://coderefinery.org/blog/2024/07/30/lesson-cffs/). + - Improvements based on what we learn from this workshop. + +The overarching trend was to make the lesson simpler and more accessible - to +meet the learners where they are instead of pulling them to the tool choices of +the instructors. Looking back, we learned a lot and the learning process is +not over yet. + + +## Exercise: Discussion about learning objectives and exercise design + +:::{exercise} We work in groups but use the shared document as result (20 min) +1. As a group **pick a lesson topic**. It can be one of the topics listed here but + you can also choose something else that your group is interested in, or a topic + that you have taught before or would like to teach. Some suggestions: + - Git: Creating a repository and porting your project to Git and GitHub + - Git: Basic commands + - Git: Branching and merging + - Git: Recovering from typical mistakes + - Code documentation + - Jupyter Notebooks + - Collaboration using Git and GitHub/GitLab + - Using GitHub without the command line + - Project organization + - Automated testing + - Data transfer + - Data management and versioning + - Code quality and good practices + - Modular code development + - How to release and publish your code + - How to document and track code dependencies + - Recording environments in containers + - Profiling memory and CPU usage + - Strategies for parallelization + - Conda environments + - Data processing using workflow managers + - Regular expressions + - Making papers in LaTeX + - Making figures in your favorite programming language + - Linux shell basics + - Something non-technical, such as painting a room + - Introduction to high-performance computing + - A lesson you always wanted to teach + - ... +1. Try to define 2-3 learning objectives for the lesson and write them down. + You can think of these as "three simple enough messages that someone will + remember the next day" - **they need to be pretty simple**. +1. Can you come up with one or two engaging exercises that could be used to + demonstrate one of those objectives? + **They should be simple** enough people can actually do them. Creating simple exercises is not easy. + Some standard exercise types: + - Multiple choice (easy to get feedback via a classroom tool - try to design each wrong answer so that it identifies a specific misconception). + - Code yourself (traditional programming) + - Code yourself + multiple choice to see what the answer is (allows you to get feedback) + - Inverted coding (given code, have to debug) + - Parsons problems (working solution but lines in random order, learner must only put in proper order) + - Fill in the blank + - Discussions, self directed learning exercises +::: + + +## Great resources + +- [Teaching Tech Together](http://teachtogether.tech/) +- [Our summary of Teaching Tech Together](https://coderefinery.github.io/manuals/teaching-tech-together/) +- [Ten quick tips for creating an effective lesson](https://doi.org/10.1371/journal.pcbi.1006915) +- [Carpentries Curriculum Development Handbook](https://cdh.carpentries.org/) +- [Our manual on lesson design](https://coderefinery.github.io/manuals/lesson-design/) diff --git a/branch/comms/_sources/lessons-with-git.md.txt b/branch/comms/_sources/lessons-with-git.md.txt new file mode 100644 index 0000000..f91a0e9 --- /dev/null +++ b/branch/comms/_sources/lessons-with-git.md.txt @@ -0,0 +1,217 @@ +(lessons-with-git)= + +# Lessons with version control + +:::{objectives} +- Understand why version control is useful even for teaching material +- Understand how version control managed lessons can be modified. +- Understand how the CodeRefinery lesson template is used to create new lessons +::: + +:::{instructor-note} +- Discussion: 25 min +- Exercises or demos: 20 min +::: + + +## Why version control? + +- If you are in CodeRefinery TTT, you probably know what version + control is and why it is important. +- The benefits of version control also extend to lessons: + - Change history + - Others can submit contributions + - Others can make derived versions and sync up later + - Same workflow as everything else + - Write it like documentation: probably more reading after than + watching it as a presentation. +- Disadvantages + - "What you see is what you get" editing is hard + - Requires knowing version control + +:::{discussion} Accepting the smallest contribution + +Question: if someone wants to make a tiny fix to your material, can they? +::: + +## Tour of lesson templates options + +There are different ways to make lessons with git. Some dedicated to +teaching: + +- CodeRefinery + - Example: This lesson itself + - Based on the Sphinx documentation generator + - [sphinx-lesson](https://github.com/coderefinery/sphinx-lesson) is + *very* minimal extra functionality +- Carpentries + - Example: + - Based on R and Rmarkdown + +Our philosophy is that anything works: it doesn't have to be just +designed for lessons + +- Jupyter Book + - Example: https://jupyterbook.org/ + - Note: is based on sphinx, many extensions here are used in CR lessons +- Various ways to make slides out of Markdown +- Cicero: GitHub-hosted Markdown to slides easily + - [Demo: Asking for Help with + Supercomputers](https://cicero.xyz/v3/remark/0.14.0/github.com/bast/help-with-supercomputers/main/talk.md/#1) + [The source](https://github.com/bast/help-with-supercomputers/blob/main/talk.md) +- Whatever your existing documentation is. + +**We like the CodeRefinery format, but think that you should use +whatever fits your needs the most.** + + +## [Sphinx](https://www.sphinx-doc.org) + +- We build all our lesson material with Sphinx +- Generate HTML/PDF/LaTeX from RST and Markdown. +- Many Python projects use Sphinx for documentation but **Sphinx is not limited to Python**. +- [Read the docs](https://readthedocs.org) hosts public Sphinx documentation for free! +- Also hostable anywhere else, like Github pages, like our lesson material +- For code a selling point for Sphinx is that also API documentation + is possible. + +Sphinx is a doc generator, not HTML generator. It can: + +- Markdown, Jupyter, and ReST (and more...) inputs. Executable inputs. + - jupyter-book is Sphinx, so anything it can do we can do. This was one of the + inspirations for using Sphinx +- Good support for inline code. Much more than static code display, if + you want to look at extensions. +- Generate different output formats (html, single-page html, pdf, epub, etc.) +- Strong cross-referencing within and between projects + + +## [CodeRefinery lesson template](https://github.com/coderefinery/sphinx-lesson-template) + +It is "just a normal Sphinx project" - with extensions: +- [Sphinx lesson extension](https://github.com/coderefinery/sphinx-lesson) + - adds is various directives (boxes) tuned to lesson purposes + - provides a sample organization and template repo you can use so that lessons look consistent +- Sphinx gives us other nice features for free + - Tabs: they are very important for us and allow us to customize in-place instead of copying everything and fragmenting lessons + - Emphasize lines: they make it easier to spot what has changed in longer code snippets + - Various input formats + - Markdown (via the MyST-parser), ReStructured text, Jupyter + Notebooks. + - Many other features designed for presenting and interacting with code +- It's fine if you use some other static site generator or git-based lesson method. + +:::{demo} Instructors go through the building and contributing process + +Depending on the course, instructors will demo what is roughly +exercise 4 below. Or a course might go straight to exercises. + +- Instructors decide what change they would want to make +- Instructors clone the repository +- **Instructors make the change** +- **Instructors set up the build environment** +- **Instructors build and preview** +- Instructors command and send upstream +::: + + +## Exercises + +Some exercises have prerequisites (Git or Github accounts). Most +instances of this course will have you do **1 and 2** below. + +:::{exercise} Lesson-VCS-1: Present and discuss your own lesson formats + +We don't want to push everyone towards one format, but as long as you +use Git, it's easy to share and reuse. + +- Discuss what formats you do use +- Within your team, show examples of the lessons formats you use + now. Discuss what is good and to-be-improved about them. +- Look at how they source is managed and how easy it might be to edit. +::: + + +:::{exercise} Lesson-VCS-2: Tour a CodeRefinery or Carpentries lesson on Github +- Look at either a CodeRefinery or Carpentries lesson + - CodeRefinery Git-Intro: [Lesson](https://coderefinery.github.io/git-intro/), [Github repo](https://github.com/coderefinery/git-intro) + - Carpentries Linux shell: [Lesson](https://swcarpentry.github.io/shell-novice/), [Github repo](https://github.com/swcarpentry/shell-novice/) +- Can you find + - Where is the content of the lessons? + - What recent change propsals (pull requests) have been made? + - What are the open issues? + - How you would contribute something? + - How would you use this yourself? +::: + + +:::{exercise} Lesson-VCS-3: Modify a CodeRefinery example lesson on Github +In this, you will make a change to a lesson on Github, using only the +Github interface. (Github account required, and we assume some +knowledge of Github. Ask for help in your team if it is new to you!) + +- Navigate to the example lesson we have set up: + [repo](https://github.com/coderefinery/sphinx-lesson-scratch-space), [web](https://coderefinery.github.io/sphinx-lesson-scratch-space/) +- Go to some page and follow the link to go to the respective page on + Github. (Alternatively, you can find the page from the Github repo directly). +- Follow the Github flow to make a change, and open a Pull Request + with the change proposal: + - Click on the pencil icon + - Make a change + - Follow the flow to make a commit and change. You'll fork the + repository to make your own copy, add a message, and open a pull + request. + +We will look at these together and accept some changes. +::: + + +:::{exercise} Lesson-VCS-4: Clone and build a CodeRefinery lesson locally +In this exercise, you will use Git to clone one a CodeRefinery lesson +and try to preview it locally. It assumes installation and knowledge +of Git. + +- Use this sample repository: + [git-intro](https://github.com/coderefinery/git-intro) (or whatever + else you would like) +- Clone the repository to your own computer +- Create a virtual environment using the ``requirements.txt`` + contained within the repository. +- Build the lesson. + - Most people will probably run: `sphinx-build content/ _build/` + - If you have `make` installed you can `make html` + - Look in the `_build` directory for the built HTML files. + +Overall, this is pretty easy and straightforward, if you have a Python +environment set up. The [CodeRefinery documentation +lesson](https://coderefinery.github.io/documentation/sphinx/) teaches +this for every operating system. + +This same tool can be used to build documentation for other software +projects and is pretty standard. +::: + + +:::{exercise} Lesson-VCS-5: (advanced) Create your own lesson using the CodeRefinery format +In this lesson, you'll copy the CodeRefinery template and do basic +modifications for your own lesson. + +- Clone the lesson template: + https://github.com/coderefinery/sphinx-lesson-template +- Attempt to build it as it is (see the previous exercise) +- How can you do tabs? +- How can you highlight lines in code boxes? +- How can you change color, logo and fonts? +- What directives are available? + +::: + + +## Summary + +:::{keypoints} +- Version control takes teaching materials to the next level: + shareable and easy to contribute +- There are different formats that use version control, but we like + Sphinx with a sphinx-lesson extension. +::: diff --git a/branch/comms/_sources/notes-archive.md.txt b/branch/comms/_sources/notes-archive.md.txt new file mode 100644 index 0000000..178256f --- /dev/null +++ b/branch/comms/_sources/notes-archive.md.txt @@ -0,0 +1,1605 @@ +# Collaborative notes archives from workshops + +## August/September 2024 + +### Day1: Session 1 (13.08.24) - About lesson design, deployment and iterative improvement + +#### :calendar: Schedule + +| Time (CEST) | Title | EEST (UTC+3) | BST (UTC+1) | +|---------------|--------------------------------------------|---------------|---------------| +| 8.45 - 9.00 | Connecting time | 9.45 - 10.00 | 7.45 - 8.00 | +| 9.00 - 9.15 | Intro and Icebreaker | 10.00 - 10.15 | 8.00 - 8.15 | +| 9.15 - 10.00 | Lesson design and development | 10.15 - 11.00 | 8.15 - 9.00 | +| 10.00 - 10.15 | Break | 11.00 - 11.15 | 9.00 - 9.15 | +| 10.15 - 11.00 | Lessons with version control | 11.15 - 12.00 | 9.15 - 10.00 | +| 11.00 - 11.15 | Break | 12.00 - 12.15 | 10.00 - 10.15 | +| 11.15 - 12.00 | How we collect feedback and measure impact | 12.15 - 13.00 | 10.15 - 11.00 | + +#### :icecream: Icebreaker + +##### Check-in + +Which emoji best describes your current state of mind? [Emoji cheat sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) +- :Decaffed ... and going strong ... +- :coffee: 🤔 +- :100: (ironically!) :coffee: intake happening +- :smile: +- :tired_face: +- :coffee: :party: +- :coffee: :happy: +- 😪 +- just got zoom installed / before my coffee +- :smil- +- :sweat_smile: (+) +- :yawning_face: +- :is it morning already? +- :smile: +- :yawning_face: +- :nerded_face: +- 🥵 +- :smile: +- :sleeping: +- :sleepy: :coffee: :smiley_cat: +- 🥳 +- :coffee: +- :coffee: + +##### Introduction in breakoutrooms. + +- Name / Affiliation / Location + +##### About teaching + +What is the hardest thing about teaching for you? +- Knowing how "it's going", whether learners are happy or not (especially when teaching online) :+1: +- The preparation the night before. It is always much more that I would hope, no matter how prepared I want it to be :+1: :+1: +- Managing groups with vastly different academic backgrounds +- Teaching wide spectrum of skill level at the same time. :+1: :+1: :+1: :+1: +- Time management! (Knowing how much can fit in a sessions) :+1: :+1: +- General preparation time, how to fit it into the regular work schedule, and estimate how much time is needed for prep. +- How to reduce too much text into just the right amount +- Preparation of the session material and estimating the right amount of time for each section +- Getting learners to take the first step: sign up for and attend a workshop, when they don't think programming is a skill they can learn +- Getting learners to take the _second_ step: translating what they've learned in a workshop into something they can apply +- preparation and time management +- Engaging with the students which was much easier for me when I used to coach +- Finding the right depth for an unknown audience for "my topic" +- education background of participants and their learning objectives + +What is the best thing about teaching for you? +- Seeing when learner gets interested/curious about something and takes inspiration from the course. :+1: +- Seeing it works and someone can do something new. +- Motivated students grasping new stuff +- Students picking up and running with the matertial and skills I give them and using it for their own work. :+1: +- The "ah-ha!" moment when a student gets it! :+1::100: :+1: +- Learning from students who know about some topic more than you do. :+1: +- Being able to help people reach their goals, by showing them something new. +- Teaching is optimism acted out in the hope of making a difference both ways I suppose. +- The feeling of accomplishment when you see learning grow and implement the learnings :book: +- mutual learning and impact on learners :+1: +- Results and feedbacks / Mutual interests and interesting discussions +- mutual learning and I can also learn lots of things and new ideas from participants + + +#### :question: Questions + +##### General / Practicalities + +- Will the material be made available? + - Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/ + - Can I share them with a colleague + - Yes please :) + - Can I resuse them in my own teaching? + - Yes please :) +- Will these sessions be recorded? + - No, but the materials (see above) should include everything needed for self-learning. +- Can I get a certificate for this workshop? + - You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended. +- How often will we be talking in breakout rooms? I'm not in a place where I can talk, so if we're going to talk a lot I'll need to move offices + - We'll have about one breakoutroom session per episode +- +##### Episode 1: Lesson design and development + +Materials: https://coderefinery.github.io/train-the-trainer/lesson-development/ +**Discussion:** + +- When you start preparing a new lesson or training material, where do you start? + - I look at existing materials on the same topic, but chose/refine topics based on the perceived needs/interests of the presumed audience + - Outline of structure and Material collection for a new lesson :+1: + - What material I have already? (what other material is already out there?) + - Start by looking for related resources (documents, videos, courses, etc) to have a base data and better understanding of what have been done around the topic + - Know your audience + - Review existing material + - Think about learning objectives (to keep focus on essential things) + - Think of three things simple enough that they will be remembered the next day. Design around that. + - I write down the thoughts that I have and then go back and structure it. + +- What tricks help you with “writer’s block” or the empty page problem? + - Write anything down that comes to mind, sometimes draw something, looking out the window :) + - Do a mind map - what concepts do I want to get across? + - Starting small, for example a list of headings and then building around it. :+1: + - What does one know about the target audience and why should they be spending longer than 1 minute listening to what they will eventually get to hear? + - Get some inspiration from another source. + - Start with the three things above + - Start with the plan and the overview design + - Some kind of outline / main message(s) + - Start with three things. Three supporting points for each of these. +- Maybe you haven’t designed training material yet. But how do you start when creating a new presentation? + - Think about the learning objectives and try to break them down into steps + - Title, Objectives, target audience and Plan + - Some kind of outline / main message(s). Get as many images as I can, instead of words + - Draft an outline and use chatgpt to fill in details + - Example of how the teaching content is applied in a real-world context +- If your design process has changed over time, please describe what you used to do and what you do now instead. + - I look more at existing materials and try to get more information about the audience. Unfortunately getting information about the audience before the event is hard + - I used to start from the begginning and get from there but that often meant a very polished start and a rushed end. Now I try an overview first, then fil out sparsed details at every section + - Updating the data and tweak the presentation + - If I am teaching a small group (or one to one) talk to them before hand - find out what they know already, what they want to learn. +- What do you know now about preparing lessons/training/presentations that you wish you knew earlier? + - less is more. It's better to have 2-3 main messages rather than trying to show everything in one go :+1: :+1: :+1: :+1: + - how much practice time the learners need to master what's taught + - Don't worry about something going wrong. It often makes the lesson (and thus the material) more presistent in memory. :+1: + - Try and remove everything except what you want the person to learn + - That's a very tough part for me in the sense that I never know how much of an underlying "black box" is still ok.... + - Designing intermediate materials is hard, and requires putting some "gatekeeping" making sure that learners are directed to appropriate courses + - When I see a cool graphic, concept, slide, etc., download it and save it in my 'new-materials' folder to use later on! + - I have come to the conclusion that perhaps a more "agile" approach to developing materials (try to do design/teaching iterations quickly) might be the best way to go, but there are risks with this approach too + +**Questions** + +- From zoom chat: Can you expand on what a learner persona is? + - A defined example person described in terms of the materials you are preparing, making up a story about the background and interest of t + - Answer from chat: A learner persona is a blackbox which has a very simple algorithm inside: GIGO. + - Answer from chat: I think it's the same as ICP (Ideal customer persona) where you describe the learner as a customer + - Answer from chat: I'm a big fan of "How Learning Works" by Ambrose et al https://bookshop.org/p/books/how-learning-works-eight-research-based-principles-for-smart-teaching-michele-dipietro/18640868?ean=9781119861690 + - See also book: [Teaching tech together](http://teachtogether.tech/) +> CodeRefinery lessons: https://coderefinery.org/lessons/ +- From chat: Do you have an example of an instructor guide? + - One example from our [reproducible research lesson](https://coderefinery.github.io/reproducible-research/guide/) + - Another from git intro: https://coderefinery.github.io/git-intro/guide/ +- From zoom chat: Do you have a "measure" of how better are the new lesson compared to the old ones? Does it make sense to talk about measurements here? + - So far we only have daily feedback that we collect at the end of the day and we can compare that to earlier daily feedbacks. More about that in the last episode of today. But measuring this is indeed not easy and it also takes time to capture the effect during longer-term surveys. Some of the changes were more leap-of-faith than based on data. + - I guess that sometimes one can use "compelling arguments" instead of data to justify a decision +- Software Carpentry does teach using the command line, and gives a session on the command line before. What do you think about this approach? Are you stating that a 3-hour lesson about CLI is not sufficient to make people comfortable enough to use that for version control? + - Yes, good question. For CR we consider it a more advanced step: we do think people should learn command line, but it's for a different course. We accept some people might not know it or want to know it so adapt to that. + - In general, we've found the "you need X, but have to learn A, B, and C first" approach should be avoided if possible: people are busy, try to reach people where they are. + +:::danger +[Exercise](https://coderefinery.github.io/train-the-trainer/lesson-development/#exercise-discussion-about-learning-objectives-and-exercise-design) in breakoutrooms +::: + +- Room 1 + - Research data management + - Objectives + - Research life cycle + - FAIR principles (Findable, Accessible, Interoperable, Reusable) + - Exercise + - develop a data management plan (DMP) that outlines how their research data will be handled throughout its lifecycle. + +- Room 2: What is the difference between eating breakfast and sitting through a lecture? (Tip: Start by listing the similarities ...) +- Room2 : Making papers in LaTeX + - What is LaTex and how is it different from editors like Word + - Basic Structures + - How to find and use a template + - Including figure & table + - How to use references and labels + - Exercise: to create a new LaTeX document & edit it + - Excercise: common error messages: can you find the error in this code? + - Exce +- Room 3 + - GPU Programming (1 hour intro) + - Learning objectives: + - What is GPU programming. + - When is it usable, beneficial to use GPU programming? + - What are technologies to do GPU programming? + - [What are and how to manage typical issues] + +- Room 4 + - Git / Figures / Project management / data cleaning + - Chose data cleaning + - Three learning objectives: + 1. What do we mean by "clean"? How to identify it? + 2. Identify some common problems in a dataset + 3. Identifying and handling missing values/fields + - Exercise + 1. Discuss problems, find the most common ones + - In small groups + - What problems have you run into with datasets you've worked with? + - What problems can you imagine, or have you heard about from colleagues/news/social media? + - Report back, instructor collects all problems into a list + 2. Have a dataset to clean; a clean and a messy example + - (identifying) Using a visualisation or overviewing tool? + +- Room 5 + - Jupyter Notebooks + - Learning Objectives + - Can setup an enviroment you can reuse / can share with others / a project. + - The order you run the commands in needs to match the order of the code in the Notebook - otherwise you end up in a pickle. + - Why use a Jupyter Notebook? What are the advantages? Easy to use environment. + - Exercise + - Print variable assignments from different cells - show that the order you run the code is important. + - hand out a domain specific notebook that does some calculations and visualization to run and modify, to show that you can share easily + - show !pip install to add dependencies/features +- Room 6 + - Using GitHub without the command line + - Learning Outcomes: + - Be able to discuss changes before merging changes into the main repository. + - Publish a personal repository page ( I think its called intro repository) + - Share their script/notebook/code/small data on GitHub + - Homepage using GitHub pages or the README that becomes the "index page" of the GitHub user account page + - Learner personas: + - Check the Personas of the learners + - Somebody who has seen/heard of GitHub but hasn't used it yet + - Someone using it for their own work but struggling with collaboration + - Exercises: + - Upload/share an example dataset or script + - Review another collaborators pull request. + - Take part in the discussion on a pull request. +- Room 7 + Linux shell basics: why do we want to teach them? + (this took most of the time for the discussion) + - Learning objectives: + 1. Filesystem: Directory (CLI) - Folder (GUI) analogy + 1. Basic commands (which commands are basic? make a survey of shell histories and get the most common ones) + 1. Basic constructs (e.g., for loops, pipes, while loops... which ones are basic? See above) + +> Note from chat: Zoom timer: https://support.zoom.com/hc/en/article?id=zm_kb&sysparm_article=KB0068677 + +##### Episode 2: Lessons with version control + +Materials: https://coderefinery.github.io/train-the-trainer/lessons-with-git/ + +Poll options: I want to hear about: +- A: Why use version control for teaching materials +- B: Different template options +- C: How CodeRefinery does it; CodeRefinerys lesson template + +Poll vote (multi-select): add a `o` to your answer + - A: ooo + - B: oooooo + - C: oooooooo :ghost: + +Question to audience: if someone wants to make a tiny fix to your material, how hard is it? +- If my material is only in pdf format which is not online, then it is hard. +- I hope it is easy - my material is in GitHub. Nobody has ever done that though! +- Slides: hard to find, easy to edit; Git repos somewhat easy, unless they have to be built locally or with an action; HackMD easiest to edit. + - if you use something like google slides they are not that difficult to find + - known permanent address. Google docs et al fail on that/same for many pads. +- For this material today - very easy! e.g. https://github.com/coderefinery/train-the-trainer/pull/128 +- Template with an edit button in the HTML pointing to the source-code in the repo. + +**Questions/Discussion topics** +> Upcoming CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/ +> Please share with your networks, and let us know if you would like to co-teach a lesson (to support@coderefinery.org or in our [Zulip chat](https://coderefinery.zulipchat.com/)) + +- Changes to the material are sometimes not just tiny fixes. For example, one wants to present a slightly different selection of topics, but maybe some topics are "coupled" (perhaps naturally or perhaps just because of how they are presented), or change the general "theme" (e.g., life sciences vs theoretical physics) while keeping the actual topics the same. How could a lesson be developed to avoid having to do a huge rewrite? + - You can try to modularize your material and keep non topic specific parts non themed. E.g. where you explain the functionality, don't make reference to the example (not simple), so the example can be changed depending on the audience. +- What are the pros/cons of renaming a course / changing a repo name in GitHub? + - It should be relatively unproblematic since GitHub will forward to the new name. + - How long does Github keep the "old" name linked? Is there a max time it's blocked, or changed as soon as a new one appears with the name? + - in my experience it forwards "forever" until I create a new repo with the old name which will break the forward +- what should be in the readme for the git repo? (canonical address? contact points? license!) + - https://coderefinery.github.io/mini-workshop/2/documentation/#often-a-readme-is-enough-checklist + - I miss the url to the (main) repo in the readme + - Do you mean the link to the rendered (lesson) page? + - Link to rendered page: We often have this in the "about" section of the readme (see up right: https://github.com/coderefinery/train-the-trainer) + - this gets lost in a fork, doesn't it? so 20 folks forking and or reuploading the repo somewhere means the url gets lost? + - True, but they might want to have their own version rendered? + - yes, I have had issues finding and contributing to the "master" repo so all benefit. Else it gets cluttered. Both is valid + - Good point though, the link to rendered page should probably also be included in the readme for completeness; ah and the link to the repository too, yes + - so realistically we need a content folder and some more next to the readme as a best practice. sounds good! +- Is myst (markdown renderer) enabled by default in sphinx now? + - to my knowledge no. we add the "myst_parser" extension to conf.py. + +> Cicero: https://cicero.readthedocs.io/ +> Sphinx documentation: https://www.sphinx-doc.org/en/master/ +> Carpentries workbench for creating Carpentries lessons: https://carpentries.github.io/workbench/ +> This is the testing lesson Richard showed: https://coderefinery.github.io/testing/ +> And the corresponding repository: https://github.com/coderefinery/testing +> You can lean back and watch, exercise coming in a bit :) +> Richard will now edit our train the trainer material repository: https://github.com/coderefinery/train-the-trainer +> The Sphinx extension for CodeRefinery lessons: https://github.com/coderefinery/sphinx-lesson +> Empty lesson template to build your own lesson: https://github.com/coderefinery/sphinx-lesson-template + +**More questions** +- Does the coderefinery.org page built on sphinx? + - It's built also from markdown but it uses https://www.getzola.org/ (which is more optimized to render websites, but we could do teaching also with Zola or create the project page using Sphinx) + +- Is there a way to build and preview CR lessons without the command line? + - The GitHub workflow we use creates HTML from all branches. This means that one can push a branch to GitHub, preview it there, and then open a pull request. One thing that would be nice but we don't have yet is if a bot automatically posts the link to the preview to a pull request. + +- For VCS-2, for the Carpentries Linux shell example, Lesson, Github repo, to me it seemed as though the Sandpaper setup they have makes a very nice interface, complicates the relationship between source and output. E.g on the soucre page https://github.com/swcarpentry/shell-novice/blob/main/index.md I could only see to 'Prerequisits' and not 'Download files' on the page https://swcarpentry.github.io/shell-novice/. Perhaps I have missed something? + - I am sorry I don't know the new Sandpaper setup well enough to answer this question. + +- Do we have the instructions to build the lessons available somewhere to try out later? + - https://github.com/coderefinery/sphinx-lesson + +:::danger +Exercise VCS-1 (and VCS-2 (if time)) (https://coderefinery.github.io/train-the-trainer/lessons-with-git/#exercises) in breakoutrooms until xx:05 + +then short summary in main room and then break. + +Use the notes below. Collect a list of lesson formats and discuss what you like about each of them. +::: + +- PDF slides by a presentation program +- pdf slides with beamer in latex under source control. +- Markdown slides via Github +- CodeRefinery template +- Carpentries template +- Google Slides +- git-book +- [Jupyter Book](https://jupyterbook.org/) - allows creating a structured reference website using RST/Markdown, including Jupyter Notebooks to show result of running code +- [mdbook](https://rust-lang.github.io/mdBook/) - create simple/minimal website using Markdown +- [Binder](https://mybinder.org) - allows learners to run their own live version of a github repository with Jupyter Notebooks, with only a web browser +- Jupyter notebooks and jupyterhub platform +- Jupyter + Nbviewer and custom css (read only) + Binder link (hands on) +- RMarkdown +- Quarto Slides +- [Reveal.js](https://revealjs.com/) - write slides in HTML (also supports markdown) + - Example: https://bl-presentations.erambler.co.uk/2024-02-21-idcc24/ +- [Remark.js](https://remarkjs.com/) - write slides in markdown + - Example: https://bl-presentations.erambler.co.uk/2024-02-19-idcc-pids-workshop/ + + +Room discussions: +- Room 1 + - (https://smc-aau-cph.github.io/SPIS/README.html) + - CodeRefinery template + - Shared notes & blogs + +- Room 2 + - demo the exercise + +- Room 3 + - Mix of JupyterLab, Terminal within that, and traditional slides + - Jupyter + RISE (benefit: slides that are editable and executable live) + - Challenges + - present code in an interactive way + - handle lots of images/ figures without too much additional overhead when setting up the material + +- Room 4 + - Material and tools depend on instructors + - Some slide building tools + - https://revealjs.com/ + - https://remarkjs.com/ + - https://github.com/rust-lang/mdBook + - Using flat git repos without fancy styling to make it easier to edit but still version controlled + +- Room 5 + - Using R as a GIS: https://github.com/nickbearman/intro-r-spatial-analysis + - Workbook: RMarkdown, Slides: Quarto + - No continuous intergration + - Having a jupyter nbinder link to test the notebook + - repo lives on codeberg in this example + +- Room 7 + - Ex 1: + - Sphinx, similar to CR + - Sometimes pdfs generated with beamer package (or from pptx and odt), but blows up repository size if in version control + - Ex 2: + - Content + - CR: Content commonly found int the content folder + - SC: Mostly under episodes + - Question that came up: + - is CR/Sphinx approach mostly for technical topics? What about language. + - I guess by our nature it's focused there. But probably could be used for others (I guess it it's much easier to use git in a technical audience.) + + +##### Episode 3: How we collect feedback and measure impact + +Materials: https://coderefinery.github.io/train-the-trainer/feedback-and-impact/ + +**Questions to audience** + +- What tricks/techniques have you tried in your teaching or seen in someone else's teaching that you think have been particularly effective in collecting feedback from learners? + - preparing a survey and emailing it to participants as soon as the event ends (usually get <50% of answers but it's a representative enough sample) + - do engage with the audience, give them the time to get the courage to speak up + - Be the audience yourself + - yes! some problems/issues I don't notice as instructor, only as listener + - Have time (e.g. 5 min) in the session to fill out the feedback form + - If the course/workshop has several days/sections do a couple questions every change, then a full one afterwards + - "Traffic light" feedback (e.g. for pacing or progress on exercises): give each learner two different coloured post-it notes for in-person, or use emoji for online, to indicate a current status +- Can you give tips or share your experiences about how to convert feedback into changes or actionable items? + - ask questions about things you know you don't know + - “Don’t let the noise of others’ opinions drown out your own inner voice.” — Steve Jobs +- When people ask questions / get stuck with a specific step. Is there a typo I can change there and then in the workbook? + - Being able to fix small things on the fly helps sometimes, otherwise open issues if working on github + - If multiple people have the same question, then this is an indication that I should look at this in more detail +- How do you measure the impact of your teaching? Any tips or experiences about what you have tried or seen other courses do? + - "How likely are you to recommend this workshop to others? (0/5)" + - Check the 'Garbage Out' bin, what you find there will be what went across. The rest will be history... +- Anybody knows of good resources on survey design? Please link them here. + - "Our job is to figure out what they're going to want before they do... Our task is to read things that are not yet on the page." - Steve Jobs + +**Questions/Discussion points** + +- Feedback is necessary to design good lessons. Improvement can only be done iteratively. So the faster the iteration (design/teach), the better. But on the other hand, I cannot constantly bomb our community with training event emails. So I would like to try proposing a course many times a year, but I don't want to spam everybody many times a year. + - :+1: + - With CR we also have a calendar that can be imported to different calendar applications, where we add all workshops: https://github.com/coderefinery/calendar/ +- Does an even split of too fast / too slow mean speed is about right?! + - I take it to mean "it's roughly where it should be". Would be better to accomdate the sides better though... (we do try to design for a broad audience: some easy stuff, some advanced stuff, so people can make their own path) + - It could also indicate that the prerequisites/scope are not well defined :+1: + - Based on long term surveys we also know though that even though the workshop might have been to fast, people appreciate having "heard things before and know where to find them later" + - perhaps the even split between too fast/too slow is ok only if the majority of votes goes for "just right" :+1: +- One of the most important disciplines in journalism is to challenge your working premises. (Bill Keller) This applies equally to learning as well. + - Participants can be encouraged to write some posts on LinkedIn. If it is helpful some blurbs can be created for pre and post-workshop to generate more traction for Code Refinery and future participation. + - Ask participants if they use Dev.to, hashnode etc to blog their work or use twitter etc to have a memory of their work. +- Do you have any suggestions for prerequisites? I try to make them clear, but occasionally people attend who clearly do not meet them. :+1: + - I guess it depends how much it matters for the workshop itself. If you have group exercises etc, it probably matters? , lecture style maybe not so much?; important is that the participants themselves know that prerequisites exist and if they meet them + - Sometimese people that do not meet the prerequisites join to get to "know what they don't know", find out where to find information on topics they might get interested in future etc + - Other suggestions? Viewpoints? :) + - Thank you - things for me to think about there :-) + - With CR's latest ideas, we try to make the prerequisites clear, but there is no capicity limit: it's OK if people drop by and are less than prepared: it's livestream, anyone can come. We try to have something for these people, too: learn what you are missing, why you might want to study more in the future. + - Any thoughts on applying this to a more practical focused course, with a total capacity limit (i.e. not like CodeRefinery). +- Everytime you do a course on CodeRefinery, think of it as trying to bake a new cake with an old recipe with no idea about the individual taste preferences of the one you bake the cake for. Then, you will not experience too many surprises. Fine-tuning the recipe for one cohort still remains the 'old recipe' as far as the next 'new cohort' will be concerned. C'est la vie. + - nice analogy! +- Question from chat: For examples 2 & 4, would you also consider using something like a Likert scale? E.g. Rate how well you agree with the statement "My code is more reusable as a result of attending a CodeRefinery workshop" (from 1 Strongly disagree to 5 Strongly agree) + - Thanks! I am new to Likert scale and will read up on it. In my experience numbered answers can be useful for reporting. But I also like questions where we ask for what actually to change. +- Comment from chat: Richard, your point crowns the point of having CodeRefinery, With Radovan's and Samantha's acquiescence assured, I would like to suggest you wear a crown going forward, especially for the CodeRefinery session. Do we have a deal ? + - I don't quite understand this + - I *think* it's a tongue-in-cheek-comment (joke) but I am not sure..... +- What is the ideal way to allow people to interact while course is going on in the main online session, i.e. without a breakout room? Taking a pause or discussion in the background? + - I've had some success with WhatsApp groups for a course - particually ones that run over 4 (or 2) sessions. + - A quick survey/quiz + - Question to the audience that we take time to answer but it helps to show the answers +--- + +### Wrapup + +- Thank you for active participation :) + - We'll continue answering questions after the workshop and make the cleaned up (no names etc) available from the materials +- Next session **Tuesday August 20, 9 CEST: Tools and techniques adopted in CodeRefinery workshops** + - we will talk about on-boarding, install help, roles, screensharing, sound, collaborative notes +- All workshop materials will stay available (after the full workshop also on Zenodo :tools:) +- CodeRefinery community: https://coderefinery.zulipchat.com/ +- If you want to co-teach with us in the upcoming (or next) CodeRefinery workshop (https://coderefinery.github.io/2024-09-10-workshop/); or just want to learn more about this opportunity: Send your name and e-mail address to support@coderefinery.org; we will contact you! + +### Feedback about todays session + +What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session: +- Lesson design approach +- I liked the backwards lesson design, gives a name to a practice I've already been doing :+1: :+1: +- Lessons from code refinery on lesson design. Learning about Sphinx. +- Collaborative notes and anonymized archive of notes. +- it's nice to have a community to discuss these kinds of problems +- Hearing the variety of tools people use for slides (PDF, Quarto, Beamer etc.) +- Good intro of the tools, the jargon and the pedagogical philosophy of teaching tech. +- The absolute openess in having everything publicly available - materials ofc but also questions, discussions, feedback, ... +- Thinking about all content being available publicly and as a git repo +- Thanks for explaining the HedgeDoc interface, with view and edit options + - Is there anyway to come back to this document later (e.g. tomorrow) and see what has changed since now? So I can see if any other questions have been asked/answered? + - There is a "revision" point under "Menu" up right, which shows you different versions of this document +- Modesty: the gentle art of enhancing your charm by pretending not to be aware of it. - Oliver Herford +- + + + +What one thing would you improve about this session? +- Perhaps some more interactivity but can be hard to plan and time + - We'll see what we can do. +- _Maybe_ mix the breakout groups up for each breakout session (although there are advantages to consistency too) :+1: + - yes, pros and cons! For me, having consistency worked well this time. + - Likely we will have different participants next week, and a bit of mixing will happen naturally. +- The pace of the presentations could be a little tighter (the pace is good for a discussion though) +- Richard's voice was only 80% audible + - Sorry to hear that. It seemed fine on my end. Will check better for next session. +- Hands on simulation and collaborative notes +- I found it difficult to follow the presentation and the collaborative notes at the same time + - We will highlight the collaborative notes more in the next session. Our strategy usually is to say to focus on the "teaching part" and use the notes only when needed. Since you can go back and also check the notes later. + - My problem is that I want to follow both since I don't want to miss out on anything. As such, I have both windows (zoom and the notes) open side-by-side. Since there is near-constant real-time typing in the editor, and as such visible movement on screen, I get constantly distracted. This makes following the event quite exhausting. +- Heads up to participants on using the break out rooms on voice interaction and screen sharing. + - Do you mean that we should have mentioned it more clearly in the pre workshop email? +- I found it hard to follow with so many things going on at once... + - A collaborative document being changed at the same time as... + - Someone speaking and explaining content at the same time as... + - Chat in a different application at the same time as... + - Content changing in a termin application. + - Thank you for the feedback. We will remove the Zoom chat out for the next session and explain the use of the collaborative notes more. +- Make more use of defining and then making sure the learning objectives are met + - True we did not talk about them much, will pick that up better for next session. +- UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. - Dennis Ritchie. You need to do a lot to prove that to be wrong, simply put. +- Allocate some time for learners to type in the answers so that we don't have to listen and type at the same time. + +Any other comments? +- It's great to hear other people's experience + - Good to hear :) +- Looking to meet you onsite if there are any events and get more emails from you :) + - We will keep you informed :) +- Thanks for putting this together, I got a lot of inspiration for my own courses + - Good to hear :) +- I didn't know where to ask questions. It would work best *for me* to do it in zoom chat as that's the application that I'm watching in.. + - Sorry for that, just to figure out why: Did you join a bit late? + - No. Perhaps I just missed that or it was too quick for me or something? + - Ok, sorry. Will try to make this more clear in next session. + - Perhaps also because there were so many things going on and jumping around. For me, the zoom chat is the constant (and obvious) place to ask questions while watching a shared screen, trying to find the right place in a moving collaborative document is difficult. It tears my attention into too many pieces. :+1: +- Had a lot of content that assumed extant knowledge that I didn’t have. This wasn’t in the pre-requisites. + - Do you have examples? + - Yes! The code refinery templates and even just the way of doing that. I was expecting more on "when designing a lesson you should think about these steps" rather than this is how we do it and this is our tool for doing it. I guess I should have read the pre-workshop content better? + - Ok, thank you for your feedback. You are right that we actually had some content that for sure would have been easier to follow for people with background knowledge about a certain topic. + - "If you are in CodeRefinery TTT, you probably know what version control is and why it is important." - extant knowledge, why not just add a sentence or two? + - Please can you update in preparation for the next workshops so that I can decide whether or not they will be right for me? + - Yes, we will think more thoroughly about this and send the info in the next email going out Wed/Thu + - Thank you! +- Lots of the content was relevant to code refinery but not the wider topic (e.g. it was how to design a code refinery lesson and not how to design a lesson as stated in the session title) + - We thought of the content of showing one way of doing things, ie "what we have learned", if you have suggestions on how we could make that more clear on the event page, please let us know :) + - "in a code refinery lesson" in the lesson/workshop description? +- When you have pre-written “thank you for your active participation” it feels fake! + - He, that is true, did not think about that. Thank you for the feedback. I would not have added it if Radovan and Richard would not have provided good feedback from circling the rooms. +- I found it vague and disorganised and difficult to follow. It felt like the instructors were presenting the content for the first time and didn't know what to do next. + - Thank you for your feedback. This is not the first time we have this training, but it is the first time in this constellation/way. The way of teaching may also sometimes make it seem new to instructors. +- I really liked the active exchange with other participants, but I also would have enjoyed a bit more technical content in the presentations. In a sense it felt less like a 'training' and more like a get-together :+1:. + - Thank you for your feedback. We thought the name "workshop" would combine the training and exchange nature of this event. But maybe it didn't do so enough? Do you have suggestions on how to clarify it on the event page? + - Well, the 'train the trainer' title created the anticipation of being trained ;) don't get me wrong, I liked the exchange, but I felt that the training aspect fell a little short. imho the workshop would benefit from a little more (instructional) content that is presented in a more structured way by the instructors (as opposed to 'crowd-sourced knowledge' that is collated in a loose collection of questions, notes and links) + - Other than that, you could add another section on the main page, sth like 'Workshop structure: we aim for a mix of modular presentations and work in small groups. The latter will be done in breakout rooms - be prepared to switch on your camera and have a fruitful exchange with fellow participants!' + - Thank you for the suggestions, will add something like this :tools: + - > Added : https://github.com/coderefinery/train-the-trainer/commit/03308595436e636b3bb37ed9d1f0dee39eeccd0f +- My understanding (so far) of what (unlike the competition) CodeRefinery DOES NOT seek to exemplify - +https://images.ctfassets.net/rxqefefl3t5b/2k45BFtw4sBMlBfjr1OZ90/5c6ecd3628a43b0cdc79815f665e224a/Screenshot_2023-05-02_at_09.35.23.png?fl=progressive&q=80 +- My understanding of what (unlike the competition) today's session of CodeRefinery DID exemplify - Definition of 'Workshop' from the Oxford dictionary of the English language "a period of discussion and practical work on a particular subject, in which a group of people share their knowledge and experience" +- In my experience, even for the most seasoned Programmer coding, by its very nature, is nothing trivial, this being a simple straightforward fact just like there is no such thing as an egg which is a cube. I mean there is a reason why not just about everybody is a poet either. But, other minds have pointed this out without having to first explain why the universe is what it is in a way that could be understood without effort ... https://i.pinimg.com/originals/7b/7e/c4/7b7ec4b91d2cf9d8e1b064678d205467.jpg +- The inclusive environment feels very welcoming. Keep up the good work! + +**Thank you all for your feedback! Highly appreciated!** + +--- + +### Day 2 : Session 2 (20.08.24)- Tools and techniques adopted in CodeRefinery workshops + +#### :calendar: Schedule + +| Time (CEST) | Title | EEST (UTC+3) | BST (UTC+1) | +|---------------|---------------------------------------|---------------|---------------| +| 8.45 - 9.00 | Connecting time | 9.45 - 10.00 | 7.45 - 8.00 | +| 9.00 - 9.15 | Intro and Icebreaker | 10.00 - 10.15 | 8.00 - 8.15 | +| 9.15 - 9.25 | About CodeRefinery workshops | 10.15 - 10.25 | 8.15 - 8.25 | +| 9.25 - 9.55 | Collaborative notes and interaction | 10.25 - 10.55 | 8.25 - 8.55 | +| 9.55 - 10.10 | Break | 10.55 - 11.10 | 8.55 - 9.10 | +| 10.10 - 10.45 | Workshop overview, roles, onboarding | 11.10 - 11.45 | 9.10 - 9.45 | +| 10.45 - 11.05 | Sound | 11.45 - 12.05 | 9.45 - 10.05 | +| 11.05 - 11.20 | Break | 12.05 - 12.20 | 10.05 - 10.20 | +| 11.20 - 11.50 | How to prepare a quality screen-share | 12.20 - 12.50 | 10.20 - 10.50 | +| 11.50 - 12.00 | Outro and feedback | 12.50 - 13.00 | 10.50 - 11.00 | + + +#### :icecream: Icebreaker + +##### Check-in + +Which emoji best describes your current state of mind? [Emoji cheat sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) +- :-) +- https://media.istockphoto.com/id/148421550/vector/bored-emoticon.jpg?s=612x612&w=0&k=20&c=uo5KBTqdJZbBQb_Xldhzuovx5t08fHfGR7dw7TCk90I= +- :saluting_face: +- :sleepy: +- :coffee: +- :umbrella: +- :cocktail: :coffee: +- :seedling: +- :tired_face: +- :sun_with_face: +- 🥴 (:woozy_face: not converted?) +- :coffee: +- :sunflower: :book: +- :satisfied: +- :coffee: +- :coffee: +- 🥱:tired_face: +- :bread: - I am baking bread today so I have been kneading dough while listening! + +##### Introduction in breakoutrooms + +Name / Affiliation / Location + +##### Teaching + +- Do you teach and organize teaching alone or with others? What would you prefer and why? + - Coming together is a beginning; keeping together is progress; working together is success. – Edward Everett Hale + - These days always with others. Alone is easier to prepare but almost always is harder during it. + - Teaching with very diverse partners, it can be challenging to find a common language with people very different than you. + - I teach alone, in the future there will be more collaboration with multiple team members. Both approaches have their pros and cons. + - Both has its own distinct advantages + - Most of my teaching is on my own, as a freelancer its more expensive to work with colleagues than to deliever a course on my own. + - Teaching together, learns from each other, feedbacks to improve + - Not formally taught yet, only given presentations actually . + - collective teaching would benefit the teachers with collaborative curriculumn and experiences sharing. + + +- If applicable, have you seen any challenges when teaching together and how to overcome them? + - It actually requires preparation, + - Is it about teaching or about inspiring ? Discover the answer and get inspired ... + - It's like being in a band: you might be great at improvising and your band-partners might be great at improvising too, but a bit of rehearsing makes even the impro gig much better + - Need to plan before session, difficult if people don't 'plan' in the same way, e.g. with the same time frame. + - Heterogeneity in learners make it impossible to get the same result from everyone. + - In fact, the same applies to teachers :D + - Teaching together requires to have similar opinions on how to teach. I share vews only with ~40% of my colleagues I think. +- No Teaching experience but it is good to give the outline of the lessons beforehand and learning goals. + + +--- + +#### :question: Questions + +##### General / Practicalities + +- What is this document for? + - Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts) +- Will the material be made available? + - Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/ + - Can I share them with a colleague + - Yes please :) + - Can I resuse them in my own teaching? + - Yes please :) +- Will these sessions be recorded? + - No, but the materials (see above) should include everything needed for self-learning. +- Can I get a certificate for this workshop? + - You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended. +- How often will we be talking in breakout rooms? + - We'll have about one breakoutroom session per episode + - BR 1 : The Zoom chat does not work for the breakout room so we should take note of that. No webcam/mic = expect silence. + - Thanks for notifying! This was not intended. Turned the chat back on. + + + + +--- + +#### Episode 1: CodeRefinery + +Materials: https://coderefinery.github.io/train-the-trainer/coderefinery-intro/ + +- (questions continue here) +- Is there the plan to build capacity / be paid to deliever courses? + - We've discussed it but right now we don't have many people who could accept money to do this (and maybe shouldn't, because of their jobs). But, we would encourage others to use our materials as "independents" to deliver paid courses + - One idea we have had is that paid courses could be delivered through the DRA (link below), who we know. Basically, DRA could find instructors and handle the money transfers (If someone wanted a paid course, we could help find someone to do it through DRA or independently) + - :smile: +- Have you come across DRA, https://digital-research.academy/, Heidi Seibold, Joyce Kao who are doing similar work? I can connect you if you like. + - Yes we have been discussing about possible future collaborations and are already sending possible clients their way (we, as a project cannot take money) :+1: + - Excellent! :-D :smile: +- . + +#### Episode 2: Collaborative Notes + +Materials: https://coderefinery.github.io/train-the-trainer/collaborative-notes/ + +- So anyone can type anonymously? + - Yes, as long as you do not log in, you are Guest XXX + - And at least in our hedgedoc case you cannot log in so you will always be anonymous. You can do [name=xxx], to add your name to a comment + +- Test of +1 + - +1 :+1: :+1: + - :-1: a test + +- You are hosting your own version of HedgeDoc, and Hackmd.io is a similar (free) option. What are the limitations of the free hackmd.io? Should each center install their own HedgeDoc instance? + - It **seems** the free version of HackMD has gotten worse lately. It works still well enough with a few people editing at the same time. + +- Have there every been problems with the anonymity and CoC? + - We haven't had any issues so far. + - With a different anonymous tool in a bachelor course, we had issues with anonymous participants (participants were posting slurs and unsafe links). The course organiser decided to stop allowing anonymous tools. + +- Why not google documents? + - Google documents are actually setting a hard limit for simultaneous writing, no more than 100 concucurrent editors. I am unsure if microsoft onedrive word documents would allow more users writing at the same time. + +- What's the most people you have every had on HackMD / Hedgedoc? + - I believe about 200 active participants? + +- What are your thoughts on using the build-in Zoom Q&A? + - We haven't tried this, in part because the way we do streaming now (you'll see in session 4), participants aren't in Zoom so don't have access to that. The doc-format works pretty well though, when we keep it in this limited "write at end" format. + +- How do you see what has changed? e.g. if leave the session at the end, can I come back tomorrow and see X has been added? e.g. a diff for this maybe? + - In the menu up right there is revision, it does show the document and changes at different time step :+1: Thanks! + - We recommend people only write at the bottom (and since we answer things live), so as a first level approximation you find where you were and read below that. Think of it more like chat than a full document. (Yes, we do revise questions at the end) + +- How about flinga boards or similar tools? + - My take is that the simplicity of a simple text document wins over free-form in-person-workshop-like tools. + - There's miro, can be a bit confusing though + +- How does this work with small groups, e.g. 10-15 people? + - Good question: it can be hard if people aren't rigorous about it, people start only using chat/voice. So there seems to be some lower bound in size but we haven't tested this much + - And if the instructors never screenshare it to show what goes on it, then seems to be less used. + - And if there aren't other people to read/answer it during the session (perhaps less likely in a small course), it seems to be less used. + + +:::info +Breakoutrooms until xx:55 + +Exercise/discussion: https://coderefinery.github.io/train-the-trainer/collaborative-notes/#exercise +::: + +- Breakout room 1: + * Use of etherpad for collaborative discussion. + * Use of slido for polling and quizzing. + * Presemo as a slido alternative (https://www.aalto.fi/en/services/presemo-a-fully-web-based-classroom-participation-system) + * Use of text based approach for questions rather than live can be helpful if there is a language barrier issue. + - A good teaching session which had many questions coming spontaneously to the teacher is a non-entity of sorts. If the overall flow of feedback / questions increases it could indicate that the session will not prove to be a helpful experience. A signal that generates noise is, well, noise, if calling a spade a spade signals anything. Note that the 'overall' bit and the 'to the teacher' aspect are important. Both the best and the worst teaching session have two things in common: a teacher, and the fact that NO Materials of any kind are used, ie speech is the only channel of communication via a common language. The only difference is that it is not the same teacher, at least not in the same session at the same time. + + Another less mentioned, but perhaps more relevant indicator of a great session is the simple fact that at the end of the session EVERYONE feels empowered, NOT tired. This is not an easy to quantify thing, but screams out the quality of the experience loud. More often then not, such sessions differ little from each other, apart from in terms of the theme / topic and the participant mix. It ends up being the 'keep your cake and eat it too,' of sorts, not quite the far less amusing post-bombardment devastation scenario in the wake of a take it or leave it go at anything. + + - profanity in collaborative documents where people can add content anonymously could be a problem (happens very rarely, fortunately and somewhat surprisingly) + +- Breakout Room 2: + - Good experiences with Zoom polls + - Handling questions in hybrid setups: all participants (on-site and online) ask questions in written form + - Collaborative notes can be challenging when conducting a course alone (without teaching assistants) :+1: + - Providing a method to ask questions anonymously can make asking easier for shy participants + - Questions can give valuable feedback on how the course is going + - Online collaborative whiteboarding platforms such as Miro + - Large monitors are useful for this not to have to drag a "periscope" around + + + + +- Room 4 + - good experience with whatsapp chat for questions. since most learners have the app already and one thing less to install and set up + - reply to question is a way to handle multiple questions at the same time but it works well for smaller groups + - experience with collaborative docs in in-person workshops: voice questions might "win" over the document + - "seeding" questions may help to not have an empty document + - it can help somebody to start and create a structure which helps others to see and follow + - we discussed the Carpentries sticky notes system (red sticky note: signal tech issues and use for feedback, green sticky note: signal that exercise worked and for positive feedback) + - Nice summary of sticky notes system: https://teachtogether.tech/en/#s:classroom-sticky-notes :+1: + - What is the success rate of in-person workshops after COVID? Discussion: Teachers prefer in person and learners prefer remote or recorded to spool back and relearn. + + +- Room 5 + + - Good experience with Collaborative tools as HackMD and HedgeDoc while teaching with no bad feedback + - When used with smaller groups works best as one-way, like sharing links with students and so on + - Needs to be done as a team, quite difficult if teaching alone + - Most useful when online/hybrid + - Anonymisity is important for transparent feedback and no biasis in classrooms + - Not very collaborative but useful to share history or jupyter notebooks live https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush + - Used Flinga before that seems like Figma and also onsite teaching using sticky notes + - There's miro.com but can be a bit confusing, more for brainstorming than for teaching + - Using quizzes apps like Kahoot is beneficial while teaching to have more engaging students + - + +- Room 6 + - teaching teenagers (in presence) but using shared pad becomes quickly very chaotic, so only usable for short moments when answering very precise questions + - Yeah, I can imagine. For CR we try to keep it in this very limited format (all questions bullet points, only add to the end) and I think that helps. + - using shared notepad for small workshop (5-10 people) to explore common thematic (mainly technical) to keep a shared notes and condense aftwerward (and publish on wiki to archive) + - Difference between teaching in person and online. Some people prefer in-person and sometimes you have no option but to organise it online. + - There are sometimes cultural differences and learners feel shy to ask / question the knowledge of the Teacher, so shared notes are a good way to safely ask questions. + + +Questions continue: + +- Have we demonstrated how we do polls in HedgeDoc? Add your vote by adding an `o` + - yes: oooo *(in session 1)* + - no: + - :smile: + - not sure: o + + +#### Episode 3: One workshop, many perspectives + +Materials: https://coderefinery.github.io/train-the-trainer/overview/ +Next CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/ + + +:::info +#### Exercise until xx:39 +https://coderefinery.github.io/train-the-trainer/overview/#discussion +::: +- Room 1 + - Send pre-workshop email with pre-requisite instructions on what should be set-up beforehand. + - But, also mention that if help is needed for set-up, we will be ready before the session officially starts. + - Discussion on whether we push to work in a pre-ready environment (e.g. Binder, Colab) or in their own environment. + - Lots of help needed both before and after. + - Installations: as much as we can provide ready made environments for the learners, maybe installations will be something that the learners will face sooner or later. Maybe one should teach more about installations? + - My only cherished role in a teaching-learning session is the that of one who is living the moment as if there were no tomorrow. What cuts all ways really is that “By failing to prepare, you are preparing to fail.” ― Benjamin Franklin. A helpful motto: “When one teaches, two learn.” — Robert Heinlein. The best experience cannot be given, it can only be allowed to flow its way, so get out of its way. + + +- Room 2 + - Frequently, a single person fills all the roles for a single or multi-day workshop + - Collaboration with different centers/ universities can be challenging + - Preparing participants: it's essential for the instructor to go through the demos and be sure that they will work (no unpleasant surprises live). This can be extended to advance-prep for participants. + - Best experience is to hear (live or in feedback notes) some positive things directed at you :) + - Fully prepared environments (eg self-hosted JupyterHub) can make preparation for participants easy + + +- Room 3 + - Some students have problems with setuping the environment. Maybe having a step by step instructions could help. But some students don't want to "start" the course before hand. + - Preparing the environemnt before hand ensures everyone is onboard from day 1. The same thing happend in CSC training sessions and another session Peng attended. + + - Had experience in attending as teacher and student in previous workshops + +- Room 4 + - knowing the background of the audience is helpful + - Try and ask in advance of the background of the audience. Do a poll at the start of the workshop. In person one can do it interactive. + - among co-instructors: discuss topics and flow + - if more people are involved, it can help changing roles from time to time to see different perspectives + - preparation is key + - Circulate instructions beforehand + - Do a poll before session: Have you installed (QGIS) successfully? + - Push hard to do this in the welcome email + - communicate clearly to the participants + - +- Room 5 + - We've all taken most roles + - How to prepare in advance? + - Meet and discuss once or twice + - Make a pre-survey to check for interest and background + - Going through the materials + - Checking the toolkit (zoom) + - Agree on the reponsibilities and back-up plans (bit of scenarios planning) + - How to prepare trainings in advance? + - Collect resources and prepare the workshop plan + - Having the material readily available online ans sharing it + - Making a pre-survey + - What was the best workshop experience for you as learner, helper or instructor? What made it great? + - learner + - Engaging and practical workshop with more exercices and follow-up theoretical part explanations + - helper + - When the instructor is well prepared and as helper ther's only typos to fix and interesting questions to answer + - Assist the instructor, coordinate the collaborative notes, and make sure that the time is respected + - instructor + - I have a colleague whom I've ran the same workshop a few times already, goes quite smoothly now and we've made a few changes. Hard to reach that point with new colleagues but getting there + - Students/participants were engaging with the material and many good feedback collected even some of them asked for the next workshop + + +- Room 6 + - What has made a great experience for you as a learner/helper/instructor? + - Common ground between learners & teachers + - + - Motivation + - Teaching is much more enjoyable when the learners want to be there + - I spend a lot of time at the start of a workshop making sure learners feel that the content is possible for them to understand and master + + +Poll: I have joined a CodeRefinery workshop before: (add an `o` for your answer) +- yes (within last 2 years): ooooooo +- yes (longer time ago): oo +- no: oooooooo +- + + +(questions would continue below:) +- What is the motivation / advantages of streaming workshop versus using zoom? + - We'll cover this more in week 4, but roughly: zoom became unmanageable and essentially quiet once things got big. Streaming allowed "one to many" communication with no limit, and collab notes allowed better interaction anyway. By separating the rooms, it was more pleasant to teach. Videos could be released immediately since there was no risk of privacy of participants. There could still be in-person/online small groups who have "watching parties." +- What are the blue red and green font colors here, does it symbolify anything or just a convention HedgeDoc uses? + - Visual separation of formatting, mostly. (It helps to quickly realize you've missed/ mistyped a control Markdown symbol etc.) + - Yeah, it's bascically "code highlighting" for markdown. No special meaning but quite convenient for us. +- Is this next workshop only for team leads or also open for helpers and coordinators? + - You mean the next session of this workshop or the upcoming "CodeRefinery workshop"(this one: https://coderefinery.github.io/2024-09-10-workshop/)? + - The upcoming workshop coordinators are alredy working, but can be joined if you are interested + - As helper roles we currently only have "collaborative notes helper", which is all about helping to answer questions in the collaborative notes + - We do have some co-teaching slots open :) + - If interested: join the discussion in our chat: https://coderefinery.zulipchat.com/#narrow/stream/316508-coderefinery-tools-workshop/topic/Fall.202024.20CodeRefinery.20workshop + +- Can a person have multiple roles in a workshop as a helper and a teacher? + - Yes, many teachers also contribute to the rest of the workshop by answering questions in collaborative notes. :+1: + - Some teachers also host a local classroom in week one and do their teaching in week two of the workshop + - Roles that do not go well together are broadcaster/director/host and instructor (goes well until there is a problem; co-teaching solves that partly) + + +#### Episode 4: Sound +https://coderefinery.github.io/train-the-trainer/sound/ + +- To me, Richard is a bit quieter than the other two :+1: :+1: :+1: + - to elaborate: I think that the audio coming from him is missing some mids + - Do you have any links about this kind of evaluation and adjustment? + +- Do you suggest / recommend a specific headset(s) with mounted microphone? + - in our experience headsets with a microphone will almost always be better than a separate microphone sitting on the desk or in the monitor + - + +- Speakers have different tones of voice and speaking styles, is there a recommendation or experience from CR workshops for how this is adjusted and catered to environemnts for listeners? + - Yeah, people's voices are different and we haven't gone as far as voice training or improving. + +- How to change the volume for speakers? Tried Zoom settings and system settings and didn't help. + - From linux I can use different pulsemixers `pavucontrol`, `pulsemixer` to set the gain to above 100%. I'm not sure the equivalent on other OSs but + +--- + +:::info + +Exercise until xx:10 +https://coderefinery.github.io/train-the-trainer/sound/#exercises +::: + +- room 1 + + - Practically, no typical headset is designed or can capture the technical purity of human voice within its natural environment. But one needs to understand the polar pattern of the (specific) microphone or how much of the signal will be picked up by the microphone from different directions, a sine qua non when it comes to mitigating unwanted sound sources to bleed into the signal. + +For best results, keep the right direction & distance to your (directional) mic. Usually, that’s between 15-30 cm to get get a natural sound. A microphone records everything it can, also silence, so check the headphone output BEFORE adjusting the gain, in some specific cases aim for a dry sound, ie the influence of the room or how audible the room is on the recording ! Finally, adjust the mix between dry and room sound, or change the frequency response in tandem using a compressor to reduce the dynamic range of a signal for a more consistent listening experience = the quietest parts of your signal will appear louder by reducing the loudest parts. + +It is all about one thing and one thing only - love your voice, let people fall in love with the acoustic quality of your charm. So remember: GIGO, it matters! + +- Room 3 + - Had different headsets and we could see the difference (bluetooth low quality) + - How to change the volume? + - It's surprisingly hard to get more control than the basic slider you see in the apps! You need to look. + +- room 4 + - headset is probably better listening experience but they can be uncomfortable to wear during long meeting days :+1: + - Yeah. Luckily only instructors + - Therefore breaks are non-negotiable + - loud keyboard can be an issue + - if one has a silent room that does not echo, it can be ok to teach without headset + - on Linux I am using `pulsemixer` to adjust levels and `pavucontrol` to change outputs/sources + - mic modes on mac + - check default microphone for zoom. + + - room 5 + - Most tricks help tuning yourself but hard to do it as a group. Perhaps doing a short recording. + - Yeah. Some independent recording/playing aronud, but also asking for advice. I would do small group/one-on-one things. + - Background noises cancellation tools or wise choice of quiet environments + - Audio check with colleagues or through the app with the audience saying numbers for example + - Zoom or Teams have sound checks but work different in the app than the browser. They also work different across Operating systems + - Some sound issues might be related to network speed or stability, also to RAM available. Worthwhile to try and control those as well + - Make it welcoming for the audience to give you feedback on the audio and other settings, give reminders + + +#### Episode 5: How to prepare a quality screen-share + +Materials: https://coderefinery.github.io/train-the-trainer/screenshare/ + +- If your Zoom does not support "share portion of screen", sharing a tab and resizing it to portrait for yourself is a possible workaround (this at least works when joining the call from Chromium browser) + - Another workaround is to use an editor/IDE that displays multiple panels in one window and can show a web page, code files and terminal session +10 +- Is 'share a portion of your screen' where you draw a box in Zoom to share a section? + - yes :+1: + + +- When using zsh, one can run something like this in a terminal + ``` + tail -n $NLASTCOMMANDS -f ~/.zsh_history | sed 's/^.............../LAST COMMAND:/g' + ``` + (I place this in a window under the main terminal, I use i3) + +- I am a bit confused on what platform you are putting this code? + - Radovan is using Linux with (I think) the "i3 window manager". It can be quite involved and there is lots of personal customization here. +- When teaching with a custom prompt, is it worth starting with the default (that your learners will see) and explicitly mentioning "I change these things to make it clearer when teaching" + - One should always comment on what may be different. Thing is "default" may look different for many people :+1: + - "I am _not_ going to teach you how to customise your prompt, but here's an online tutorial, be prepared to lose several days of your life..." :laughing: + + +- Now I can't see the last line in the terminal + - Yep, that's a problem. It can be good to keep a buffer on the bottom of the screen. + - If you move your mouse outside the Zoom window, the controls should go away. But still a good note. + - My mouse was on another screen. + - Ok, thanks. + - I think one can also make the zoom bars not auto-hide (then it won't display under), but that is annoying also since it wastes space. + + +- Does anybody still use shellshare? Does it work? + - We in CR haven't used it much but we have seen it. + +- Does the stacking of the screens work on windows? + - Don't know unfortunately + + + +:::info +Exercises (done together) +https://coderefinery.github.io/train-the-trainer/screenshare/#exercises + +Write your cool tips and ideas below. +Stay after xx:00, to +::: + +- To be safe, I have created on my computer an account that I use only for teaching, so I do not need to do any manual set up +- share history or jupyter notebooks live (5-10 secs refresh rate) into a git repo. Share the link with the learners so they can catch up https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush + +--- + +### Wrapup + +- Next session Tuesday August 27 9 CEST: About teaching & cool things we all would like to share +- All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development) +- CodeRefinery community: https://coderefinery.zulipchat.com/ +- Cool gems session: If you want to share something, please edit your registration and fill it in there (link to modify in registration confirmation); or e-mail to support@coderefinery.org +- If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14:00 (Europe/Stockholm time) + + +### Feedback about todays session + +What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session: +- Sound and screen share optimization as well as relevant tools and good practices for online instruction. “While you may be unable to control your users’ mindset, you can anticipate it, and make sure that your user experience caters to it.” - Jonathan Cherki +- Nice opportunity to (re)think about my online teaching setup :+1: :+1: :+1: +- Other ways to display command history :+1: +- Did not know that bluetooth gear had so much latency! :+1: +- A good reminder about headsets with microphones +- Nice and friendly teaching. Thank you! +- Screen share with command history and terminal customisation +- Really useful tips on sound and screen sharing :+1: +- Nice experience share +- very useful and practical tips! +- Easy to follow along and filled with useful tips on sound, video etc. +- + +What one thing would you improve about this session? +- Just digging to find something: I have read some of the things you have talked about here already in some blog posts, so perhaps these sessions are not as shokingly full of new content as I imagined (but actually sharing experiences is something I can't do by reading a blog post) + - Perhaps: could you link some blog posts or other sources for what you have discussed so far? If it makes sense. Not sure. +- Talking about interface optimization approaches, which applies to sound as much as to visuals or any other aspect either for that matter, it might offer a perspective to bear in mind the concept of introducing asymptotic complexity increment. The latter would mean the goal is measuring how fast the effort of engaging, on one or more of the three parallel levels of interaction, must change to reach higher levels of partial certainty on the correctness of the implementation of the method in question, in this case the pedagogical paradigm. For the former, lower is better I guess, or in this case, in the intended sense, slower is faster. Let us consider an abstract example: People liked using the search engine Google (a Google session to put it in a fancy way) in the early days because it was as simple as it could get, a literally featureless entry point with no bells and whistles. That was the level of its visible complexity, or rather Google set a bar as low as it one could have, and then any higher point of VISIBLE complexity that was to be introduced, such a move would only be on the path of an asymptotic curve curving towards the set bar, never reaching it, as far as the entry point is concerned. We still see the same level of complexity when we fire up google and we never feel distracted to start with, except for the rather forgivable nuisance of the GDPR conformity pop-up notice which appears only AFTER the first move has been made, and thankfully it works plain and simple from there on (unless one starts feeling lucky, pun intended). Now, think about Youtube ... the user experience complexity is a totally different matter, the same company today (unfortunately) yet one now has a steadily worsening engagement experience. Good learning sessions tend to be more of the Google search engine experience and a far cry from the current Youtube trend I would opine. Or, to sum it up and keep it sweet and simple, it helps to identify the limits of human-human and human-technology interaction, within the framework of any applicable technology-technology interaction and joy is the result of respecting those limits. Wishful thinking ? +- Bring the cat back! + - I wish it came, but it's been resting all morning! I don't bother it or stage apperances... +- Maybe having a digest/ summary of previous iterations of this session might be interesting. I feel a lot of experiences have been exchanged and a lot of techniques/ tools have been mentioned. Spending some time in compiling this into a selected list and adding it as content to the course itself might be worthwhile. + - Good idea! We will write a blog post about this workshop and will include a summary of all discussions there :) +- Possibly have some command line examples from Windows rather than (just) *nix? I will look at the screenshots after the session. :+1: :+1: + - Also, a thought if you do do breakout sessions with this work, do one for Unix, one for Windows, one for Mac as an option. +- I could not follow the part Radovan showed codes (Radovan is using Linux with (I think) the "i3 window manager".) +- .. + +Any other comments? +- Looking forward to the topics of following sessions. +- Looking forward to the next sessions! +- Thank you! +- Relax, nothing else matters, live a life and have fun ! If you obey all the rules you may end up missing all the fun. 'The best way to predict your future is to create it.' - Abraham Lincoln :+1: + + +### Day 3 : sessiion 3 (27.08.24) - "About teaching and cool things we all would like to share" + +#### :calendar: Schedule + +| Time (CEST) | Title | EEST (UTC+3) | BST (UTC+1) | +|---------------|---------------------------------------|---------------|---------------| +| 8.45 - 9.00 | Connecting time | 9.45 - 10.00 | 7.45 - 8.00 | +| 9.00 - 9.15 | Intro and Icebreaker | 10.00 - 10.15 | 8.00 - 8.15 | +| 9.15 - 9.45 | Computational thinking | 10.15 - 10.45| 8.15 - 8.45 | +| 9.45 - 10.00 | Break | 10.25 - 11.00 | 8.25 - 9.00 | +| 10.00 - 10.30| Teaching philosophies | 11.00 - 11.30 | 9.00 - 9.30 | +| 10.30 - 11.00 | Co-teaching | 11.30 - 12.00 | 9.30 - 10.00 | +| 11.00 - 11.15 | Break | 12.00 - 12.15 | 10.00 - 10.15 | +| 11.15 - 11.50 | Sharing teaching gems (voluntary) | 12.15 - 12.50 | 10.15 - 10.50 | +| 11.50 - 12.00 | Outro and feedback | 12.50 - 13.00 | 10.50 - 11.00 | + + +#### :icecream: Icebreaker + +##### Check-in + +Which emoji best describes your current state of mind? [Emoji cheat sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) +- ... +- :sleeping: +- :coffee:+2 +- :robot: +- Still little sleeppy :) +- 🥴 (:woozy_face: still not converted 🤷‍♂️) +- Our planet could be a cube. It has six sides to it. It must be a cube. A cube it is, this Blue Planet ... just wondering ... +- 🦾 +- :sweat_smile: +- computer says no :-) some network trouble +- running late, and participating from a :train2: + + +##### Introduction in breakoutrooms + +Name / Affiliation / Location + +##### Best classroom experiences + +As a learner or teacher; what was the best workshop/lesson/seminar you have attended? What made the experience great? + +- Room 1 + - First summer HPC streamed workshop (as a teacher). Somehow the first felt the best + - CSC HPC summer workshop + - story telling teaching approach +- Room 2 + - NVIDIA DLI Course on Deep Learning + - very enthusiastic instructor + - intuitive and very accessible way of showing technical details and fostering deeper understanding + - a lot of hands-on material and smaller coding exercises + - Anything as long as its interactive and somehow enjoyable from both teacher and learner sides +- Room 4: + - EPCC MPI Distributed training workshop. + - Lots of hand on coding / experience gained. + - Very interactive instructor who also discussed ideas for more personalised cases of distributed computing. + - Coderefinery RSE course + - relevance of topic to my current work. + - Dynamic / friendly / positive teaching style. + - Modular Code Development; very instructive + - Some CSC courses / LinkedIn learning courses + - up to date materials and topics. + - Good way to merge theory with practicalities without making learner feel bored (Example: Jonathan Reichental) + - Challenging information to learn more and research about the topic + - Trainers are the experts in the field + + +:::success + +##### Episode on teaching gems + +If you want to share or demo something about tools and techniques you have found helpful in your teaching, please add your name/initials and rough topic below for smooth transition. + +> Note: It does not have to be your tool or your idea, this episode is meant to share experiences and discover new things. You also do not need any slides or materials, a story will do fine :) +> Length of the stories will be depending on interest, but be prepared to fit it into 3 min (shortest possible). + +- RD: teaching clock +- RB: [Containerized teaching setup](https://github.com/bast/teaching-setup) + - Isolated home dir is a good idea! +- AVM: [Screenkey for showing keyboard shortcuts](https://www.thregr.org/wavexx/software/screenkey) + +::: + +--- + +### :question: Questions + +#### General / Practicalities + +- What is this document for? + - Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts) +- Will the material be made available? + - Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/ + - Can I share them with a colleague + - Yes please :) + - Can I resuse them in my own teaching? + - Yes please :) +- Will these sessions be recorded? + - No, but the materials (see above) should include everything needed for self-learning. +- Can I get a certificate for this workshop? + - You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended. +- How often will we be talking in breakout rooms? + - We'll have about one breakoutroom session per episode + + +--- + +#### Episode 1 : Computational thinking + +Materials: https://coderefinery.github.io/train-the-trainer/computational-thinking/ (Link to slides in the middle of material) + +##### Questions to audience + +How might breaking down a complex problem into smaller parts change your approach to problem-solving in your current projects? + +- Avoids cognitive overload +- I used to give an example about this in workshops of cutting long tree into pieces from top to avoid that it falls and destroy a house bloc. +- Easier to start on something small +- Each individual part is familiar and can take existing solutions. +- Only focus on the new things +- One can lose oversight of where is supposed to be getting to due to problems with summation of biases introduced during the solving of the parts. +- . + +Can you think of a research project where identifying patterns in your data led to new insights or breakthroughs? +- Multi-targeted drug design where you need to identify both chemical and biological pathways/patterns +- Distilling complex physics problems into simpler 1D statistics is very often done. +- I used to do bioinformatics, pretty much everything in biology is about patterns in strings of charachters (DNA, proteins). Finding those patterns and using them is the way to go +- Pattern recognition DOES NOT lead to new insight, it is new insight which allows for the recognition of a 'pattern', the latter being an allocation of possible bias. +- +- .. + +What challenges do you face when trying to simplify complex concepts in your field, and how do you decide which details to focus on? + +- Absence of a terminology / jargon to describe a new idea. :+1: +- Similar to above, when teaching often students know what they want to achive, but don't have the termonology to express it, so working through what they want is helpful, after teaching them some termonology. +- Whatever is most useful to the learner first? +- I work with researchers in different fields. I don't always fully understand their domain knowledge but I can take the basiscs or generalities and get code that works for them +- A very practical problem is trying to resist going for a coffee in the midst of taking a shot at a complex concept, in the hope that the true details are to be found in the coffee. +- not all information is easy to find or a lot of conflicting information or even sometimes imformation explosion + + +How do you determine the priority of tasks when designing algorithms for your academic projects, and what criteria do you use to ensure that the most critical tasks are addressed first? + +- Working chronologically when going through a problem - start at the beginning. +- What gives the more insight with the least effort can be a nice start +- Talk to colleagues and Subject matter experts to understand various perspective to decide and prioritize. +- Logic will get you from A to B. Imagination will take you everywhere. - Albert Einstein. +- .. + +##### Questions from the audience + +- About the 4 core concepts, is this based on the model of how human brain works and perceives vision / abstract ideas? + - I don't know if it's based on how the brain works, but it's related to creating a framework for solving programming programs that has been extrapolated to solve any other problem as well. + +- Devil's advocate question: cooking (by recipe) actually employs all four principles outlined here and has done so since before the advent of computers. Why then is this concept presented as "computational"? + - Random aside, this is an interesting connection to our "cooking metaphor to HPC" +- Devil's answer to the Devil's advocate: Great question, cooking, as far as the act happens in the Devil's kitchen, does not employ numerical algorithms. The Devil introduced the computer precisely to make man lose apetite for that what is cooked in the Devil's kitchen to be served to all. Only then can the Devil eat the cake and keep it too ... + - Well, an algorithm without numbers is still an algorithm, i.e. a set of rules :) + +- Are there other names for this technique? I may have missed something crucial, but it strikes me as 'logical thinking' in a way. + - Yes, you could also just see it as problem solving. Most people know how to do it and if you've worked with programming, you've probably applied it. It can be the case that it's very obvious to some, but not to others. + +- Any chance we can ge a link to the slides? + - They are in the course material: https://coderefinery.github.io/train-the-trainer/computational-thinking/ :thumbs_up: + + +##### Exercise questions to discuss + +1. Conceptually would the strategies provided by computational thinking help you in completing tasks more efficiently? +- Room 1: + - divide and conquer technique + - We discussed what happens if you *don't* use these, since they are so natural +- Room 2: + - in some cases yes, if the task is not too small + - not sure if more efficiently but it does help at least getting strted + - Computational thinking is an extension of what others have called solutionism: the belief that any given problem can be solved by the application of computation. Whatever the practical or social problem we face, there is an app for it. - James Bridle +- Room 3: + - Helps in starting the task. + - For many it is the normal way to do problem solving. Also in Agile & Scrum methodlogies. +- Room 4: + - Yes, it helped me during my scientific research to manage multiple projects and research publications simultaneously. + - + + +2. Do you think that the effectiveness of computational thinking depends on the person’s personality type? +- Room 1: + - yes, we agree it's quite different. But good vision and motivation this can be effective +- Room 2: + - yes, laying out all the steps necessary to achieve an overall goal can be very daunting; some people are not good at/ comfortable with following fine-grained instructions + - once the problem is broken down, different personalities might choose different ways to tackle the parts + - The degree to which something, that is a result of what one means by 'Computational Thinking,' is successful in producing a desired result, that is success, cannot be a function of personality. +- Room 3: + - Yes. Different people have different ways to communicate. + - Online tools vs pen and paper +- Room 4: + - We are all agree that it depends on the personality type but it could be learned and trained + +3. Would this type of thinking be an option for you to integrate into your current workflow? +- Room 1: + - Yes; we didn't know the name explicitly; but we use it + - It's quite important for +- Room 2: + - I'm already doing it implicitly :smile: :+1: :+1: + - Writing a program is like writing a song, its all about the tune, lyrics are merely the necessary nuisance a coder needs to put up with. The latter can, if so written, result in a lot of noise. +- Room 3: + - Easy if you are working alone. But different team may have their own ways of working (inertia). One way would be then to gradually show the rest of the team its effectiveness. + - https://teamtopologies.com/key-concepts + +- Room 4: + - We are using it in our daily life so it's already an option for us, only the terminologies are a bit new. + + +#### Episode 2 : Teaching philosophies + +Materials: https://coderefinery.github.io/train-the-trainer/teaching-philosophies/ + +Questions to discuss: +- Share your approach to teaching and your teaching philosophy with your group. +- Please share your tricks and solutions in the live document for others. + +Additional ice-breaker questions: +- What is your motivation for taking this training? +- How structured or informal are your own teaching needs? +- What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching? +- What other skills need to be taught, but academic teaching isn’t the right setting? + +#### Breakout Room exercise + +- Room1 + + - Motivation + - For best practices in teaching, learning from each other, collaboration + - Learning applied tech is like an apprecentiship: there is theory, but real learning happens by co-working with others. + - Worse is better: teach what can be used more quickly and it can be improved later + - + - I think there are two bits of teaching - teach the basics and terminology so people know what they want to know, and then teaching how to find out how to do things like Richard said - how to find answers yourself. + - Using Jupyter notebooks - good for learning a technique, but not for learning the basics. + - Possibly command line usage has a branding problem - "programming other programs"? + - the skills we learn in CR training are expected to stay , it is not exam oriented + +- Room 2 + - State objectives clearly and repeat them a few times + - Try to keep it informal, interactive, flexible + - Helps when having practical tasks in mind for the materials taught + - Leave some reasoning to the learner, not always giving full answers + - How to deal with frustration though: try some personal approaches, more clues... + - The mediocre teacher tells. The good teacher explains. The superior teacher demonstrates. The great teacher inspires. — William Arthur Ward + - Teaching kids to count is fine, but teaching them what counts is best. –Bob Talbert + +- Room 4 + - Question 1: What is your motivation for taking this training? + - Currently do instruction, wanting to improve as an instructor and helper when conducting software carpentries. + - Planning to start some side hustles providing online courses and why not joining the CR in the near future + - Question 2: How structured or informal are your own teaching needs? + - More recently, follow software carpentries, but look into what aspects can be tailored to keep to different time slots. + - I used to be more informal in the past, repetetive practice sessions. Would like to be more structured given the teaching tools. + - I've done life-coaching and some teaching but I feel i'm both of them + - Question 3: What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching? + - Smaller size, and more targetted. + - Collaborative tools and targeted audience working with small groups + - Academic probably focuses on an audience with a more focused/narrow background, while this style encompasses a wider audience. + - Academic teaching keeps theory and practical lab sessions very separate, whereas carpentries combine both. + - Question 4: What other skills need to be taught, but academic teaching isn’t the right setting? + - Public speaking, collaborative meeting skills + - Industrial cases and related work skills + + +#### Episode 3: Co-teaching + +Materials: https://coderefinery.github.io/train-the-trainer/co-teaching/ + +- In general: Co-teaching is a beast with at least two personalities each of which + * demand higher preparation requirements + * face remarkable complexity in terms of coteacher coordination + * in the virtual component face shortcomings related to the technical equipment and the failure of the human factor +* Co-teaching requires the framework of co-operative learning. Team teaching does not by default translate into parallel learning, and vice versa. + +- Re: CodeRefinery in-person beginnings -- I agree with the "didn't work so well in-person", I'm not sure if it's that we weren't as ready for it, or that the different characteristics made it not work so much + +- How do the downsides compare to a single instructor monologuing? + - That's a great question! The main difference is that a single instructor can teach himself to be good (i.e. not just boring monologuing) **alone**, while for teams of 2+ to work well, **everyone** needs to be baseline-competent. So the effort to avoid downsides gets reduced if (and only if) all team members share it. + + +:::info + +Exercise/Discussion: https://coderefinery.github.io/train-the-trainer/co-teaching/#exercise + +Questions: +- Have you already tried this or similar model in your teaching? +- Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best? +- Have you tried or seen a different model for two instructors to present? Please share with us how it works. +::: + +- room 1 + - We have tendend to do presenter/interviewer more + - challenges are co-teaching with different personalities +- room 2 + - Main challenge: finding enough personell :smile: + - It's not always possible/feasible to have colleagues co-teaching + - A combination of both, but presenter and interviewer could be difficult to plan an to follow + - Guide and demo-giver with technical / non-technical roles could be nice + - How to plan the guide and demo-giver + - First guide, then demo + - Demo, then guide describes + - Alternative model: main presenter + 'technical expert' + - main presenter introduces concepts from a birdseye view and passes on to the technical expert for additional details, experiences and answers to questions from the audience + - We frequently do a classical division: on person in presenting, one or more are answering questions in the chat; there is rarely any interaction between them however + +* As has been pointed out by Paolo Freire, in general, ‘education is suffering from narration sickness’ ... ‘The outstanding characteristic of this narrative education, then, is the sonority of words, not their transforming power’. Perhaps one approach could be to rephrase the question after having the answer: It is not apriori about the model implemented, it is about whether that what was implemented was judged aposteriori to have succeeded in becoming, or at least could pretend to have done so, the intended context matched model implementation it probably was computed to be. + +- room 4 + - the co-teaching approach does not seem to be widely practiced + - it can be interesting to see "mistakes" which are less likely to happen in solo-teaching? + - co-teaching can be nicer for audience but maybe more stress/anxiety for instructors to prepare? more stress in terms of not knowing all the questions in advance. less stress worrying about forgetting something. + + + +#### Teaching gems + +(scroll up to find the green box "Episode on teaching gems") + +What's your favorite way of teaching? Any nice tools you use? + +Has anyone found a nice online tool to draw? +- I love this tool suite https://excalideck.com/ + - For drawing https://excalidraw.com/ +- I have seen Miro ... +- I think the Code Refineries use something for their graphics that looks a bit 'cartoony' - but I cannot remember what it is called! + - Drawn on remarkable and then coloured and tidied up in Inkscape. :+1: +- I am a big fan of remarkable. I think sharing option is fairly good. Unfortunately bit expensive tool. + - true, for me it was worth it already for the pdf annotation for research papers, cannot read on computer screen +- https://webwhiteboard.com/ +- https://www.youtube.com/watch?v=4-l8MY5kYGc +- Figma and Kahoot are useful as well + +Screenkey: [Screenkey for showing keyboard shortcuts](https://www.thregr.org/wavexx/software/screenkey) +- Is there a Windows version people can recommend? + - I found this list of alternative for windows users like me: https://alternativeto.net/software/screenkey/ :+1: +- I sometimes use the on-screen keyboard already provided by the OS :+1: + +### Wrapup + +- Next session Tuesday September 3rd 9 CEST: About teaching & cool things we all would like to share +- All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development) +- CodeRefinery community: https://coderefinery.zulipchat.com/ +- If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14 CEST + +- Preparations for next week will be sent out by e-mail + +### Feedback about todays session + +What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session: +- The co-teaching lesson and experiences from others +- Discussions were quite good, had a nice group +- Breakout rooms and collaborative tools +- Computational thinking and co-teaching are interesting ideas! I have seen it before, but never knew or even recognized it was a method. +- Thanks for group discussions working with my chat only interaction! :smile: +- .. + +What one thing would you improve about this session? +- Minor point - it would be useful to have the teaching gmes box at the bottom of the document rather than the top - tricky to scroll between! In the end I opened two windows which was easier. + - Thanks, yes agree. Also had that problem, but did not want to move it in between. +- The meaning of teaching "philosophy" wasn't very clear, felt more like teaching "styles" + - Thank you, we will take that into consideration +- Some prepared slides to present for an intro about the topics + - You mean in addition to the materials? To use in the beginning of each session? +- The [*instructor views*](https://coderefinery.github.io/train-the-trainer/teaching-philosophies/#instructor-views) segment could be named as additional material, if it was not meant to be discussed within the course. + - Thank you, we will take that into consideration + +Any other comments? +- Keeping it short and sweet: If at first you don't succeed in teaching, try to explain it like you're talking to a room full of cats. Caveat: In a room full of computational thinkers maybe if you tell students that the brain is a computational device that is forbidden, they might get excited and start using it. + +### Day4: Session 4 (3.09.24) - Streaming and video editing + +#### :calendar: Schedule + Time (CEST) | Title | EEST (UTC+3) | BST (UTC+1) | +|---------------|---------------------------------------|---------------|---------------| +| 8.45 - 9.00 | Connecting time | 9.45 - 10.00 | 7.45 - 8.00 | +| 9.00 - 9.15 | Intro and Icebreaker | 10.00 - 10.15 | 8.00 - 8.15 | +| 9.15 - 10.00 | Why we stream & Behind the scenes | 10.15 - 11.00| 8.15 - 9.00 | +| 10.00 - 10.15 | Break | 11.00 - 11.15 | 9.00 - 9.15 | +| 10.15 - 10.35 | Video Editing | 11.15 - 11.35 | 9.15 - 9.35 | +| 10.35 - 10.55 | Exercise: Video Editing | 11.35 - 11.55 | 9.35 - 9.55 | +| 10.55 - 11.10 | Break | 11.55 - 12.10 | 9.55 - 10.10 | +| 11.10 - 11.30 | Open Broadcaster Software(OBS) introduction | 12.10 - 12.30 | 10.10 - 10.30 | +| 11:30 - 11:50 | OBS setup & what next | 12.30 - 12.50 | 10.30 - 10.50 | +| 11.50 - 12.00 | Outro and feedback | 12.50 - 13.00 | 10.50 - 11.00 | + +#### :icecream: Icebreaker + +##### Check-in + +Which emoji best describes your current state of mind? [Emoji cheat sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) +- :coffee: + +- :runner: +- :tired_face: Tired! +- :nerd_face:![](https://) +- ![](https://notes.coderefinery.org/uploads/58bfdc31-ac86-4172-aef4-b7b4bd762533.png) +- :cloud: :tea: + +##### Introduction in breakoutrooms + +- Name / Affiliation / Location + +What's the most number of people you have taught to? +- 20 at a time, with 1 asleep, 2 fidgiting with some silly device and the rest were... well... staring at their good luck... straight ahead it was of course, right before them. +- ~35 +- ~80 in a lecture in a previous (lecturer) role, 26 in a training course setting +- ~30 +- ~50 in training spaces and more than 100 for public audience talk +- 35 (software carpentry) +- CodeRefinery answer: The biggest ones are maybe 200-300 people. "small" for a stream is ~100 people. + +What's the most number of people you have taught with? +- 5 or so +- 2 or 3 in total +- 3, as in three, none of them smiling. I wish I could figure out why... it was such fun really... +- 7 +- 2 or 3 +- 3 (helpers, not really co-teaching) +- CodeRefinery answer: our biggest workshops are something like 10-20 people helping out in many different roles. + +How can you divide teaching into separate independent tasks? +- By content blocks, having roles like main and assistant... +- Having responsibility for different sections of the course. +- Wow, now thats what we call a question... bravo... indeed, how does one separate sleeping and snoring into separate independent tasks... +- Course, exercices, resources, tools and forms. +- Different people teach different topics +- CodeRefinery answer: the big logical blocks are instructors, in-person and breakout room helpers, and Notes-questions answers. + +What’s the most interesting or useful thing you’ve learned from an online workshop, and how have you applied it/planning to apply in your life or work +- Having breaks every hour or so +- New approach to screensharing, using the 'portrait' approach +- Manage breathing: reduce stress and use silence to let the audience grasp what you're saying +- Well, the most interesting or useful thing I’ve learned from online workshops is how not to conduct a workshop, or at least some elements of the same, and I have applied this understanding by engaging in the global effort to discover more about how not to conduct a workshop, or at least some elements of the same, with the motto: That's one small step for a man, one giant leap for mankind.. + +#### :question: Questions + +#### [Why we stream](https://coderefinery.github.io/train-the-trainer/why-we-stream/) + +- If during streaming there is no interaction between the teacher and the audience, why don't we just record the lectures and stream them? So one can do a better job, perhaps? + - Streaming it making it a "thing" that's a group experience. It feels good to be a part of it, so we hope that encourages people to actually attend. All the mass Q&A is fun, and the audience helps to make it easier to present. Still, this is a good question. + - I really appriciate it being "a thing". If it was just recorded, I would say I would watch it tomorrow, and then I never would. + - But then you can just fake it, and still have all the breakout rooms and collaborative document and so on. I appreciate the value of having a proper "event". + - I think I follow you, but if you pre-recorded the talking bits, then the presentors couldn't change what they do based on the feedback in the shared document. + - true, but I assumed that the teachers were too busy to actually do that. The more (less )division of labor between the teachers and the helpers (or collaborative document editors), the more (less) sense it makes to pre-record - IMHO +- What interaction options do 'streamers' use, e.g. on Twitch/YouTube (not Code Refinary)? + - I'm besides chat and things that happen in chat, I'm not sure. The Notes-doc is definitely unique to us. +- Streaming is a kind of exercise for the movie star type. If you cannot be one, act like one, pretend, fool the listener into thinking you are one, take their brains and emotions under control. And if they don't leave the session with tears of love for learning running down their chubby cheeks you know who to kick for doing a job just that bit worse than it should have been necessary. +- Have you kept track of streming stats? like how many people logged in and stayed troughout, how many interacted? + - Yes please, it would be good to see the stats + - Here is stats [repo](https://github.com/coderefinery/workshop-stats) + - Thanks, I get a 404 error, is it private? + - No, I don't think so. https://github.com/coderefinery/workshop-stats + - Still get 404. Does it work for anyone else? + - Yeah I think it's private. We need to fix this... +- How big is small (10-15), medium (~30-40)? + - I would say below 50 is small. +- Have you considered scaling to more events instead of to a larger audience? I mean, this seems the opposite of scaling, but this kind of content would be more useful the more often is it taught ("I need to learn GIT/Python/* in December!") + - We would, but right now we simply don't have enough time and people to do more small events. But yes, "scheduling conflict" is a big problem - the best we can do right now is written material+videos to follow up on (and hope it's interesting enough) + - [Python for Scientific Computing 5-7/November/2024](https://www.aalto.fi/en/events/python-for-scientific-computing-5-7november2024) + - This was just an example. I mean, if I am a PHD student that needs to start working on a topic on Month X which happens to be inconveniently placed in the year, I will not benefit as much from having a workshop at Month X+3 + - The materials are open and the videos are publically available on YouTube channel + - What's the ratio of people watching videos afterwards vs people attending the event? That ratio can give an idea of the popularity of the two possible approaches. + - The more you scale up the less interactive the course / workshop will need to be. It then becomes a question of priorities, and if teaching is a lower priority then learning than I guess there really should be no prizes for guessing which approach should reign the airwaves. +- I guess outside Europe / Africa, time zones could be a problem? + - yes, that is true + - +- Sorry, I might have missed this: have you been rehearsing and/or doing dry runs? + - With instructors I like to try to do a dry run. I often don't do a live broadcast dry run these days since I'm confidente enough, but when you are just starting, it's a good idea. +- Do you always use Zoom for the 'presenter end' or have you tried other things? Teams? Jitsi? etc.? + - we use mostly zoom + - It was first pioneered using Jitsi. You can probably use others, too. + +- A comment: for deRSE24 we have been using the [GWDG streaming service](https://docs.gwdg.de/doku.php?id=en:services:mobile_working:live_streaming:start) and OBS, it worked quite well (with a 20s delay or so) + - Cool! Yes, there is plenty of livestreaming options. Twitch+our OBS config gives us 2-3s of latency (which is low enough for live Notes interaction). You might be able to tune this if needed. + +#### Behind the stream + +- Does OBS take a lot of RAM or CPU? what are the specs on your machine? + - Richard have a relatively powerful computer with 8 AMD CPUs. + - 4 CPUs are relatively enough for a good OBS setup, most important is a stable internet connection (ideally wired). + - An extra monitor is recommended for the setup + - See the hardware notesrecommendation [here](https://coderefinery.github.io/train-the-trainer/obs/#hardware-requirements) +- Do you do a screenshare from Zoom -> OBS or OBS -> Zoom? + - Instructors share to Zoom, OBS captures Zoom, OBS sends to the world. + - When I am using OBS sfor a single-person presentation recording, I go the other way: OBS captures my desktop/camera, OBS generates the preview window, and then Zoom captures and broadcasts the preview window. + + +#### [Video editing](https://coderefinery.github.io/train-the-trainer/video-editing/) + +##### Poll +- Have you tried video editing? Add an`o` as answer below + - yes: ooooo + - no : + - Video editing makes all the difference. I have never known a way to avoid this sacred of steps, so to speak. In short, no recording can ever be production ready by default in the books of the wiser among the streamers. In fact, during the editing one can considerably refine and improve the learning experience in great ways. But then one would need to invest both time and effort. + +- If `yes` Which are the tools you use? + - Windows Movie Maker / ClipChamp + - (raw stream from Zoom) + - I think it was shotcut - I did only basic trimming + - Kdenlive + - Clipchamp, OpenShot, Sony Vegas + - also ffmpeg from command line to cut beginning and end + +##### Questions +- What is Whisper? + - Open-source model from OpenAI that converts speech to text transcripts. + - this one? https://openai.com/index/whisper/ + - curious if anyone has tried it with languages other than english + - I heard that one of my spanish colleague try it with another software. I don't remember the tool. But with AI bloom there are many licensed tools that can do it with fifferent language + +- What do you use to crop the videos? + - I see now, ffmpeg + +- how to merge multiple parts in one? I asked because you edited only the icebreaker part? + - you can manage it in input part, see ffmpeg-editlist readme. + +- Do you generate custom thumbnails for the video? + - no, because of the time, but its good to have. If we had a volunteer to manage that, then we should! + +- Does anyone recommend any other (GUI) tools that work well? ffmpeg is very new to me! + - if you want a basic trimming and editing , you can use Quicktime player/imovies on mac + - Clipchamp as the Microsoft video editor + - Thanks :smile: + +- How do subtitles get uploaded to YouTube? + - You upload the video and subtitles as part of upload. + - :+1: + +- How does codewhisperer compare against youtube's automatically generated subtitles? + - by experience, whisper was better couple of years ago. We haven't compared it recently + - I guess and advantage is that you can edit whisper subtitles in case something is odd or whatever, probs cannot do that in YouTube + + +#### [Open Broadcaster Software (OBS) introduction](https://coderefinery.github.io/train-the-trainer/obs/) & [setup](https://coderefinery.github.io/train-the-trainer/obs-config/) + +- Are the profiles public? + - Yes, you can see it [here](https://coderefinery.github.io/train-the-trainer/obs-config/#coderefinery-obs-configs) +- Does it work in Linux+Wayland? + - I think everything we do with OBS would. + +### Wrapup +- All workshop materials will stay available (and be put on Zenodo right after the workshop) +- Upcoming Workshops + - [CodeRefinery workshop September 10-12, 17-19, 2024](https://coderefinery.github.io/2024-09-10-workshop/) + - [Build Systems Course and Hackathon](https://www.kth.se/form/build-systems-course-and-hackathon-part-i) + - [Python for Scientific Computing](https://www.aalto.fi/en/events/python-for-scientific-computing-5-7november2024) + +- CodeRefinery community: https://coderefinery.zulipchat.com/ +- If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org +- A summary email will be sent out to all participants + +### Feedback about todays session + +What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session: + +- ffmpeg seems great, will give a try for fun! +- great to see everything in practice! +- Very insightful to see what happens behind the scenes. + +What one thing would you improve about this session? + +- Some more interactivity would've been nice but since most the group preferred demo instead of exercise perhaps it's only a personal opinion +- It would have been good to share the OBS profiles repo beforehand in the setup email - so I could have had it to hand. (https://github.com/coderefinery/obs-config) + - +1 good idea, we should do this next time +- Perhaps a simpler starter OBS setup? + - Good idea... I should have, but basically ran out of time to prepare. + +Any other comments? + +- Cool to see the switch from RSE to trainer to AV guy, impressive! + + + diff --git a/branch/comms/_sources/obs-config.md.txt b/branch/comms/_sources/obs-config.md.txt new file mode 100644 index 0000000..df5e530 --- /dev/null +++ b/branch/comms/_sources/obs-config.md.txt @@ -0,0 +1,93 @@ +(obs-config)= + +# Open Broadcaster Software (OBS) setup + +:::{objectives} +- See how to configure OBS using the pre-made CodeRefinery scene + collections +- Modify the collections to suit your needs. +::: + +:::{instructor-note} +- Teaching: ?? min +- Hands-on: ?? min +- Q&A: ?? min +::: + +:::{See also} +* The previous episode {doc}`obs` +* [OBS theory in CodeRefinery manuals](https://coderefinery.github.io/manuals/obs/) +::: + + +In this lesson, we'll see how to configure OBS from scratch for your +purposes. We'll do this by deleting the instructor's configuration +and trying to recreate it + +This section is short, since it has never been done before: we'll just +give it a short and update the lesson later. + + +## CodeRefinery OBS configs + +- CodeRefinery configs are shared in a repository: + +- These can be imported to pre-configure some things +- There are two types of configs: + - Profiles + - Servers, resolutions, audio, video, etc. + - Scene collections + - The graphical layouts. + + +## Installing the OBS config + +- Clone the git repository. +- Import the profile and scene collections under their respective + menus. + + +## Initial setup + +- Click through each menu and change anything that is needed +- Set the streaming server + +:::{demo} The instructor will go through the setup. + +- Reset configuration: `mv .config/obs-studio/ + .config/obs-studio-old/` +- Import `profiles/TeachingStreamingv3/` +- Import `scenes/TeachingStreamingZoomv3.json` +::: + + + +## Set up the remote control + +- Create a Python environment and install it: `pip install https://github.com/coderefinery/obs-cr/archive/refs/heads/master.zip` + +- Run it: `python obs_cr/control.py localhost:4445 TOKEN + --broadcaster` +- There are more options but let's not cover them yet... and leave + this for a hands-on session. + + +## Setup before each course + +- Re-confirm audio +- Re-confirm each scene +- Test everything +- rkdarst has a [rather long + checklist](https://docs.google.com/spreadsheets/d/1g8Bc_76OPcv1vYWtB54wz6HsXQcb3B1GtQFga4Oanw4/edit?gid=0#gid=0), + but each individual step is short. + + +## Q&A + +We'll answer audience questions. + + +:::{keypoints} +- Most of our configuration has been OBS may seem complicated, but it's a graphical application and most + pieces make sense once you know how it works. +::: diff --git a/branch/comms/_sources/obs.md.txt b/branch/comms/_sources/obs.md.txt new file mode 100644 index 0000000..8db24f4 --- /dev/null +++ b/branch/comms/_sources/obs.md.txt @@ -0,0 +1,74 @@ +(obs)= + +# Open Broadcaster Software (OBS) introduction + +:::{objectives} +- Understand that OBS is a video mixer. +- Understand the basic controls and features of OBS. +::: + +:::{instructor-note} +- Teaching: 15 min +- Q&A 5 min +::: + +:::{See also} +* [OBS theory in CodeRefinery manuals](https://coderefinery.github.io/manuals/obs/) +* The next episode {doc}`obs-config` +::: + +In this episode, you'll get more familiar with the OBS portion of the +streaming setup. You'll see how it's used, but not yet how to +configure it from scratch. You'll learn how to be a "director". + + +## What is OBS? + +- Formally "OBS Studio" +- Most commonly known as a livestreaming application. +- Open source, free. +- Cross-platform, easy to use screencasting and streaming application. +- Real-time video mixer. + + +## OBS user interface + +- We'll click through each view. +- What does each view do? +- Let's click through the buttons. +- Let's see the important config options. + + +## OBS during a course + +- What management is needed. +- The control panel. +- Audio. +- Adjusting windows and so on. + + +## Hardware requirements + +- Reasonably powerful broadcast computer + - CodeRefinerys streaming computer is 8 CPU AMD, 64GB memory + - That is way overkill: a powerful laptop can probably do this. +- Large second monitor for laying out the windows you capture +- Stable internet connection (wired preferable) + - CodeRefinery's broadcast is the slowest purchasable: 100 Mbit down / + 25Mbit up + + +## Q&A + +We'll answer audience questions. + + +## See also + +- The next episode {doc}`obs-config` which is about configuring OBS. + + +:::{keypoints} +- OBS may seem complicated, but it's a graphical application and most + pieces make sense once you know how it works. +::: diff --git a/branch/comms/_sources/overview.md.txt b/branch/comms/_sources/overview.md.txt new file mode 100644 index 0000000..aaa3395 --- /dev/null +++ b/branch/comms/_sources/overview.md.txt @@ -0,0 +1,185 @@ +(workshop-overview)= + +# A workshop seen from different perspectives + +:::{objectives} +- Understand the general structure of CodeRefinery workshops and why it is the way it is +- Get to know the different roles of a workshop and which ones are the most essential ones +- Understand the importance of installation instructions and how they contribute to learners success +- Understand the importance of onboarding and a welcoming community for volunteers in a workshop +::: + +:::{instructor-note} +- Teaching: 20 min +- Exercises: 15 min +- Roles journeys can be shortened to looking only at instructor role. +::: + +:::{note} +This episode focuses on the large scale streamed workshop setup. Some of the features can also be applied to smaller scale workshops though. +::: + +## Discussion + +:::{discussion} +In breakoutrooms: choose one or two questions to talk about your own experiences; summary in collaborative notes: +- What kind of roles have you been in yourself regarding workshops? +- How were you prepared for your role? +- What are the things you would like to know before a workshop? +- How are you preparing your participants for your trainings? +- What was the best workshop experience for you as learner, helper or instructor? What made it great? +::: + +## One workshop - many parts + +```{figure} img/CR_workshop_setup.png +Image showing the different phases of a CodeRefinery workshop described below. Also showing that while there is only two people teaching, many people work behind the scenes. +``` + +### Before the workshop + +- During winter/summer: "Someone" takes the coordinator role for the next workshop +- Coordinator fills other roles: + - Coordinator: collects necessary lesson updates, supports other coordinators + - Registration coordinator: Sets up web page, starts and manages registration + - Instructor coordinator: Finds instructors and onboards them + - Advertising coordinator: Prepares advertizement texts and finds people to distribute them + - Team coordinator: Gathers local organizers/teams + - Bring your own code session coordinator: If available, offer BYOC session after main workshop +- Instructor: Onboarding with (instructor-) coordinator and previous instructor of lesson; update of lesson materials (urgent issues and personal touches) +- Local organizer/Team lead: Group [onboarding](https://coderefinery.github.io/manuals/team-leaders/) ~ week/or two before workshop +- Learner: Gets [installation instructions](https://coderefinery.github.io/installation/), invited to installation help session, workshop info from event page and summary via e-mail +- Collaborative notes manager sets up the notes document + +:::{note} +#### [Onboarding manuals](https://coderefinery.github.io/manuals/team-leaders/) +- **Outline of what will happen during the workshop** +- Discussion of different strategies to handle the exercise sessions +- Lowering the barrier to ask for support by meeting some organizers +- Q&A +::: + +:::{note} +#### [Installation instructions](https://coderefinery.github.io/installation/) +- Instructions for all operating systems +- Goal: Learners leave the workshop and are ready to apply the learned tools and techniques to their own work +- Support session for installation challenges +::: + + + +### During the workshop + +```{figure} img/BYOC.png +Image showing the different ways learners can do the exercises. No matter which way they choose, they always watch the stream and interact with instructors and organizers via collaborative notes. Individual learners do the exercises alone, people in online or local classrooms in addition get to discuss with their peers. +``` + +- Everyone watches stream +- Co-instructors + - Present content + - Answer questions in collaborative notes +- Collaborative notes manager + - Keeps the collaborative notes clean + - Helps answering questions + - Adds sections + - Archives the document after each day +- Learners do exercises individually or in team +- Local organizer / Team lead + - Guides learners through exercises + - Facilitates discussion +- (Registration-) coordinator sends out e-mails to participants after each day (summary + preparation) +- Director/Broadcaster manages the streaming (see session 4) + +### After the workshop + +- Coordinator collects lessons learned based on experience and feedback and turns them into issues +- Coordinator organizes debriefing week after the workshop, where anyone can join to give feedback +- "Someone" sends out post-workshop survey half a year after workshop +- Coordinator organizes "Bring your own code" sessions +- Broadcaster prepares and shares recording (see session 4) + +:::{note} +#### Bring your own code sessions + +We want to support learners to apply what they have learned in the workshop to their own work by offering one/two sessions where they can drop in, and discuss challenges with CodeRefinery instructors and helpers. + +```{figure} img/welcome.png +Image showing a classroom learning about git leading to a discussion between student and teacher to start a welcoming environment for asking for help. +``` +::: + +## This sounds like a lot of people and time investment! + +- Many roles can be combined or adjusted as needed +- Some roles can be taken on by multiple people + +So how many people are needed for this kind of workshop? +- Recommended minimum: 2-3 people +- Optimum: ~ 4-5 people +The more people you involve, the more time goes into coordination work. + +## How did we get to this setup? + +- **Collaborative** in-person workshops since 2016 around the Nordics +- Moved online in 2020 +- Started with "traditional zoom" workshops, breakoutrooms, volunteer helpers +- Thought about scaling and ease of joining -> current setup (More about this in session 4) +- Continuous development + +We also still do smaller scale local workshops, if instructors are available. +**You can offer your own CodeRefinery workshop** by inviting other CodeRefinery instructors. +You can also reuse single lessons and integrate them into your own teaching. + +## Workshop roles and their journeys + +### Individual learner journey + +- Registration +- Installation +- (if appicable: Invited to local meetup) +- Workshop + - Watch stream + - Q&A in notes + - Exercises alone or in team + - Daily feedback +- Debrief/ Feedback session +- Post workshop survey + +### Instructor journey + +- Indicate interest in CodeRefinery chat +- Onboarding +- Lesson material updates +- Teaching +- (if wished: supports answering questions in notes) +- Debrief + +### Team lead / Local host journey + +- Registration +- (if applicable: run own registration) +- Onboarding +- Workshop + - Watch stream + - Facilitate exercises/discussions + - Daily feedback +- Debrief / feedback / survey + +### Other roles + +Director and broadcaster roles will be discussed in Session 4. +For more in-depth descriptions and other roles (host, instructor, registration coordinator, etc), see also our [CodeRefinery manuals](https://coderefinery.github.io/manuals/roles-overview/). + +## Different roles as stepping stones for community involvement + +```{figure} img/steps.png +Image showing a person jumping from step to step following learner, helper, expert helper, co-instructor, co-organizer. +``` +There is no "one way" to get involved. Do what feels right. +Interested in teaching with us? Let us know and we can discuss what is a suitable path **for you**! + +:::{keypoints} +- CodeRefinery workshops are a collaborative effort with many different roles +- Onboarding the different roles is one key aspect of our workshops +- Everyone has their own path +::: diff --git a/branch/comms/_sources/screenshare.md.txt b/branch/comms/_sources/screenshare.md.txt new file mode 100644 index 0000000..cdf552a --- /dev/null +++ b/branch/comms/_sources/screenshare.md.txt @@ -0,0 +1,370 @@ +(screenshare)= + +# How to prepare a quality screen-share + +:::{objectives} +- Discuss the importance of a well planned screen-share. +- Learn how to prepare and how to test your screen-share setup. +- Know about typical pitfalls and habits to avoid. +::: + +:::{instructor-note} +- Discussion: 15 min +- Exercises: 15 min +::: + + +## Share portrait layout instead of sharing entire screen when teaching online + +- Many learners will have a smaller screen than you. +- You should plan for learners with **only one small screen**. +- A learner will **need to focus on both your screen share and their + work**. +- Share a **portrait**/**vertical half of your screen** (840 × 1080 is our standard and your + maximum). +- Zoom provides a "Share a part of screen" that is good for this. + - Our latest streaming setup (day 4) can take the portrait part for + you so you can share landscape. + - Zoom + Linux + Wayland display manager doesn't have "Share a + portion of the screen" + - You can share a single window portrait. + - Or you can start your desktop session in "X11" or "Xorg" legacy + mode. + - Or possibly other workarounds (does anyone know other solutions?) + +:::{figure} screenshare/landscape.png +:width: 80% + +A FullHD 1920x1080 screen shared. Learners have to make this really small if +they want to have something else open. +::: + +:::{figure} screenshare/portrait.png +:width: 45% + +Portrait layout. Allows learners to have something else open in the other half. +::: + +Motivation for portrait layout: +- This makes it easier for you to look at some other notes or to coordinate + with other instructors at the same time + without distracting with too much information. +- This makes it possible for participants to have something else open in the + other screen half: terminal or browser or notebook. + + +### Instructor perspective + +:::{figure} screenshare/instructor.png +:width: 75% + +**I1**: +This is how it can look for the instructor. Zoom is sharing a portion of the left +side, the right side is free for following notes, chat, etc. +::: + + +### Learner perspective + +Here are three examples of how it can look for the learner. + +:::{figure} screenshare/learner-large.png +:width: 75% + +**L1**: +Learner with a large screen, Zoom in dual-monitor mode so that the instructor +pictures are not shown. Screen-share is on the left side, collaborative notes +at bottom left, terminal and web browser on the right. +::: + +:::{figure} screenshare/learner-normal.png +:width: 75% + +**L2**: +A learner with a single large screen (Zoom in "single monitor mode"). +Instructor screen share at right, learner stuff at left. +::: + +:::{figure} screenshare/learner-small.png +:width: 75% + +**L3**: +A learner with a particularly small screen. Instructor screen-share at left, +your windows at right. +::: + + +## Share the history of your commands + +Even if you type slowly it is almost impossible to follow every command. We +all get distracted or want to read up on something or while following a command +fails on the learner laptop while instructor gets no error. + +**Add pauses** and **share the commands that you have typed** so that one can catch up. + +Below are some examples (some more successful than others) of sharing history +of commands. + +:::{figure} screenshare/history-portrait.png +:width: 50% + +**H1**: +A vertical screen layout shared. Note the extra shell history at the top. The +web browser is at the bottom, because the Zoom toolbar can cover the bottom +bit. +::: + +:::{figure} screenshare/history-rsh.png +:width: 75% + +**H2**: +This isn't a screen-share from CodeRefinery, but may be instructive. Note the +horizontal layout and shell history at the bottom right. +::: + +:::{figure} screenshare/history-landscape-dark.png +:width: 75% + +**H3**: +Similar to above, but dark. Includes contents on the right. +::: + +:::{figure} screenshare/history-portrait-light.png +:width: 50% + +**H4**: +Jupyter + terminal, including the ``fish`` shell and the terminal history. +::: + +:::{figure} screenshare/history-portrait-dark.png +:width: 50% + +**H5**: +Lesson + terminal, ``tmux`` plus terminal history and dark background. +::: + +:::{figure} screenshare/portrait.png +:width: 50% + +**H6**: +HPC Kickstart course. Note the colors contrast of the windows and colors of +the prompt and text. The history is smaller and doesn't take up primary +working space. The working directory is in the window title bar. +::: + +:::{figure} https://raw.githubusercontent.com/bast/history-window/main/demo.gif +:width: 80% + +**H7**: +Show command history "picture-in-picture", in the same terminal window. +::: + + +## How to configure history sharing + +You need to find a way to show the recent commands you have entered, so that +learners can see the recent commands. Below are many solutions. Try them out +and see what works for you. + +- [prompt-log](): + It adds a interesting idea that the command you enter is in color and also + provides terminal history before the command returns. + +- **Simple**: The simple way is `PROMPT_COMMAND="history -a"` and then + `tail -f -n0 ~/.bash_history`, but this doesn't capture ssh, + sub-shells, and only shows the command after it is completed. + +- **Better yet still simple**: Many Software Carpentry instructors use + [this script](https://github.com/rgaiacs/swc-shell-split-window), + which sets the prompt, splits the terminal window using tmux and displays command history + in the upper panel. Requirement: [tmux](https://github.com/tmux/tmux/wiki) + +- **Better (bash)**: This prints the output before the command is run, + instead of after. Tail with `tail -f ~/demos.out`. + ``` + BASH_LOG=~/demos.out + bash_log_commands () { + # https://superuser.com/questions/175799 + [ -n "$COMP_LINE" ] && return # do nothing if completing + [[ "$PROMPT_COMMAND" =~ "$BASH_COMMAND" ]] && return # don't cause a preexec for $PROMPT_COMMAND + local this_command=`HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"`; + echo "$this_command" >> "$BASH_LOG" + } + trap 'bash_log_commands' DEBUG + ``` + +- **Better (zsh)**: This works like above, with zsh. Tail with `tail -f + ~/demos.out`. + ``` + preexec() { echo $1 >> ~/demos.out } + ``` + +- **Better (fish)**: This works like above, but for fish. Tail with + `tail -f ~/demos.out`. + ``` + function cmd_log --on-event fish_preexec ; echo "$argv" >> ~/demos.out ; end + ``` + +- **Better (tmuxp)**: This will save some typing. + [TmuxP](https://tmuxp.git-pull.com/) is a Python program (`pip install + tmuxp`) that gives you programmable `tmux` sessions. One configuration that + works (in this case for `fish` shell): + ```yaml + session_name: demo + windows: + - window_name: demo + layout: main-horizontal + options: + main-pane-height: 7 + panes: + - shell_command: + - touch /tmp/demo.history + - tail -f /tmp/demo.history + - shell_command: + - function cmd_log --on-event fish_preexec ; echo "$argv" >> /tmp/demo.history ; end + ``` + +- **Windows PowerShell**: In [Windows Terminal](https://docs.microsoft.com/en-us/windows/terminal/), + a split can be made by pressing `CTRL+SHIFT+=`. Then, in one of the splits, the following + PowerShell command will start tracking the shell history: + ``` + Get-Content (Get-PSReadlineOption).HistorySavePath -Wait + ``` + Unfortunately, this only shows commands after they have been executed. + +- [Tavatar: shell history mirroring teaching tool](https://github.com/Sabryr/Tavatar) can copy recent history to a remote server. + +- [history-window](https://github.com/bast/history-window): Show command + history "picture-in-picture" when teaching command line. Requires Bash. + + +## Font, colors, and prompt + +### Terminal color schemes + +- Dark text on light background, *not* dark theme. Research and our + experience says that dark-text-on-light is better in some cases and + similar in others. +- You might want to make the background light grey, to avoid + over-saturating people's eyes and provide some contrast to the pure + white web browser. (this was an accessibility recommendation when + looking for ideal color schemes) +- Do you have any yellows or reds in your prompt or program outputs? + Adjust colors if possible. + + +### Font size + +- Font should be large (a separate history terminal can have a smaller + font). +- Be prepared to resize the terminal and font as needed. Find out + the keyboard shortcuts to do this since you will need it. + + +### Prompt + +At the beginning of the workshop your goal is to have a shell +**as easy to follow as possible** and **as close to what learners will +see on their screens**: +- Your prompt should be minimal: few distractions, and not take up many + columns of text. +- [prompt-log]() does + this for you. +- The minimum to do is is `export PS1='\$ '`. +- Blank line between entries: `export PS1='\n\$ '`. +- Have a space after the `$` or `%` or whatever prompt character you + use. +- Strongly consider the Bash shell. This is what most new people will + use, and Bash will be less confusing to them. +- Eliminate menu bars and any other decoration that uses valuable + screen space. +- Add colors only if it simplifies the reading of the prompt. + +Later in the workshop or in more advanced lessons: +- Using other shells and being more adventurous is OK - learners will + know what is essential to the terminal and what is extra for your + environment. + +Try to find a good balance between: +- Showing a simple setup and showing a more realistic setup. +- Showing a consistent setup among all instructors and showing a + variety of setups. + + +## Habits we need to un-learn + +- **Do not clear the terminal**. Un-learn CTRL-L or `clear` if possible. + More people will wonder what + just got lost than are helped by seeing a blank screen. Push + ``ENTER`` a few times instead to add some white space. +- **Do not rapidly switch between windows** or navigate quickly between multiple + terminals, browser tabs, etc. This is useful during your own work when nobody + is watching, but it is very hard to follow for learners. +- Avoid using **aliases** or **shortcuts** that are not part of the + standard setup. Learners probably don't have them, and they will fail + if they try to follow your typing. Consider even to rename corresponding + files (`.bashrc`, `.gitconfig`, `.ssh/config`, `.ssh/authorized_keys`, `.conda/*`). +- Be careful about using **tab completion** or **reverse history search** if these + haven't been introduced yet. + + +## Desktop environment and browser + +- Try to remove window title bars if they take up lots of space + without adding value to the learner. +- Can you easily resize your windows for adjusting during teaching? +- Does your web browser have a way to reduce its menu bars and other + decoration size? + - Firefox-based browsers: go to `about:config` and set + `layout.css.devPixelsPerPx` to a value slightly smaller than one, + like `0.75`. Be careful you don't set it too small or large since + it might be hard to recover! When you set it to something smaller + than 1, all window decorations become smaller, and you compensate + by zooming in on the website more (you can set the default zoom to + be greater than 100% to compensate). Overall, you get more + information and less distraction. + + +## How to switch between teaching setup and work setup? + +- Make a dedicated "demos" profile in your terminal emulator, if + relevant. Or use a different terminal emulator just for demos. +- Same idea for the browser: Consider using a different browser profile for + teaching/demos. +- Another idea is to containerize the setup for teaching. + We might demonstrate this during the {ref}`cool-gems` session later. + +--- + +:::{keypoints} +- Share **portrait layout** instead of sharing entire screen +- **Adjust your prompt** to make commands easy to read +- **Readability** and beauty is important: adjust your setup for your audience +- **Share the history** of your commands +- Get set up a **few days in advance** and get feedback from someone else. + Feedback and time to improve is very important to make things clear and accessible. + 10 minutes before the session starts is typically too late. +::: + + +## Exercises + +:::{exercise} Evaluate screen captures (20 min) + +Evaluate screenshots on this page. Discuss the trade-offs of each one. Which +one do you prefer? Which are useful in each situation? + +Please take notes in the collaborative document. +::: + +:::{exercise} Set up your own environment (20 min) + +Set up your screen to teach something. Get some feedback from another learner +or your exercise group. +::: + + +## Other resources + +- +- diff --git a/branch/comms/_sources/session-4-intro.md.txt b/branch/comms/_sources/session-4-intro.md.txt new file mode 100644 index 0000000..15cf32e --- /dev/null +++ b/branch/comms/_sources/session-4-intro.md.txt @@ -0,0 +1,28 @@ +(session-4-intro)= + +# Session 4 intro + +This session covers streaming and technical production. Some +introductory notes: + +* (As of 2024) This is the first and only comprehensive introduction + to our online streaming. +* These practices are new and well-refined internally, but a + *different* kind of refinement is needed to teach and reuse them. +* The lessons have outlines of what to talk about, but it's just an + outline. It is *not* refined, since thees things are *new*. Many + things will have to be figured out as we talk. +* This session is a demo of lots of basics. + * Ask questions - otherwise it will be boring + * If you want to use this in real life: you will need *mentoring + sessions* and active help. Contact us to do that. + + +:::{warning} + +**Audio and video weirdness** + +We are setting up video and audio recording, but also capturing that +for re-sharing it. There may be anomalies as video or audio +feedback. Please be prepared. +::: diff --git a/branch/comms/_sources/sound.md.txt b/branch/comms/_sources/sound.md.txt new file mode 100644 index 0000000..bc4ba16 --- /dev/null +++ b/branch/comms/_sources/sound.md.txt @@ -0,0 +1,170 @@ +(sound)= + +# Sound + +:::{objectives} +- Understand that sound quality is very important +- Evaluate your and others sound quality and know how to improve it +- Test tips and tricks for achieving good sound quality +::: + +:::{instructor-note} +- Teaching: 10 min +- Exercises: 10 min +::: + + + +## The importance of audio + +- Pleasing audio quality makes events much more enjoyable +- Audio is one of the most important things you can control +- Things that can go wrong: + - Too quiet + - Too loud + - Instructors' volumes imbalanced + - Background noise + - Low-quality/breaking up audio hard to hear. + - "Ducking" (first words lower volume, or lower volume other times) + + + +## Tips for good sound quality + +- Have a headset with mounted microphone + - Even if you have a professional external microphone, it doesn't + matter if your room has bad acoustics. + - The close pickup can't be beat with normal tools. + - As long as it's headset mounted, price doesn't seem to matter + *that* much. +- Don't use Bluetooth + - Bluetooth can have too much latency (300-500ms) + - This may seem small but for interactive work, it's a lot + - Use a wired headset, or wireless with a non-Bluetooth USB plug + (like gaming headsets have). These have much lower latency. + - Bluetooth 5 can have much lower latency, but you probably + shouldn't count on that without testing. + - It can also have lower sound quality on some devices due to + bandwidth limitations. +- Once you have a headset, turn input noise cancellation to low + (wherever it might be: headphone, meeting software, etc.). + + + +## Balancing and dynamic adjustment + +- It's important that instructors volumes match. +- An exercise will go over a systematic procedure for matching + volumes. + - Practice so that you can do this quickly. +- May need re-adjusting when instructors swap out or start getting + excited. +- An exercise below will demonstrate our procedure. + + + +## Speak up when there are problems + +- If you notice someone with audio issues, let them know right away + (voice if bad, or chat/notes if less urgent). +- Take the time to fix it as soon as practical. +- Make a culture of *speaking up, helping, and not suffering*. + + + +## Recommendations + +- Procure some reasonable headset. +- Low/medium-priced gaming-type headsets have worked well for us. + - (gaming headsets usually aren't Bluetooth, because gaming needs + low latency.) +- Show this page to your workplace (if you have one) and call a good + headset work equipment. + + + +## Exercises + +:::{exercise} Sound-1: Evaluate sound quality +It's important to be able to discuss with others the quality of their +audio. They can't hear themselves, after all. + +- Within the teams, discuss each person's audio quality and what kind + of setup they have. +- Be respectful and constructive (and realize that people came + prepared to listen, not teach). +- Consider, for example + - Volume + - Clarity + - Background noise + - Noise cancellation artifacts + - "Ducking": first words at lower volume or missing +- Discuss how to bring this up during other courses and meetings. +::: + + +:::{exercise} Sound-2: Adjust volume up and down +In addition to individual quality, it is important that sound is +balanced among all instructors. Have you ever been to a event when +one person is too quiet and they can't make themselves any louder? +And they can't adjust it? + +You should ensure that you have a range of volumes available to you. +You might have to look into several different locations in order to +make the full adjustment (). + +- Go to your sound settings +- One by one, each person + - Adjusts their microphone volume so quiet that they can't be heard. + - Adjusts their microphone volume so that it is extremely loud (this + may require going beyond 100% if possible). +- Basically, make sure you aren't so close to either end that you have + no potential to make an adjustment in that direction. +- Everyone tries to set the volume to something reasonable, in + preparation for the next exercise. + +Once you know where these settings are , you won't be panicked when the +volume is too low or high during a course. +::: + + +:::{exercise} Sound-3: Do a balance check +It's important that instructor audio is balanced (the same volume). +But how can you do this? + +- Pick a leader. +- The leader decides the order ("I am first, then [name-1] and + [name-2]") +- The leader says "one". Everyone else says "one" in the order + specified. +- The leader says "two". Everyone else says "two" in the order. +- The leader asks for opinions on who they think is louder or softer. + If there are more than three people, you can figure it out + yourselves. With less than two, you have to ask someone in the + audience. + +Example: +- Leader: Let's do a sound check. I am first, then AAA and BBB. +- Leader: One +- AAA: One +- BBB: One +- Leader: Two +- AAA: Two +- BBB: Two +- Leader: Three +- AAA: Three +- BBB: Three +- Leader: How did that sound to everyone? +- [Someone else]: Leader and BBB were pretty similar but AAA is a bit + lower. +::: + + + +## Summary + +:::{keypoints} +- Audio quality is important and one of the most notable parts of the + workshop. +- Improving audio isn't hard or expensive, but does require preparation. +::: diff --git a/branch/comms/_sources/streaming-whats-next.md.txt b/branch/comms/_sources/streaming-whats-next.md.txt new file mode 100644 index 0000000..68a62d9 --- /dev/null +++ b/branch/comms/_sources/streaming-whats-next.md.txt @@ -0,0 +1,31 @@ +(streaming-whats-next)= + +# What's next? + +:::{objectives} +- Know next steps if you want to do streaming +::: + +:::{instructor-note} +- Teaching: 5 min +- Q&A 5 min +::: + +What comes next? + +- We talked a lot about theory, and gave demonstrations. +- Hands-on is very different. We recommend working with someone to + put it in practice. +- + + +- Work with someone who can show you the way +- Use it for smaller courses with a backup plan + + +## See also + +:::{keypoints} +- These lessons about streaming have been the theoretical part of +streaming training. +::: diff --git a/branch/comms/_sources/streaming.md.txt b/branch/comms/_sources/streaming.md.txt new file mode 100644 index 0000000..614b847 --- /dev/null +++ b/branch/comms/_sources/streaming.md.txt @@ -0,0 +1,94 @@ +(streaming)= + +# Behind the stream + +:::{objectives} +- Take a first look at the broadcaster's view. +- Get to know what happens "behind the stream" of a workshop +- See what the "broadcaster" sees and what they need to do. +- Not yet: learn details of how to do this. +::: + +:::{instructor-note} +- Teaching: 20 min +- Q&A 10 min +::: + +In this episode, you'll see an end-to-end view of streaming from the +broadcaster's point of view. It's a tour but not an explanation or +tutorial. + + + +## Who does what + +We have certain role definitions: + +- **Broadcaster**: Our term for the person who manages the streaming. +- **Director**: Person who is guiding the instructors to their + sessions, changing the scenes, calling the breaks, etc. + - Could be the same as broadcaster. +- **Instructor**: One who is teaching. They don't have to know + anything else about how streaming works. + +This lesson describes what the Broadcaster/Director sees. + + +## Window layouts + +What does the broadcaster see on their screen? + +- What are the main windows you see? +- What do each of them do? +- Which ones do you need to focus on? +- How do you keep all this straight in your head? + + +## CodeRefinery control panel + +- A custom application that controls scenes +- Based on OBS-websocket (remote control connection for OBS - we'll + learn about this later) +- Can also work remotely, so that you can have a remote director + + +## How scenes are controlled + +What has to be done during a course? + +- How do you start the stream? +- How do you change the view? +- How do you adjust things based on what the instructors share? +- How do you coordinate with the instructors? +- How do you know when to change the view? + + +## Getting it set up + +- How hard was it to figure this out? +- How hard is it to set it up for each new workshop? + + +## What can go wrong + +- What's the worst that has happened? +- What if you need to walk away for a bit? +- Someone broadcasts something unexpectedly + + +## Alternatives + +- Youtube vs Twitch +- Zoom stream directly to YouTube/Twitch +- Direct streaming platform, e.g. streamyard + + +## Q&A + +Q&A from audience + + +:::{keypoints} +- The broadcaster's view shouldn't be so scary. +- There is a lot to manage, but each individual part isn't that hard. +::: diff --git a/branch/comms/_sources/teaching-philosophies.md.txt b/branch/comms/_sources/teaching-philosophies.md.txt new file mode 100644 index 0000000..7609af2 --- /dev/null +++ b/branch/comms/_sources/teaching-philosophies.md.txt @@ -0,0 +1,155 @@ +(teaching-philosophies)= + +# CodeRefinery teaching philosophies + +:::{objectives} +- Get to know the teaching philosophies of CodeRefinery instructors +::: + +:::{instructor-note} +- Teaching: 10 min +- Discussion: 20 min +::: + + +## Introduction + +During this episode we split into breakoutrooms and discuss own teaching philosophies. +Collect your teaching philosophies in the collaborative document. We will be going through +these and the end of the lesson. + +:::{challenge} Ice-breaker in groups (20 minutes) +- Share your approach to teaching and your teaching philosophy with your group. +- Please share your tricks and solutions in the live document for others. + +Additional ice-breaker questions: +- What is your motivation for taking this training? +- How structured or informal are your own teaching needs? +- What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching? +- What other skills need to be taught, but academic teaching isn't the right setting? +::: + + +## Instructor views + +Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops. + +It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us. + +:::{prereq} Video recordings +We have recorded some of the below as videos: +::: + +:::{challenge} Bjørn Lindi +My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this "BLOB" (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the "BLOB", to be able to share it with others. + +In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic. + +When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson. + +Tools that I find useful in preparing a lesson is concept maps and Learner Personas (though I have developed too few of them): +- [Concept Maps](https://teachtogether.tech/#s:memory-concept-maps) +- [Learner Personas](https://teachtogether.tech/#s:process-personas) +::: + +:::{challenge} Radovan Bast +My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos. + +My goal for a lesson is to spark curiosity to try things after the lesson, both +for the novices ("This looks like a useful tool, I want to try using it after +the workshop.") and the more experienced participants ("Aha - I did not know +you could do this. I wonder whether I can make it work with X."). I like to +start lessons with a question because this makes participants look up from +their browsers. + +Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise. + +For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate the +answer. + +I try to avoid jargon and "war stories" from the professional developers' +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid "customer", +"production", also a lot of Agile jargon is hard to relate to. + +Less and clear is better than more and unclear. Simple examples are better than +complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +"simply", "just", "easy". If participants take home one or two points from a +lesson, that's for me success. + +I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don't want to be +surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or slide. +This allows me to skip and distill the essence and not read bullet point by +bullet point. + +I try to never deviate from the script and if I do, be very explicit about it. + +A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel listening to me. + +I very much like the co-teaching approach where the other person helps +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson. +::: + +:::{challenge} Sabry Razick +My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case. +::: + +:::{challenge} Richard Darst +Like many people, I've often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I've realized long ago that my most important lessons weren't +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I've realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds. + +My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I'm often start at the +very basics, because this is what I see missing most often. + +When teaching, I like lots of audience questions and don't mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don't have to know everything perfectly, just show how +you'd approach a problem. +::: + +:::{challenge} Stepas Toliautas +I aim for my learners to understand things (concepts, techniques...), instead of just memorizing them. The phrase I use from time to time when teaching information technology topics (be it hardware or software) is "there is no magic": everything can be explained if necessary. While CodeRefinery also emphasizes usefulness/ immediate applicability of the content, often having the correct notions actually helps to start using them sooner and with less mistakes. + +I try to guide my audience through the presented material with occasional questions related to previous topics and common knowledge -- to help them link the concepts already during the lesson. I'm also fully aware that waiting for someone to answer is quite uncomfortable in-person and doubly so in an online environment, especially if no one uses their cameras :) + +And if I get the question I don't have the answer for (or material to show it) at the moment, in university classes I prepare and come back to it next time. While with one-off workshops there might not be a "next time", open-source material used by CodeRefinery allows to have the same outcome: the latest and greatest version stays available for self-study afterwards. +::: + + +## Summary + +:::{keypoints} +- People have different viewpoints on teaching. +::: diff --git a/branch/comms/_sources/video-editing.md.txt b/branch/comms/_sources/video-editing.md.txt new file mode 100644 index 0000000..b41ee26 --- /dev/null +++ b/branch/comms/_sources/video-editing.md.txt @@ -0,0 +1,468 @@ +(video-editing)= + +# Video editing + +:::{objectives} +- Get to know ways of quick video editing to be able to provide + accessible videos +- Learn how video editing can be distributed and done the same day. +::: + +:::{instructor-note} +- Teaching: 20 min +- Exercises: 20 min +::: + + +Video recordings could be useful for people watching later, +but also are (perhaps more) useful for **immediate review and catching +up after missing a day in a workshop**. For this, they need to be +released immediately, within a few hours of the workshop. +CodeRefinery does this, and you can too. + +Hypothesis: videos must be processed the same evening as they were +recorded, otherwise (it may never happen) or (it's too late to be +useful). To do that, we have to make processing *good enough* (not +perfect) and *fast* and the work *distributeable*. + + + +## Primary articles + +* Video editor role description: + +* ffmpeg-editlist: the primary tool: + + * Example YAML editlists: + + + +## How this relates to streaming + +- If you stream, then the audience *can not* appear in the recorded + videos +- This allows you to release videos *very quickly* if you have the + right tools. +- When you have a large audience, the videos start helping more + (review a missed day, catch up later, review later) +- Thus + - If you would never want videos, there may never be a benefit to + streaming + - If you want videos, it gives motivation to stream. + + +## Summary + +* Basic principle: privacy is more important than any other factor. + If we can't guarantee privacy, we can't release videos at all. + + - Disclaimers such as "if you don't want to appear in a recording, + leave your video off and don't say anything", since a) accidents + happen especially when coming back from breakout rooms. b) it + creates an incentive to not interact or participate in the course. + +* Livestreaming is important here: by separating the instruction from + the audience audio/video, there is no privacy risk in the raw + recording. They could be released or shared unprocessed. + +* Our overall priorities + + 1) No learner (or anyone not staff) video, audio, names, etc. are + present in the recordings. + 2) Good descriptions. + 3) Removing breaks and other dead time. + 4) Splitting videos into useful chunks (e.g. per-episode), perhaps + equal with the next one: + 5) Good Table of Contents information so learners can jump to the + right spots (this also helps with “good description”.) + +* [ffmpeg-editlist](https://github.com/coderefinery/ffmpeg-editlist) + allows us to define an edit in a text file (crowdsourceable on + Github), and then generate videos very quickly. + + +## How we do it + +The full explanation is in the form of the exercises below. As a +summary: + +- Record raw video (if from a stream, audience can't possibly be in + it) +- Run Whisper to get good-enough subtitles. Distribute to someone for + checking and improving. +- Define the editing steps (which segments become which videos and + their descriptions) in a YAML file. +- Run ffmpeg-editlist, which takes combines the previous three steps + into final videos. + + + +## Exercises + +### Exercise A + +These exercises will take you through the whole sequence. + +:::::{exercise} Editing-1: Get your sample video + +Download a sample video: + +* Video (raw): +* Whisper subtitles (of raw video): + +* [Schedule of + workshop](https://scicomp.aalto.fi/training/scip/kickstart-2023/#schedule) + (day 1, 11:35--12:25) - used for making the descriptions. ::::: + + +:::::{exercise} Editing-2: Run Whisper to generate raw subtitles and test video. + +First off, install Whisper and generate the base subtitles, based +on the. Since this is probably too much to expect for a short +lesson, they are provided for you (above), but if you want you can +try using Whisper, or generating the subtitles some other way. + +You can start generating subtitles now, while you do the next +steps, so that they are ready by the time you are ready to apply +the editlist. ffmpeg-editlist can also slice up the subtitles from +the main video to make subtitles for each segment you cut out. + +Whisper is left as an exercise to the reader. + +::::{solution} + +Example Whisper command: + +```console +$ whisper --device cuda --output_format srt --initial_prompt="Welcome to CodeRefinery day four." --lang en --condition_on_previous_text False INPUT.mkv +``` + +An initial prompt like this make Whisper more likely to output +full sentences, instead of a stream of words with no +punctuation. +:::: +::::: + +:::::{exercise} Editing-3: Create the basic editlist.yaml file + +Install +[ffmpeg-editlist](https://github.com/coderefinery/ffmpeg-editlist) and +try to follow its instructions, to create an edit with these features: + +* The input definition. +* Two output sections: the "Intro to the course", and "From data + storage to your science" talks (Remember it said the recording + started at 11:35... look at the schedule for hints on when it + might start!). This should have a start/end timestamp from the + *original* video. + +A basic example: + +```yaml +- input: day1-raw.mkv + +# This is the output from one section. Your result should have two of these sections. +- output: part1.mkv + title: something + description: >- + some long + description of the + segment + editlist: + - start: 10:00 # start timestamp of the section, in *original* video + - end: 20:00 # end timestamp of the section, in the *original* video +``` + +::::{solution} + +This is an excerpt from our [actual editlist file of this +course](https://github.com/AaltoSciComp/video-editlists-asc/blob/master/kickstart-2023.yaml#L16-L53) + +```yaml +- input: day1-obs.mkv + +- output: day1-intro.mkv + title: 1.2 Introduction + description: >- + General introduction to the workshop. + + https://scicomp.aalto.fi/training/kickstart/intro/ + + editlist: + - start: 00:24:10 + - end: 00:37:31 + + +- output: day1-from-data-storage-to-your-science.mkv + title: "1.3 From data storage to your science" + description: >- + Data is how most computational work starts, whether it is + externally collected, simulation code, or generated. And these + days, you can work on data even remotely, and these workflows + aren't obvious. We discuss how data storage choices lead to + computational workflows. + + https://hackmd.io/@AaltoSciComp/SciCompIntro + + editlist: + - start: 00:37:43 + - end: 00:50:05 +``` +:::: +::::: + +:::::{admonition} Discussion: what makes a video easy to edit? +--- +class: discussion +--- + +* Clear speaking and have high audio quality. +* For subtitle generation: Separate sentences cleanly, otherwise it + gets in a "stream of words" instead of "punctuated sentences" + mode. +* Clearly screen-sharing the place you are at, including section + name. +* Clear transitions, "OK, now let's move on to the next lesson, + LESSON-NAME. Going back to the main page, we see it here." +* Clearly indicate where the transitions are +* Hover mouse cursor over the area you are currently talking about. +* Scroll screen when you move on to a new topic. +* Accurate course webpage and sticking to the schedule + +All of these are also good for learners. By editing videos, you +become an advocate for good teaching overall. +::::: + + +:::::{exercise} Editing-4: Run ffmpeg-editlist + +Install ffmpeg-editlist: ``pip install ffmpeg-editlist[srt]`` (you +may want to use a virtual environment, but these are very minimal +dependencies). + +The ``ffmpeg`` command line tool must be available in your +``PATH``. + +::::{solution} + +It can be run with (where ``.`` is the directory containing the +input files): + +```console +$ ffmpeg-editlist editlist.yaml . +``` + +Just running like this is quick and works, but the stream may be +garbled in the first few seconds (because it's missing a key +frame). (A future exercise will go over fixing this. +Basically, add the ``--reencode`` option, which re-encodes the +video (this is **slow**). Don't do it yet. + +Look at the ``.info.txt`` files that come out. +:::: +::::: + + +:::::{exercise} Editing-5: Add more features + +* Several chapter definitions.(re-run and you should see a + ``.info.txt`` file also generated). Video chapter definitions + are timestamps of the *original* video, that get translated to + timestamps of the *output* video. + + ```yaml + + - output: part1.mkv + editlist: + - start: 10:00 + - -: Introduction # <-- New, `-` means "at start time" + - 10:45: Part 1 # <-- New + - 15:00: Part 2 # <-- New + - end: 20:00 + ``` + + Look at the ``.info.txt`` files that come out now. What is new in it? + +* Add in "workshop title", "workshop description", and see the + ``.info.txt`` files that come out now. This is ready for + copy-pasting into a YouTube description (first line is the title, + rest is the description). + + Look at the new ``.info.txt`` files. What is new? + +::::{solution} + +* This course actually didn't have chapters for the first day + sessions, but you can [see chapters for day 2 + here](https://github.com/AaltoSciComp/video-editlists-asc/blob/master/kickstart-2023.yaml#L239-L262), + for example. +* [Example of the workshop description for this + course](https://github.com/AaltoSciComp/video-editlists-asc/blob/master/kickstart-2023.yaml#L1-L13) +* Example info.txt file for the general introduction to the + course. The part after the ``-----`` is the workshop description. + + ``` + 1.2 Introduction - HPC/SciComp Kickstart summer 2023 + + General introduction to the workshop. + + https://scicomp.aalto.fi/training/kickstart/intro/ + + 00:00 Begin introduction <-- Invented for the exercise demo, not real + 03:25 Ways to attend <-- Invented for the exercise demo, not real + 07:12 What if you get lost <-- Invented for the exercise demo, not real + + ----- + + This is part of the Aalto Scientific Computing "Getting + started with Scientific Computing and HPC Kickstart" 2023 + workshop. The videos are available to everyone, but may be + most useful to the people who attended the workshop and want + to review later. + + Playlist: + https://www.youtube.com/playlist?list=PLZLVmS9rf3nMKR2jMglaN4su3ojWtWMVw + + Workshop webpage: + https://scicomp.aalto.fi/training/scip/kickstart-2023/ + + Aalto Scientific Computing: https://scicomp.aalto.fi/ + ``` +:::: +::::: + +:::::{exercise} Editing-6: Subtitles + +Re-run ffmpeg-editlist with the ``--srt`` option (you have to +install it with ``pip install ffmpeg-editlist[srt]`` to pull in the +necessary dependency). Notice how ``.srt`` files come out now. + +Use some subtitle editor to edit the *original* subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use ``subtitle-editor`` on Linux, or find some other +tool. + +What do you learn from editing the subtitles? + +::::{solution} + +```console +$ ffmpeg-editlist --srt editlist.yaml +``` + +There should now be a ``.srt`` file also generated. It +generated by finding the ``.srt`` of the original video, and +cutting it the same way it cuts the video. Look and you see it +aligns with the original. + +This means that someone could have been working on fixing the +Whisper subtitles while someone else was doing the yaml-editing. +:::: +::::: + + +:::::{exercise} Editing-6: Subtitles + +Re-run ffmpeg-editlist with the ``--srt`` option (you have to +install it with ``pip install ffmpeg-editlist[srt]`` to pull in the +necessary dependency). Notice how ``.srt`` files come out now. + +Use some subtitle editor to edit the *original* subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use ``subtitle-editor`` on Linux, or find some other +tool. + +What do you learn from editing the subtitles? +::::: + + +:::::{exercise} Editing-7: Generate the final output file. + +* Run ffmpeg-editlist with the ``--reencode`` option: this + re-encodes the video and makes sure that there is no black point + at the start. + +* If you re-run with ``--check``, it won't output a new video file, + but it *will* re-output the ``.info.txt`` and ``.srt`` files. + This is useful when you adjust descriptions or chapters. +::::: + + +:::::{admonition} Discussion: how to distribute this? +--- +class: discussion +--- + +Create a flowchat of all the parts that need to be done, and which +parts can be done in parallel. Don't forget things that you might +need to do before the workshop starts. + +How hard was this editing? Was it worth it? +::::: + + +### Exercise B + + +This is a more limited (and older) version of the above exercise, +using an synthetic example video. + +:::::{exercise} Use ffmpeg-editlist to edit this sample video + +Prerequisites: ``ffmpeg`` must be installed on your computer +outside of Python. Be able to install ffmpeg-editlist. This is +simple in a Python virtual environment, but if not the only +dependency is ``PyYAML``. + +* Download the sample video: +* Copy a sample editlist YAML +* Modify it to cut out the dead time at the beginning and the end. +* If desired, add a description and table-of-contents to the + video. +* Run ffmpeg-editlist to produce a processed video. + +::::{solution} + +```yaml +- input: sample-video-to-edit.raw.mkv +- output: sample-video-to-edit.processed.mkv + description: > + editlist: + - start: 00:16 + - 00:15: demonstration + - 00:20: discussion + - stop: 00:25 +``` + +```console +$ ffmpeg-editlist editlist.yaml video/ -o video/ +``` + +Along with the processed video, we get +``sample-video-to-edit.processed.mkv.info.txt``:: + +``` +This is a sample video + + +00:00 Demonstration +00:04 Discussion +``` +:::: +::::: + +## See also + +* ffmpeg-editlist demo: +* Full demo of producing videos (everything in these exercises): +* Example YAML editlists: + + + + + +:::{keypoints} +- Video editing is very useful for learning +- Set your time budget and make it good enough in that time +- Reviewing videos improves your teaching, too. +::: diff --git a/branch/comms/_sources/why-we-stream.md.txt b/branch/comms/_sources/why-we-stream.md.txt new file mode 100644 index 0000000..56d5e5e --- /dev/null +++ b/branch/comms/_sources/why-we-stream.md.txt @@ -0,0 +1,100 @@ +(why-we-stream)= + +# Why we stream + +:::{objectives} +- Learn the general history of CodeRefinery streaming. +- Discuss the benefits of streaming and recording +- Discuss the downsides and difficulties +::: + +:::{instructor-note} +- Discussion: 10 min +- Q&A: 5 min +- Exercises: 0 min +::: + + +This is a general discussion of the topics of the day, focused on the +history of why we stream and record, how we got here, and how people +feel about it. We won't focus on how anything is done. + + +## Icebreaker questions + +- What is the most people you have taught for? +- What are the distinct parts of teaching, that can be + separated? (teaching, helping, etc) + + +## What is streaming and recording? + +- Streaming is mass communication: one to many + - Interaction audience→presenters is more limited (but different) +- Using consumer-grade tools, normal people can reach huge audiences + by Twitch/YouTube/etc. +- This isn't actually that hard: people with much less training than + us do it all the time. +- They reach huge audiences and maintain engagement for long events. + +**Recording and rapid video editing is useful even without +streaming.** + + +## History + +- In-person workshops + - 3 × full day, required travel, infrequent, one-shot +- Covid and remote teaching + - Traditional "Zoom" teaching several times +- Mega-CodeRefinery workshop + - 100-person Zoom teaching + - Emphasis on teams +- Research Software Hour + - Livestream free-form discussions on Twitch +- Streamed "HPC Kickstart" courses + + + +## Benefits and disadvantages + +Benefits: +- Larger size gives more (but different) interaction possibility + - "Notes" for async Q&A +- Recording (with no privacy risk) allows instant reviews +- Stream-scale allows for many of the things you have learned about in + days 1-3. + +Disadvantages: +- Requires training for using the tools +- Requires a certain scale to be worth it +- Coordination is much harder for big events + +When would I recommend it? +- No: For small courses +- Questionable: Medium sized courses with no videos +- Yes: When you want the largest audience +- Yes: When you want without registration required +- Yes: When you want good reusability/fast videos + + +## Future prospects (briefly) + +- Streaming probably stays as a CodeRefinery tool +- We *can* scale our courses much larger than they are now. Why don't + we, together with others? +- These tools are useful in other places too + - I've used them to record my own talks to make videos of my + single-person presentations or record conference talks nicer than Zoom. + + +## Q&A + +Q&A from audience + + +:::{keypoints} +- Streaming optimizes a course for different things +- The disadvantages can be compensated for +- There are benefits and disadvantages +::: diff --git a/branch/comms/_sphinx_design_static/design-tabs.js b/branch/comms/_sphinx_design_static/design-tabs.js new file mode 100644 index 0000000..b25bd6a --- /dev/null +++ b/branch/comms/_sphinx_design_static/design-tabs.js @@ -0,0 +1,101 @@ +// @ts-check + +// Extra JS capability for selected tabs to be synced +// The selection is stored in local storage so that it persists across page loads. + +/** + * @type {Record} + */ +let sd_id_to_elements = {}; +const storageKeyPrefix = "sphinx-design-tab-id-"; + +/** + * Create a key for a tab element. + * @param {HTMLElement} el - The tab element. + * @returns {[string, string, string] | null} - The key. + * + */ +function create_key(el) { + let syncId = el.getAttribute("data-sync-id"); + let syncGroup = el.getAttribute("data-sync-group"); + if (!syncId || !syncGroup) return null; + return [syncGroup, syncId, syncGroup + "--" + syncId]; +} + +/** + * Initialize the tab selection. + * + */ +function ready() { + // Find all tabs with sync data + + /** @type {string[]} */ + let groups = []; + + document.querySelectorAll(".sd-tab-label").forEach((label) => { + if (label instanceof HTMLElement) { + let data = create_key(label); + if (data) { + let [group, id, key] = data; + + // add click event listener + // @ts-ignore + label.onclick = onSDLabelClick; + + // store map of key to elements + if (!sd_id_to_elements[key]) { + sd_id_to_elements[key] = []; + } + sd_id_to_elements[key].push(label); + + if (groups.indexOf(group) === -1) { + groups.push(group); + // Check if a specific tab has been selected via URL parameter + const tabParam = new URLSearchParams(window.location.search).get( + group + ); + if (tabParam) { + console.log( + "sphinx-design: Selecting tab id for group '" + + group + + "' from URL parameter: " + + tabParam + ); + window.sessionStorage.setItem(storageKeyPrefix + group, tabParam); + } + } + + // Check is a specific tab has been selected previously + let previousId = window.sessionStorage.getItem( + storageKeyPrefix + group + ); + if (previousId === id) { + // console.log( + // "sphinx-design: Selecting tab from session storage: " + id + // ); + // @ts-ignore + label.previousElementSibling.checked = true; + } + } + } + }); +} + +/** + * Activate other tabs with the same sync id. + * + * @this {HTMLElement} - The element that was clicked. + */ +function onSDLabelClick() { + let data = create_key(this); + if (!data) return; + let [group, id, key] = data; + for (const label of sd_id_to_elements[key]) { + if (label === this) continue; + // @ts-ignore + label.previousElementSibling.checked = true; + } + window.sessionStorage.setItem(storageKeyPrefix + group, id); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/branch/comms/_sphinx_design_static/sphinx-design.min.css b/branch/comms/_sphinx_design_static/sphinx-design.min.css new file mode 100644 index 0000000..860c36d --- /dev/null +++ b/branch/comms/_sphinx_design_static/sphinx-design.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative;font-size:var(--sd-fontsize-dropdown)}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary.sd-summary-title{padding:.5em .6em .5em 1em;font-size:var(--sd-fontsize-dropdown-title);font-weight:var(--sd-fontweight-dropdown-title);user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;list-style:none;display:inline-flex;justify-content:space-between}details.sd-dropdown summary.sd-summary-title::-webkit-details-marker{display:none}details.sd-dropdown summary.sd-summary-title:focus{outline:none}details.sd-dropdown summary.sd-summary-title .sd-summary-icon{margin-right:.6em;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary.sd-summary-title .sd-summary-text{flex-grow:1;line-height:1.5;padding-right:.5rem}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker{pointer-events:none;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker svg{opacity:.6}details.sd-dropdown summary.sd-summary-title:hover .sd-summary-state-marker svg{opacity:1;transform:scale(1.1)}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown .sd-summary-chevron-right{transition:.25s}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-right{transform:rotate(90deg)}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-down{transform:rotate(180deg)}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-bg: rgba(0, 113, 188, 0.2);--sd-color-secondary-bg: rgba(108, 117, 125, 0.2);--sd-color-success-bg: rgba(40, 167, 69, 0.2);--sd-color-info-bg: rgba(23, 162, 184, 0.2);--sd-color-warning-bg: rgba(240, 179, 126, 0.2);--sd-color-danger-bg: rgba(220, 53, 69, 0.2);--sd-color-light-bg: rgba(248, 249, 250, 0.2);--sd-color-muted-bg: rgba(108, 117, 125, 0.2);--sd-color-dark-bg: rgba(33, 37, 41, 0.2);--sd-color-black-bg: rgba(0, 0, 0, 0.2);--sd-color-white-bg: rgba(255, 255, 255, 0.2);--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem;--sd-fontsize-dropdown: inherit;--sd-fontsize-dropdown-title: 1rem;--sd-fontweight-dropdown-title: 700} diff --git a/branch/comms/_static/_sphinx_javascript_frameworks_compat.js b/branch/comms/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 0000000..8141580 --- /dev/null +++ b/branch/comms/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/branch/comms/_static/basic.css b/branch/comms/_static/basic.css new file mode 100644 index 0000000..f316efc --- /dev/null +++ b/branch/comms/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/branch/comms/_static/check-solid.svg b/branch/comms/_static/check-solid.svg new file mode 100644 index 0000000..92fad4b --- /dev/null +++ b/branch/comms/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/branch/comms/_static/clipboard.min.js b/branch/comms/_static/clipboard.min.js new file mode 100644 index 0000000..54b3c46 --- /dev/null +++ b/branch/comms/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/branch/comms/_static/copybutton.css b/branch/comms/_static/copybutton.css new file mode 100644 index 0000000..f1916ec --- /dev/null +++ b/branch/comms/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/branch/comms/_static/copybutton.js b/branch/comms/_static/copybutton.js new file mode 100644 index 0000000..2ea7ff3 --- /dev/null +++ b/branch/comms/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/branch/comms/_static/copybutton_funcs.js b/branch/comms/_static/copybutton_funcs.js new file mode 100644 index 0000000..dbe1aaa --- /dev/null +++ b/branch/comms/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/branch/comms/_static/css/badge_only.css b/branch/comms/_static/css/badge_only.css new file mode 100644 index 0000000..c718cee --- /dev/null +++ b/branch/comms/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/branch/comms/_static/css/fonts/Roboto-Slab-Bold.woff b/branch/comms/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/branch/comms/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/branch/comms/_static/css/fonts/Roboto-Slab-Bold.woff2 b/branch/comms/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/branch/comms/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/branch/comms/_static/css/fonts/Roboto-Slab-Regular.woff b/branch/comms/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/branch/comms/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/branch/comms/_static/css/fonts/Roboto-Slab-Regular.woff2 b/branch/comms/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/branch/comms/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/branch/comms/_static/css/fonts/fontawesome-webfont.eot b/branch/comms/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/branch/comms/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/branch/comms/_static/css/fonts/fontawesome-webfont.svg b/branch/comms/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/branch/comms/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/branch/comms/_static/css/fonts/fontawesome-webfont.ttf b/branch/comms/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/branch/comms/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/branch/comms/_static/css/fonts/fontawesome-webfont.woff b/branch/comms/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/branch/comms/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/branch/comms/_static/css/fonts/fontawesome-webfont.woff2 b/branch/comms/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/branch/comms/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/branch/comms/_static/css/fonts/lato-bold-italic.woff b/branch/comms/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/branch/comms/_static/css/fonts/lato-bold-italic.woff differ diff --git a/branch/comms/_static/css/fonts/lato-bold-italic.woff2 b/branch/comms/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/branch/comms/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/branch/comms/_static/css/fonts/lato-bold.woff b/branch/comms/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/branch/comms/_static/css/fonts/lato-bold.woff differ diff --git a/branch/comms/_static/css/fonts/lato-bold.woff2 b/branch/comms/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/branch/comms/_static/css/fonts/lato-bold.woff2 differ diff --git a/branch/comms/_static/css/fonts/lato-normal-italic.woff b/branch/comms/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/branch/comms/_static/css/fonts/lato-normal-italic.woff differ diff --git a/branch/comms/_static/css/fonts/lato-normal-italic.woff2 b/branch/comms/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/branch/comms/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/branch/comms/_static/css/fonts/lato-normal.woff b/branch/comms/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/branch/comms/_static/css/fonts/lato-normal.woff differ diff --git a/branch/comms/_static/css/fonts/lato-normal.woff2 b/branch/comms/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/branch/comms/_static/css/fonts/lato-normal.woff2 differ diff --git a/branch/comms/_static/css/theme.css b/branch/comms/_static/css/theme.css new file mode 100644 index 0000000..19a446a --- /dev/null +++ b/branch/comms/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/branch/comms/_static/design-tabs.js b/branch/comms/_static/design-tabs.js new file mode 100644 index 0000000..b25bd6a --- /dev/null +++ b/branch/comms/_static/design-tabs.js @@ -0,0 +1,101 @@ +// @ts-check + +// Extra JS capability for selected tabs to be synced +// The selection is stored in local storage so that it persists across page loads. + +/** + * @type {Record} + */ +let sd_id_to_elements = {}; +const storageKeyPrefix = "sphinx-design-tab-id-"; + +/** + * Create a key for a tab element. + * @param {HTMLElement} el - The tab element. + * @returns {[string, string, string] | null} - The key. + * + */ +function create_key(el) { + let syncId = el.getAttribute("data-sync-id"); + let syncGroup = el.getAttribute("data-sync-group"); + if (!syncId || !syncGroup) return null; + return [syncGroup, syncId, syncGroup + "--" + syncId]; +} + +/** + * Initialize the tab selection. + * + */ +function ready() { + // Find all tabs with sync data + + /** @type {string[]} */ + let groups = []; + + document.querySelectorAll(".sd-tab-label").forEach((label) => { + if (label instanceof HTMLElement) { + let data = create_key(label); + if (data) { + let [group, id, key] = data; + + // add click event listener + // @ts-ignore + label.onclick = onSDLabelClick; + + // store map of key to elements + if (!sd_id_to_elements[key]) { + sd_id_to_elements[key] = []; + } + sd_id_to_elements[key].push(label); + + if (groups.indexOf(group) === -1) { + groups.push(group); + // Check if a specific tab has been selected via URL parameter + const tabParam = new URLSearchParams(window.location.search).get( + group + ); + if (tabParam) { + console.log( + "sphinx-design: Selecting tab id for group '" + + group + + "' from URL parameter: " + + tabParam + ); + window.sessionStorage.setItem(storageKeyPrefix + group, tabParam); + } + } + + // Check is a specific tab has been selected previously + let previousId = window.sessionStorage.getItem( + storageKeyPrefix + group + ); + if (previousId === id) { + // console.log( + // "sphinx-design: Selecting tab from session storage: " + id + // ); + // @ts-ignore + label.previousElementSibling.checked = true; + } + } + } + }); +} + +/** + * Activate other tabs with the same sync id. + * + * @this {HTMLElement} - The element that was clicked. + */ +function onSDLabelClick() { + let data = create_key(this); + if (!data) return; + let [group, id, key] = data; + for (const label of sd_id_to_elements[key]) { + if (label === this) continue; + // @ts-ignore + label.previousElementSibling.checked = true; + } + window.sessionStorage.setItem(storageKeyPrefix + group, id); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/branch/comms/_static/doctools.js b/branch/comms/_static/doctools.js new file mode 100644 index 0000000..4d67807 --- /dev/null +++ b/branch/comms/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/branch/comms/_static/documentation_options.js b/branch/comms/_static/documentation_options.js new file mode 100644 index 0000000..87fc516 --- /dev/null +++ b/branch/comms/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'dirhtml', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/branch/comms/_static/file.png b/branch/comms/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/branch/comms/_static/file.png differ diff --git a/branch/comms/_static/jquery.js b/branch/comms/_static/jquery.js new file mode 100644 index 0000000..c4c6022 --- /dev/null +++ b/branch/comms/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!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(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=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,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).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 w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\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(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.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,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){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 H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.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--)b.attrHandle[n[r]]=t}function pe(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 de(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 d=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")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.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}},b.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[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.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},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),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(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.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},j=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)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(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==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(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?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{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 G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.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("(^|"+M+")"+e+"("+M+"|$)"))&&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:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.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 S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(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").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.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),m(t)&&(t=t.call(e,n,S.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)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.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"===S.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"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.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)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.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?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.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)}}),S.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){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/comms/_static/js/html5shiv.min.js b/branch/comms/_static/js/html5shiv.min.js new file mode 100644 index 0000000..cd1c674 --- /dev/null +++ b/branch/comms/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/comms/_static/js/theme.js b/branch/comms/_static/js/theme.js new file mode 100644 index 0000000..1fddb6e --- /dev/null +++ b/branch/comms/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/branch/comms/_static/minipres.js b/branch/comms/_static/minipres.js new file mode 100644 index 0000000..ad11c87 --- /dev/null +++ b/branch/comms/_static/minipres.js @@ -0,0 +1,223 @@ +// Add goTo method to elements +// http://stackoverflow.com/questions/4801655/how-to-go-to-a-specific-element-on-page +(function($) { + $.fn.goTo = function() { + $('html, body').animate({ + scrollTop: $(this).offset().top //+ 'px' + }, 'fast'); + return this; // for chaining... + } +})(jQuery); + +// NO good way to do this!. Copy a hack from here +// https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript +// https://stackoverflow.com/a/2880929 +var urlParams; +(window.onpopstate = function () { + var match, + pl = /\+/g, // Regex for replacing addition symbol with a space + search = /([^&=]+)=?([^&]*)/g, + decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, + query = window.location.search.substring(1); + urlParams = {}; + while (match = search.exec(query)) + urlParams[decode(match[1])] = decode(match[2]); +})(); + +// Select heading levels +var maxHeading = urlParams['h'] +if (maxHeading === undefined) maxHeading = 2 +var headingLevels = []; +for (h=2 ; h (sections.length-1) ) { + // if we would scroll past bottom, or above top, do nothing + return; + } + + console.log('xxxxxx'); + var targetSection = sections[targetPos]; + console.log(targetSection, typeof(targetSection)); + + // Return targetSection top and height + var secProperties = section_top_and_height(targetSection); + var top = secProperties['top']; + var height = secProperties['height'] + var win_height = window.innerHeight; + //console.info(top, height, win_height) + + var scroll_to = 0; + if (height >= win_height || height == 0) { + scroll_to = top; + } else { + scroll_to = top - (win_height-height)/3.; + } + //console.info(top, height, win_height, scroll_to) + + $('html, body').animate({ + scrollTop: scroll_to //+ 'px' + }, 'fast'); + +} + + +function minipres() { + /* Enable the minipres mode: + - call the hide() function + - set up the scrolling listener + */ + document.addEventListener('keydown', function (event) { + switch(event.which) { + case 37: // left + switch_slide(-1); + event.preventDefault(); + return false; + break; + //case 38: // up + case 39: // right + switch_slide(+1); + event.preventDefault(); + return false; + break; + //case 40: // down + default: + return; // exit this handler for other keys + } + }, true) + + hide() + + // Increase space between sections + //$("div .section").css('margin-bottom', '50%'); + $(sectionSelector).css('margin-top', '50%'); + + // Reduce size/color of other sections + if (hiddenSectionSelector.length > 0) { + var hideNodes = $(hiddenSectionSelector); + console.log(typeof hideNodes, hideNodes); + for (node in hideNodes) { + console.log("a", typeof node, node); + node = hideNodes[node]; // what's right way to iterate values? + console.log("b", typeof node, node); + if (node.parentNode && node.parentNode.className == "section") { + node = node.parentNode; + console.log("c", typeof node, node); + //node.css['transform'] = 'scale(.5)'; + //node.css['transform-origin'] = 'top center'; + $(node).css('color', 'lightgrey'); + //$(node).css('font-size', '20%'); + //$(node).css('visibility', 'collapse'); + //ntahousnatouhasno; + } + } + } +} + +function hide() { + /* Hide all non-essential elements on the page + */ + + // This is for sphinx_rst_theme and readthedocs + $(".wy-nav-side").remove(); + $(".wy-nav-content-wrap").css('margin-left', 0); + $('.rst-versions').remove(); // readthedocs version selector + + // Add other formats here. +} + + +var slideshow = minipres; + +if (window.location.search.match(/[?&](minipres|slideshow|pres)([=&]|$)/) ) { + //minipres() + window.addEventListener("load", minipres); +} else if (window.location.search.match(/[?&](plain)([=&]|$)/) ) { + window.addEventListener("load", hide); +} diff --git a/branch/comms/_static/minus.png b/branch/comms/_static/minus.png new file mode 100644 index 0000000..d96755f Binary files /dev/null and b/branch/comms/_static/minus.png differ diff --git a/branch/comms/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css b/branch/comms/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css new file mode 100644 index 0000000..3356631 --- /dev/null +++ b/branch/comms/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css @@ -0,0 +1,2342 @@ +/* Variables */ +:root { + --mystnb-source-bg-color: #f7f7f7; + --mystnb-stdout-bg-color: #fcfcfc; + --mystnb-stderr-bg-color: #fdd; + --mystnb-traceback-bg-color: #fcfcfc; + --mystnb-source-border-color: #ccc; + --mystnb-source-margin-color: green; + --mystnb-stdout-border-color: #f7f7f7; + --mystnb-stderr-border-color: #f7f7f7; + --mystnb-traceback-border-color: #ffd6d6; + --mystnb-hide-prompt-opacity: 70%; + --mystnb-source-border-radius: .4em; + --mystnb-source-border-width: 1px; +} + +/* Whole cell */ +div.container.cell { + padding-left: 0; + margin-bottom: 1em; +} + +/* Removing all background formatting so we can control at the div level */ +.cell_input div.highlight, +.cell_output pre, +.cell_input pre, +.cell_output .output { + border: none; + box-shadow: none; +} + +.cell_output .output pre, +.cell_input pre { + margin: 0px; +} + +/* Input cells */ +div.cell div.cell_input, +div.cell details.above-input>summary { + padding-left: 0em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + background-color: var(--mystnb-source-bg-color); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; + border-radius: var(--mystnb-source-border-radius); +} + +div.cell_input>div, +div.cell_output div.output>div.highlight { + margin: 0em !important; + border: none !important; +} + +/* All cell outputs */ +.cell_output { + padding-left: 1em; + padding-right: 0em; + margin-top: 1em; +} + +/* Text outputs from cells */ +.cell_output .output.text_plain, +.cell_output .output.traceback, +.cell_output .output.stream, +.cell_output .output.stderr { + margin-top: 1em; + margin-bottom: 0em; + box-shadow: none; +} + +.cell_output .output.text_plain, +.cell_output .output.stream { + background: var(--mystnb-stdout-bg-color); + border: 1px solid var(--mystnb-stdout-border-color); +} + +.cell_output .output.stderr { + background: var(--mystnb-stderr-bg-color); + border: 1px solid var(--mystnb-stderr-border-color); +} + +.cell_output .output.traceback { + background: var(--mystnb-traceback-bg-color); + border: 1px solid var(--mystnb-traceback-border-color); +} + +/* Collapsible cell content */ +div.cell details.above-input div.cell_input { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-top: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; +} + +div.cell div.cell_input.above-output-prompt { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +div.cell details.above-input>summary { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; + padding-left: 1em; + margin-bottom: 0; +} + +div.cell details.above-output>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.below-input>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-top: none; + border-bottom-left-radius: var(--mystnb-source-border-radius); + border-bottom-right-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.hide>summary>span { + opacity: var(--mystnb-hide-prompt-opacity); +} + +div.cell details.hide[open]>summary>span.collapsed { + display: none; +} + +div.cell details.hide:not([open])>summary>span.expanded { + display: none; +} + +@keyframes collapsed-fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} +div.cell details.hide[open]>summary~* { + -moz-animation: collapsed-fade-in 0.3s ease-in-out; + -webkit-animation: collapsed-fade-in 0.3s ease-in-out; + animation: collapsed-fade-in 0.3s ease-in-out; +} + +/* Math align to the left */ +.cell_output .MathJax_Display { + text-align: left !important; +} + +/* Pandas tables. Pulled from the Jupyter / nbsphinx CSS */ +div.cell_output table { + border: none; + border-collapse: collapse; + border-spacing: 0; + color: black; + font-size: 1em; + table-layout: fixed; +} + +div.cell_output thead { + border-bottom: 1px solid black; + vertical-align: bottom; +} + +div.cell_output tr, +div.cell_output th, +div.cell_output td { + text-align: right; + vertical-align: middle; + padding: 0.5em 0.5em; + line-height: normal; + white-space: normal; + max-width: none; + border: none; +} + +div.cell_output th { + font-weight: bold; +} + +div.cell_output tbody tr:nth-child(odd) { + background: #f5f5f5; +} + +div.cell_output tbody tr:hover { + background: rgba(66, 165, 245, 0.2); +} + +/** source code line numbers **/ +span.linenos { + opacity: 0.5; +} + +/* Inline text from `paste` operation */ + +span.pasted-text { + font-weight: bold; +} + +span.pasted-inline img { + max-height: 2em; +} + +tbody span.pasted-inline img { + max-height: none; +} + +/* Font colors for translated ANSI escape sequences +Color values are copied from Jupyter Notebook +https://github.com/jupyter/notebook/blob/52581f8eda9b319eb0390ac77fe5903c38f81e3e/notebook/static/notebook/less/ansicolors.less#L14-L21 +Background colors from +https://nbsphinx.readthedocs.io/en/latest/code-cells.html#ANSI-Colors +*/ +div.highlight .-Color-Bold { + font-weight: bold; +} + +div.highlight .-Color[class*=-Black] { + color: #3E424D +} + +div.highlight .-Color[class*=-Red] { + color: #E75C58 +} + +div.highlight .-Color[class*=-Green] { + color: #00A250 +} + +div.highlight .-Color[class*=-Yellow] { + color: #DDB62B +} + +div.highlight .-Color[class*=-Blue] { + color: #208FFB +} + +div.highlight .-Color[class*=-Magenta] { + color: #D160C4 +} + +div.highlight .-Color[class*=-Cyan] { + color: #60C6C8 +} + +div.highlight .-Color[class*=-White] { + color: #C5C1B4 +} + +div.highlight .-Color[class*=-BGBlack] { + background-color: #3E424D +} + +div.highlight .-Color[class*=-BGRed] { + background-color: #E75C58 +} + +div.highlight .-Color[class*=-BGGreen] { + background-color: #00A250 +} + +div.highlight .-Color[class*=-BGYellow] { + background-color: #DDB62B +} + +div.highlight .-Color[class*=-BGBlue] { + background-color: #208FFB +} + +div.highlight .-Color[class*=-BGMagenta] { + background-color: #D160C4 +} + +div.highlight .-Color[class*=-BGCyan] { + background-color: #60C6C8 +} + +div.highlight .-Color[class*=-BGWhite] { + background-color: #C5C1B4 +} + +/* Font colors for 8-bit ANSI */ + +div.highlight .-Color[class*=-C0] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC0] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C1] { + color: #800000 +} + +div.highlight .-Color[class*=-BGC1] { + background-color: #800000 +} + +div.highlight .-Color[class*=-C2] { + color: #008000 +} + +div.highlight .-Color[class*=-BGC2] { + background-color: #008000 +} + +div.highlight .-Color[class*=-C3] { + color: #808000 +} + +div.highlight .-Color[class*=-BGC3] { + background-color: #808000 +} + +div.highlight .-Color[class*=-C4] { + color: #000080 +} + +div.highlight .-Color[class*=-BGC4] { + background-color: #000080 +} + +div.highlight .-Color[class*=-C5] { + color: #800080 +} + +div.highlight .-Color[class*=-BGC5] { + background-color: #800080 +} + +div.highlight .-Color[class*=-C6] { + color: #008080 +} + +div.highlight .-Color[class*=-BGC6] { + background-color: #008080 +} + +div.highlight .-Color[class*=-C7] { + color: #C0C0C0 +} + +div.highlight .-Color[class*=-BGC7] { + background-color: #C0C0C0 +} + +div.highlight .-Color[class*=-C8] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC8] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C9] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC9] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C10] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC10] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C11] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC11] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C12] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC12] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C13] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC13] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C14] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC14] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C15] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC15] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C16] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC16] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C17] { + color: #00005F +} + +div.highlight .-Color[class*=-BGC17] { + background-color: #00005F +} + +div.highlight .-Color[class*=-C18] { + color: #000087 +} + +div.highlight .-Color[class*=-BGC18] { + background-color: #000087 +} + +div.highlight .-Color[class*=-C19] { + color: #0000AF +} + +div.highlight .-Color[class*=-BGC19] { + background-color: #0000AF +} + +div.highlight .-Color[class*=-C20] { + color: #0000D7 +} + +div.highlight .-Color[class*=-BGC20] { + background-color: #0000D7 +} + +div.highlight .-Color[class*=-C21] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC21] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C22] { + color: #005F00 +} + +div.highlight .-Color[class*=-BGC22] { + background-color: #005F00 +} + +div.highlight .-Color[class*=-C23] { + color: #005F5F +} + +div.highlight .-Color[class*=-BGC23] { + background-color: #005F5F +} + +div.highlight .-Color[class*=-C24] { + color: #005F87 +} + +div.highlight .-Color[class*=-BGC24] { + background-color: #005F87 +} + +div.highlight .-Color[class*=-C25] { + color: #005FAF +} + +div.highlight .-Color[class*=-BGC25] { + background-color: #005FAF +} + +div.highlight .-Color[class*=-C26] { + color: #005FD7 +} + +div.highlight .-Color[class*=-BGC26] { + background-color: #005FD7 +} + +div.highlight .-Color[class*=-C27] { + color: #005FFF +} + +div.highlight .-Color[class*=-BGC27] { + background-color: #005FFF +} + +div.highlight .-Color[class*=-C28] { + color: #008700 +} + +div.highlight .-Color[class*=-BGC28] { + background-color: #008700 +} + +div.highlight .-Color[class*=-C29] { + color: #00875F +} + +div.highlight .-Color[class*=-BGC29] { + background-color: #00875F +} + +div.highlight .-Color[class*=-C30] { + color: #008787 +} + +div.highlight .-Color[class*=-BGC30] { + background-color: #008787 +} + +div.highlight .-Color[class*=-C31] { + color: #0087AF +} + +div.highlight .-Color[class*=-BGC31] { + background-color: #0087AF +} + +div.highlight .-Color[class*=-C32] { + color: #0087D7 +} + +div.highlight .-Color[class*=-BGC32] { + background-color: #0087D7 +} + +div.highlight .-Color[class*=-C33] { + color: #0087FF +} + +div.highlight .-Color[class*=-BGC33] { + background-color: #0087FF +} + +div.highlight .-Color[class*=-C34] { + color: #00AF00 +} + +div.highlight .-Color[class*=-BGC34] { + background-color: #00AF00 +} + +div.highlight .-Color[class*=-C35] { + color: #00AF5F +} + +div.highlight .-Color[class*=-BGC35] { + background-color: #00AF5F +} + +div.highlight .-Color[class*=-C36] { + color: #00AF87 +} + +div.highlight .-Color[class*=-BGC36] { + background-color: #00AF87 +} + +div.highlight .-Color[class*=-C37] { + color: #00AFAF +} + +div.highlight .-Color[class*=-BGC37] { + background-color: #00AFAF +} + +div.highlight .-Color[class*=-C38] { + color: #00AFD7 +} + +div.highlight .-Color[class*=-BGC38] { + background-color: #00AFD7 +} + +div.highlight .-Color[class*=-C39] { + color: #00AFFF +} + +div.highlight .-Color[class*=-BGC39] { + background-color: #00AFFF +} + +div.highlight .-Color[class*=-C40] { + color: #00D700 +} + +div.highlight .-Color[class*=-BGC40] { + background-color: #00D700 +} + +div.highlight .-Color[class*=-C41] { + color: #00D75F +} + +div.highlight .-Color[class*=-BGC41] { + background-color: #00D75F +} + +div.highlight .-Color[class*=-C42] { + color: #00D787 +} + +div.highlight .-Color[class*=-BGC42] { + background-color: #00D787 +} + +div.highlight .-Color[class*=-C43] { + color: #00D7AF +} + +div.highlight .-Color[class*=-BGC43] { + background-color: #00D7AF +} + +div.highlight .-Color[class*=-C44] { + color: #00D7D7 +} + +div.highlight .-Color[class*=-BGC44] { + background-color: #00D7D7 +} + +div.highlight .-Color[class*=-C45] { + color: #00D7FF +} + +div.highlight .-Color[class*=-BGC45] { + background-color: #00D7FF +} + +div.highlight .-Color[class*=-C46] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC46] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C47] { + color: #00FF5F +} + +div.highlight .-Color[class*=-BGC47] { + background-color: #00FF5F +} + +div.highlight .-Color[class*=-C48] { + color: #00FF87 +} + +div.highlight .-Color[class*=-BGC48] { + background-color: #00FF87 +} + +div.highlight .-Color[class*=-C49] { + color: #00FFAF +} + +div.highlight .-Color[class*=-BGC49] { + background-color: #00FFAF +} + +div.highlight .-Color[class*=-C50] { + color: #00FFD7 +} + +div.highlight .-Color[class*=-BGC50] { + background-color: #00FFD7 +} + +div.highlight .-Color[class*=-C51] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC51] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C52] { + color: #5F0000 +} + +div.highlight .-Color[class*=-BGC52] { + background-color: #5F0000 +} + +div.highlight .-Color[class*=-C53] { + color: #5F005F +} + +div.highlight .-Color[class*=-BGC53] { + background-color: #5F005F +} + +div.highlight .-Color[class*=-C54] { + color: #5F0087 +} + +div.highlight .-Color[class*=-BGC54] { + background-color: #5F0087 +} + +div.highlight .-Color[class*=-C55] { + color: #5F00AF +} + +div.highlight .-Color[class*=-BGC55] { + background-color: #5F00AF +} + +div.highlight .-Color[class*=-C56] { + color: #5F00D7 +} + +div.highlight .-Color[class*=-BGC56] { + background-color: #5F00D7 +} + +div.highlight .-Color[class*=-C57] { + color: #5F00FF +} + +div.highlight .-Color[class*=-BGC57] { + background-color: #5F00FF +} + +div.highlight .-Color[class*=-C58] { + color: #5F5F00 +} + +div.highlight .-Color[class*=-BGC58] { + background-color: #5F5F00 +} + +div.highlight .-Color[class*=-C59] { + color: #5F5F5F +} + +div.highlight .-Color[class*=-BGC59] { + background-color: #5F5F5F +} + +div.highlight .-Color[class*=-C60] { + color: #5F5F87 +} + +div.highlight .-Color[class*=-BGC60] { + background-color: #5F5F87 +} + +div.highlight .-Color[class*=-C61] { + color: #5F5FAF +} + +div.highlight .-Color[class*=-BGC61] { + background-color: #5F5FAF +} + +div.highlight .-Color[class*=-C62] { + color: #5F5FD7 +} + +div.highlight .-Color[class*=-BGC62] { + background-color: #5F5FD7 +} + +div.highlight .-Color[class*=-C63] { + color: #5F5FFF +} + +div.highlight .-Color[class*=-BGC63] { + background-color: #5F5FFF +} + +div.highlight .-Color[class*=-C64] { + color: #5F8700 +} + +div.highlight .-Color[class*=-BGC64] { + background-color: #5F8700 +} + +div.highlight .-Color[class*=-C65] { + color: #5F875F +} + +div.highlight .-Color[class*=-BGC65] { + background-color: #5F875F +} + +div.highlight .-Color[class*=-C66] { + color: #5F8787 +} + +div.highlight .-Color[class*=-BGC66] { + background-color: #5F8787 +} + +div.highlight .-Color[class*=-C67] { + color: #5F87AF +} + +div.highlight .-Color[class*=-BGC67] { + background-color: #5F87AF +} + +div.highlight .-Color[class*=-C68] { + color: #5F87D7 +} + +div.highlight .-Color[class*=-BGC68] { + background-color: #5F87D7 +} + +div.highlight .-Color[class*=-C69] { + color: #5F87FF +} + +div.highlight .-Color[class*=-BGC69] { + background-color: #5F87FF +} + +div.highlight .-Color[class*=-C70] { + color: #5FAF00 +} + +div.highlight .-Color[class*=-BGC70] { + background-color: #5FAF00 +} + +div.highlight .-Color[class*=-C71] { + color: #5FAF5F +} + +div.highlight .-Color[class*=-BGC71] { + background-color: #5FAF5F +} + +div.highlight .-Color[class*=-C72] { + color: #5FAF87 +} + +div.highlight .-Color[class*=-BGC72] { + background-color: #5FAF87 +} + +div.highlight .-Color[class*=-C73] { + color: #5FAFAF +} + +div.highlight .-Color[class*=-BGC73] { + background-color: #5FAFAF +} + +div.highlight .-Color[class*=-C74] { + color: #5FAFD7 +} + +div.highlight .-Color[class*=-BGC74] { + background-color: #5FAFD7 +} + +div.highlight .-Color[class*=-C75] { + color: #5FAFFF +} + +div.highlight .-Color[class*=-BGC75] { + background-color: #5FAFFF +} + +div.highlight .-Color[class*=-C76] { + color: #5FD700 +} + +div.highlight .-Color[class*=-BGC76] { + background-color: #5FD700 +} + +div.highlight .-Color[class*=-C77] { + color: #5FD75F +} + +div.highlight .-Color[class*=-BGC77] { + background-color: #5FD75F +} + +div.highlight .-Color[class*=-C78] { + color: #5FD787 +} + +div.highlight .-Color[class*=-BGC78] { + background-color: #5FD787 +} + +div.highlight .-Color[class*=-C79] { + color: #5FD7AF +} + +div.highlight .-Color[class*=-BGC79] { + background-color: #5FD7AF +} + +div.highlight .-Color[class*=-C80] { + color: #5FD7D7 +} + +div.highlight .-Color[class*=-BGC80] { + background-color: #5FD7D7 +} + +div.highlight .-Color[class*=-C81] { + color: #5FD7FF +} + +div.highlight .-Color[class*=-BGC81] { + background-color: #5FD7FF +} + +div.highlight .-Color[class*=-C82] { + color: #5FFF00 +} + +div.highlight .-Color[class*=-BGC82] { + background-color: #5FFF00 +} + +div.highlight .-Color[class*=-C83] { + color: #5FFF5F +} + +div.highlight .-Color[class*=-BGC83] { + background-color: #5FFF5F +} + +div.highlight .-Color[class*=-C84] { + color: #5FFF87 +} + +div.highlight .-Color[class*=-BGC84] { + background-color: #5FFF87 +} + +div.highlight .-Color[class*=-C85] { + color: #5FFFAF +} + +div.highlight .-Color[class*=-BGC85] { + background-color: #5FFFAF +} + +div.highlight .-Color[class*=-C86] { + color: #5FFFD7 +} + +div.highlight .-Color[class*=-BGC86] { + background-color: #5FFFD7 +} + +div.highlight .-Color[class*=-C87] { + color: #5FFFFF +} + +div.highlight .-Color[class*=-BGC87] { + background-color: #5FFFFF +} + +div.highlight .-Color[class*=-C88] { + color: #870000 +} + +div.highlight .-Color[class*=-BGC88] { + background-color: #870000 +} + +div.highlight .-Color[class*=-C89] { + color: #87005F +} + +div.highlight .-Color[class*=-BGC89] { + background-color: #87005F +} + +div.highlight .-Color[class*=-C90] { + color: #870087 +} + +div.highlight .-Color[class*=-BGC90] { + background-color: #870087 +} + +div.highlight .-Color[class*=-C91] { + color: #8700AF +} + +div.highlight .-Color[class*=-BGC91] { + background-color: #8700AF +} + +div.highlight .-Color[class*=-C92] { + color: #8700D7 +} + +div.highlight .-Color[class*=-BGC92] { + background-color: #8700D7 +} + +div.highlight .-Color[class*=-C93] { + color: #8700FF +} + +div.highlight .-Color[class*=-BGC93] { + background-color: #8700FF +} + +div.highlight .-Color[class*=-C94] { + color: #875F00 +} + +div.highlight .-Color[class*=-BGC94] { + background-color: #875F00 +} + +div.highlight .-Color[class*=-C95] { + color: #875F5F +} + +div.highlight .-Color[class*=-BGC95] { + background-color: #875F5F +} + +div.highlight .-Color[class*=-C96] { + color: #875F87 +} + +div.highlight .-Color[class*=-BGC96] { + background-color: #875F87 +} + +div.highlight .-Color[class*=-C97] { + color: #875FAF +} + +div.highlight .-Color[class*=-BGC97] { + background-color: #875FAF +} + +div.highlight .-Color[class*=-C98] { + color: #875FD7 +} + +div.highlight .-Color[class*=-BGC98] { + background-color: #875FD7 +} + +div.highlight .-Color[class*=-C99] { + color: #875FFF +} + +div.highlight .-Color[class*=-BGC99] { + background-color: #875FFF +} + +div.highlight .-Color[class*=-C100] { + color: #878700 +} + +div.highlight .-Color[class*=-BGC100] { + background-color: #878700 +} + +div.highlight .-Color[class*=-C101] { + color: #87875F +} + +div.highlight .-Color[class*=-BGC101] { + background-color: #87875F +} + +div.highlight .-Color[class*=-C102] { + color: #878787 +} + +div.highlight .-Color[class*=-BGC102] { + background-color: #878787 +} + +div.highlight .-Color[class*=-C103] { + color: #8787AF +} + +div.highlight .-Color[class*=-BGC103] { + background-color: #8787AF +} + +div.highlight .-Color[class*=-C104] { + color: #8787D7 +} + +div.highlight .-Color[class*=-BGC104] { + background-color: #8787D7 +} + +div.highlight .-Color[class*=-C105] { + color: #8787FF +} + +div.highlight .-Color[class*=-BGC105] { + background-color: #8787FF +} + +div.highlight .-Color[class*=-C106] { + color: #87AF00 +} + +div.highlight .-Color[class*=-BGC106] { + background-color: #87AF00 +} + +div.highlight .-Color[class*=-C107] { + color: #87AF5F +} + +div.highlight .-Color[class*=-BGC107] { + background-color: #87AF5F +} + +div.highlight .-Color[class*=-C108] { + color: #87AF87 +} + +div.highlight .-Color[class*=-BGC108] { + background-color: #87AF87 +} + +div.highlight .-Color[class*=-C109] { + color: #87AFAF +} + +div.highlight .-Color[class*=-BGC109] { + background-color: #87AFAF +} + +div.highlight .-Color[class*=-C110] { + color: #87AFD7 +} + +div.highlight .-Color[class*=-BGC110] { + background-color: #87AFD7 +} + +div.highlight .-Color[class*=-C111] { + color: #87AFFF +} + +div.highlight .-Color[class*=-BGC111] { + background-color: #87AFFF +} + +div.highlight .-Color[class*=-C112] { + color: #87D700 +} + +div.highlight .-Color[class*=-BGC112] { + background-color: #87D700 +} + +div.highlight .-Color[class*=-C113] { + color: #87D75F +} + +div.highlight .-Color[class*=-BGC113] { + background-color: #87D75F +} + +div.highlight .-Color[class*=-C114] { + color: #87D787 +} + +div.highlight .-Color[class*=-BGC114] { + background-color: #87D787 +} + +div.highlight .-Color[class*=-C115] { + color: #87D7AF +} + +div.highlight .-Color[class*=-BGC115] { + background-color: #87D7AF +} + +div.highlight .-Color[class*=-C116] { + color: #87D7D7 +} + +div.highlight .-Color[class*=-BGC116] { + background-color: #87D7D7 +} + +div.highlight .-Color[class*=-C117] { + color: #87D7FF +} + +div.highlight .-Color[class*=-BGC117] { + background-color: #87D7FF +} + +div.highlight .-Color[class*=-C118] { + color: #87FF00 +} + +div.highlight .-Color[class*=-BGC118] { + background-color: #87FF00 +} + +div.highlight .-Color[class*=-C119] { + color: #87FF5F +} + +div.highlight .-Color[class*=-BGC119] { + background-color: #87FF5F +} + +div.highlight .-Color[class*=-C120] { + color: #87FF87 +} + +div.highlight .-Color[class*=-BGC120] { + background-color: #87FF87 +} + +div.highlight .-Color[class*=-C121] { + color: #87FFAF +} + +div.highlight .-Color[class*=-BGC121] { + background-color: #87FFAF +} + +div.highlight .-Color[class*=-C122] { + color: #87FFD7 +} + +div.highlight .-Color[class*=-BGC122] { + background-color: #87FFD7 +} + +div.highlight .-Color[class*=-C123] { + color: #87FFFF +} + +div.highlight .-Color[class*=-BGC123] { + background-color: #87FFFF +} + +div.highlight .-Color[class*=-C124] { + color: #AF0000 +} + +div.highlight .-Color[class*=-BGC124] { + background-color: #AF0000 +} + +div.highlight .-Color[class*=-C125] { + color: #AF005F +} + +div.highlight .-Color[class*=-BGC125] { + background-color: #AF005F +} + +div.highlight .-Color[class*=-C126] { + color: #AF0087 +} + +div.highlight .-Color[class*=-BGC126] { + background-color: #AF0087 +} + +div.highlight .-Color[class*=-C127] { + color: #AF00AF +} + +div.highlight .-Color[class*=-BGC127] { + background-color: #AF00AF +} + +div.highlight .-Color[class*=-C128] { + color: #AF00D7 +} + +div.highlight .-Color[class*=-BGC128] { + background-color: #AF00D7 +} + +div.highlight .-Color[class*=-C129] { + color: #AF00FF +} + +div.highlight .-Color[class*=-BGC129] { + background-color: #AF00FF +} + +div.highlight .-Color[class*=-C130] { + color: #AF5F00 +} + +div.highlight .-Color[class*=-BGC130] { + background-color: #AF5F00 +} + +div.highlight .-Color[class*=-C131] { + color: #AF5F5F +} + +div.highlight .-Color[class*=-BGC131] { + background-color: #AF5F5F +} + +div.highlight .-Color[class*=-C132] { + color: #AF5F87 +} + +div.highlight .-Color[class*=-BGC132] { + background-color: #AF5F87 +} + +div.highlight .-Color[class*=-C133] { + color: #AF5FAF +} + +div.highlight .-Color[class*=-BGC133] { + background-color: #AF5FAF +} + +div.highlight .-Color[class*=-C134] { + color: #AF5FD7 +} + +div.highlight .-Color[class*=-BGC134] { + background-color: #AF5FD7 +} + +div.highlight .-Color[class*=-C135] { + color: #AF5FFF +} + +div.highlight .-Color[class*=-BGC135] { + background-color: #AF5FFF +} + +div.highlight .-Color[class*=-C136] { + color: #AF8700 +} + +div.highlight .-Color[class*=-BGC136] { + background-color: #AF8700 +} + +div.highlight .-Color[class*=-C137] { + color: #AF875F +} + +div.highlight .-Color[class*=-BGC137] { + background-color: #AF875F +} + +div.highlight .-Color[class*=-C138] { + color: #AF8787 +} + +div.highlight .-Color[class*=-BGC138] { + background-color: #AF8787 +} + +div.highlight .-Color[class*=-C139] { + color: #AF87AF +} + +div.highlight .-Color[class*=-BGC139] { + background-color: #AF87AF +} + +div.highlight .-Color[class*=-C140] { + color: #AF87D7 +} + +div.highlight .-Color[class*=-BGC140] { + background-color: #AF87D7 +} + +div.highlight .-Color[class*=-C141] { + color: #AF87FF +} + +div.highlight .-Color[class*=-BGC141] { + background-color: #AF87FF +} + +div.highlight .-Color[class*=-C142] { + color: #AFAF00 +} + +div.highlight .-Color[class*=-BGC142] { + background-color: #AFAF00 +} + +div.highlight .-Color[class*=-C143] { + color: #AFAF5F +} + +div.highlight .-Color[class*=-BGC143] { + background-color: #AFAF5F +} + +div.highlight .-Color[class*=-C144] { + color: #AFAF87 +} + +div.highlight .-Color[class*=-BGC144] { + background-color: #AFAF87 +} + +div.highlight .-Color[class*=-C145] { + color: #AFAFAF +} + +div.highlight .-Color[class*=-BGC145] { + background-color: #AFAFAF +} + +div.highlight .-Color[class*=-C146] { + color: #AFAFD7 +} + +div.highlight .-Color[class*=-BGC146] { + background-color: #AFAFD7 +} + +div.highlight .-Color[class*=-C147] { + color: #AFAFFF +} + +div.highlight .-Color[class*=-BGC147] { + background-color: #AFAFFF +} + +div.highlight .-Color[class*=-C148] { + color: #AFD700 +} + +div.highlight .-Color[class*=-BGC148] { + background-color: #AFD700 +} + +div.highlight .-Color[class*=-C149] { + color: #AFD75F +} + +div.highlight .-Color[class*=-BGC149] { + background-color: #AFD75F +} + +div.highlight .-Color[class*=-C150] { + color: #AFD787 +} + +div.highlight .-Color[class*=-BGC150] { + background-color: #AFD787 +} + +div.highlight .-Color[class*=-C151] { + color: #AFD7AF +} + +div.highlight .-Color[class*=-BGC151] { + background-color: #AFD7AF +} + +div.highlight .-Color[class*=-C152] { + color: #AFD7D7 +} + +div.highlight .-Color[class*=-BGC152] { + background-color: #AFD7D7 +} + +div.highlight .-Color[class*=-C153] { + color: #AFD7FF +} + +div.highlight .-Color[class*=-BGC153] { + background-color: #AFD7FF +} + +div.highlight .-Color[class*=-C154] { + color: #AFFF00 +} + +div.highlight .-Color[class*=-BGC154] { + background-color: #AFFF00 +} + +div.highlight .-Color[class*=-C155] { + color: #AFFF5F +} + +div.highlight .-Color[class*=-BGC155] { + background-color: #AFFF5F +} + +div.highlight .-Color[class*=-C156] { + color: #AFFF87 +} + +div.highlight .-Color[class*=-BGC156] { + background-color: #AFFF87 +} + +div.highlight .-Color[class*=-C157] { + color: #AFFFAF +} + +div.highlight .-Color[class*=-BGC157] { + background-color: #AFFFAF +} + +div.highlight .-Color[class*=-C158] { + color: #AFFFD7 +} + +div.highlight .-Color[class*=-BGC158] { + background-color: #AFFFD7 +} + +div.highlight .-Color[class*=-C159] { + color: #AFFFFF +} + +div.highlight .-Color[class*=-BGC159] { + background-color: #AFFFFF +} + +div.highlight .-Color[class*=-C160] { + color: #D70000 +} + +div.highlight .-Color[class*=-BGC160] { + background-color: #D70000 +} + +div.highlight .-Color[class*=-C161] { + color: #D7005F +} + +div.highlight .-Color[class*=-BGC161] { + background-color: #D7005F +} + +div.highlight .-Color[class*=-C162] { + color: #D70087 +} + +div.highlight .-Color[class*=-BGC162] { + background-color: #D70087 +} + +div.highlight .-Color[class*=-C163] { + color: #D700AF +} + +div.highlight .-Color[class*=-BGC163] { + background-color: #D700AF +} + +div.highlight .-Color[class*=-C164] { + color: #D700D7 +} + +div.highlight .-Color[class*=-BGC164] { + background-color: #D700D7 +} + +div.highlight .-Color[class*=-C165] { + color: #D700FF +} + +div.highlight .-Color[class*=-BGC165] { + background-color: #D700FF +} + +div.highlight .-Color[class*=-C166] { + color: #D75F00 +} + +div.highlight .-Color[class*=-BGC166] { + background-color: #D75F00 +} + +div.highlight .-Color[class*=-C167] { + color: #D75F5F +} + +div.highlight .-Color[class*=-BGC167] { + background-color: #D75F5F +} + +div.highlight .-Color[class*=-C168] { + color: #D75F87 +} + +div.highlight .-Color[class*=-BGC168] { + background-color: #D75F87 +} + +div.highlight .-Color[class*=-C169] { + color: #D75FAF +} + +div.highlight .-Color[class*=-BGC169] { + background-color: #D75FAF +} + +div.highlight .-Color[class*=-C170] { + color: #D75FD7 +} + +div.highlight .-Color[class*=-BGC170] { + background-color: #D75FD7 +} + +div.highlight .-Color[class*=-C171] { + color: #D75FFF +} + +div.highlight .-Color[class*=-BGC171] { + background-color: #D75FFF +} + +div.highlight .-Color[class*=-C172] { + color: #D78700 +} + +div.highlight .-Color[class*=-BGC172] { + background-color: #D78700 +} + +div.highlight .-Color[class*=-C173] { + color: #D7875F +} + +div.highlight .-Color[class*=-BGC173] { + background-color: #D7875F +} + +div.highlight .-Color[class*=-C174] { + color: #D78787 +} + +div.highlight .-Color[class*=-BGC174] { + background-color: #D78787 +} + +div.highlight .-Color[class*=-C175] { + color: #D787AF +} + +div.highlight .-Color[class*=-BGC175] { + background-color: #D787AF +} + +div.highlight .-Color[class*=-C176] { + color: #D787D7 +} + +div.highlight .-Color[class*=-BGC176] { + background-color: #D787D7 +} + +div.highlight .-Color[class*=-C177] { + color: #D787FF +} + +div.highlight .-Color[class*=-BGC177] { + background-color: #D787FF +} + +div.highlight .-Color[class*=-C178] { + color: #D7AF00 +} + +div.highlight .-Color[class*=-BGC178] { + background-color: #D7AF00 +} + +div.highlight .-Color[class*=-C179] { + color: #D7AF5F +} + +div.highlight .-Color[class*=-BGC179] { + background-color: #D7AF5F +} + +div.highlight .-Color[class*=-C180] { + color: #D7AF87 +} + +div.highlight .-Color[class*=-BGC180] { + background-color: #D7AF87 +} + +div.highlight .-Color[class*=-C181] { + color: #D7AFAF +} + +div.highlight .-Color[class*=-BGC181] { + background-color: #D7AFAF +} + +div.highlight .-Color[class*=-C182] { + color: #D7AFD7 +} + +div.highlight .-Color[class*=-BGC182] { + background-color: #D7AFD7 +} + +div.highlight .-Color[class*=-C183] { + color: #D7AFFF +} + +div.highlight .-Color[class*=-BGC183] { + background-color: #D7AFFF +} + +div.highlight .-Color[class*=-C184] { + color: #D7D700 +} + +div.highlight .-Color[class*=-BGC184] { + background-color: #D7D700 +} + +div.highlight .-Color[class*=-C185] { + color: #D7D75F +} + +div.highlight .-Color[class*=-BGC185] { + background-color: #D7D75F +} + +div.highlight .-Color[class*=-C186] { + color: #D7D787 +} + +div.highlight .-Color[class*=-BGC186] { + background-color: #D7D787 +} + +div.highlight .-Color[class*=-C187] { + color: #D7D7AF +} + +div.highlight .-Color[class*=-BGC187] { + background-color: #D7D7AF +} + +div.highlight .-Color[class*=-C188] { + color: #D7D7D7 +} + +div.highlight .-Color[class*=-BGC188] { + background-color: #D7D7D7 +} + +div.highlight .-Color[class*=-C189] { + color: #D7D7FF +} + +div.highlight .-Color[class*=-BGC189] { + background-color: #D7D7FF +} + +div.highlight .-Color[class*=-C190] { + color: #D7FF00 +} + +div.highlight .-Color[class*=-BGC190] { + background-color: #D7FF00 +} + +div.highlight .-Color[class*=-C191] { + color: #D7FF5F +} + +div.highlight .-Color[class*=-BGC191] { + background-color: #D7FF5F +} + +div.highlight .-Color[class*=-C192] { + color: #D7FF87 +} + +div.highlight .-Color[class*=-BGC192] { + background-color: #D7FF87 +} + +div.highlight .-Color[class*=-C193] { + color: #D7FFAF +} + +div.highlight .-Color[class*=-BGC193] { + background-color: #D7FFAF +} + +div.highlight .-Color[class*=-C194] { + color: #D7FFD7 +} + +div.highlight .-Color[class*=-BGC194] { + background-color: #D7FFD7 +} + +div.highlight .-Color[class*=-C195] { + color: #D7FFFF +} + +div.highlight .-Color[class*=-BGC195] { + background-color: #D7FFFF +} + +div.highlight .-Color[class*=-C196] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC196] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C197] { + color: #FF005F +} + +div.highlight .-Color[class*=-BGC197] { + background-color: #FF005F +} + +div.highlight .-Color[class*=-C198] { + color: #FF0087 +} + +div.highlight .-Color[class*=-BGC198] { + background-color: #FF0087 +} + +div.highlight .-Color[class*=-C199] { + color: #FF00AF +} + +div.highlight .-Color[class*=-BGC199] { + background-color: #FF00AF +} + +div.highlight .-Color[class*=-C200] { + color: #FF00D7 +} + +div.highlight .-Color[class*=-BGC200] { + background-color: #FF00D7 +} + +div.highlight .-Color[class*=-C201] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC201] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C202] { + color: #FF5F00 +} + +div.highlight .-Color[class*=-BGC202] { + background-color: #FF5F00 +} + +div.highlight .-Color[class*=-C203] { + color: #FF5F5F +} + +div.highlight .-Color[class*=-BGC203] { + background-color: #FF5F5F +} + +div.highlight .-Color[class*=-C204] { + color: #FF5F87 +} + +div.highlight .-Color[class*=-BGC204] { + background-color: #FF5F87 +} + +div.highlight .-Color[class*=-C205] { + color: #FF5FAF +} + +div.highlight .-Color[class*=-BGC205] { + background-color: #FF5FAF +} + +div.highlight .-Color[class*=-C206] { + color: #FF5FD7 +} + +div.highlight .-Color[class*=-BGC206] { + background-color: #FF5FD7 +} + +div.highlight .-Color[class*=-C207] { + color: #FF5FFF +} + +div.highlight .-Color[class*=-BGC207] { + background-color: #FF5FFF +} + +div.highlight .-Color[class*=-C208] { + color: #FF8700 +} + +div.highlight .-Color[class*=-BGC208] { + background-color: #FF8700 +} + +div.highlight .-Color[class*=-C209] { + color: #FF875F +} + +div.highlight .-Color[class*=-BGC209] { + background-color: #FF875F +} + +div.highlight .-Color[class*=-C210] { + color: #FF8787 +} + +div.highlight .-Color[class*=-BGC210] { + background-color: #FF8787 +} + +div.highlight .-Color[class*=-C211] { + color: #FF87AF +} + +div.highlight .-Color[class*=-BGC211] { + background-color: #FF87AF +} + +div.highlight .-Color[class*=-C212] { + color: #FF87D7 +} + +div.highlight .-Color[class*=-BGC212] { + background-color: #FF87D7 +} + +div.highlight .-Color[class*=-C213] { + color: #FF87FF +} + +div.highlight .-Color[class*=-BGC213] { + background-color: #FF87FF +} + +div.highlight .-Color[class*=-C214] { + color: #FFAF00 +} + +div.highlight .-Color[class*=-BGC214] { + background-color: #FFAF00 +} + +div.highlight .-Color[class*=-C215] { + color: #FFAF5F +} + +div.highlight .-Color[class*=-BGC215] { + background-color: #FFAF5F +} + +div.highlight .-Color[class*=-C216] { + color: #FFAF87 +} + +div.highlight .-Color[class*=-BGC216] { + background-color: #FFAF87 +} + +div.highlight .-Color[class*=-C217] { + color: #FFAFAF +} + +div.highlight .-Color[class*=-BGC217] { + background-color: #FFAFAF +} + +div.highlight .-Color[class*=-C218] { + color: #FFAFD7 +} + +div.highlight .-Color[class*=-BGC218] { + background-color: #FFAFD7 +} + +div.highlight .-Color[class*=-C219] { + color: #FFAFFF +} + +div.highlight .-Color[class*=-BGC219] { + background-color: #FFAFFF +} + +div.highlight .-Color[class*=-C220] { + color: #FFD700 +} + +div.highlight .-Color[class*=-BGC220] { + background-color: #FFD700 +} + +div.highlight .-Color[class*=-C221] { + color: #FFD75F +} + +div.highlight .-Color[class*=-BGC221] { + background-color: #FFD75F +} + +div.highlight .-Color[class*=-C222] { + color: #FFD787 +} + +div.highlight .-Color[class*=-BGC222] { + background-color: #FFD787 +} + +div.highlight .-Color[class*=-C223] { + color: #FFD7AF +} + +div.highlight .-Color[class*=-BGC223] { + background-color: #FFD7AF +} + +div.highlight .-Color[class*=-C224] { + color: #FFD7D7 +} + +div.highlight .-Color[class*=-BGC224] { + background-color: #FFD7D7 +} + +div.highlight .-Color[class*=-C225] { + color: #FFD7FF +} + +div.highlight .-Color[class*=-BGC225] { + background-color: #FFD7FF +} + +div.highlight .-Color[class*=-C226] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC226] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C227] { + color: #FFFF5F +} + +div.highlight .-Color[class*=-BGC227] { + background-color: #FFFF5F +} + +div.highlight .-Color[class*=-C228] { + color: #FFFF87 +} + +div.highlight .-Color[class*=-BGC228] { + background-color: #FFFF87 +} + +div.highlight .-Color[class*=-C229] { + color: #FFFFAF +} + +div.highlight .-Color[class*=-BGC229] { + background-color: #FFFFAF +} + +div.highlight .-Color[class*=-C230] { + color: #FFFFD7 +} + +div.highlight .-Color[class*=-BGC230] { + background-color: #FFFFD7 +} + +div.highlight .-Color[class*=-C231] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC231] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C232] { + color: #080808 +} + +div.highlight .-Color[class*=-BGC232] { + background-color: #080808 +} + +div.highlight .-Color[class*=-C233] { + color: #121212 +} + +div.highlight .-Color[class*=-BGC233] { + background-color: #121212 +} + +div.highlight .-Color[class*=-C234] { + color: #1C1C1C +} + +div.highlight .-Color[class*=-BGC234] { + background-color: #1C1C1C +} + +div.highlight .-Color[class*=-C235] { + color: #262626 +} + +div.highlight .-Color[class*=-BGC235] { + background-color: #262626 +} + +div.highlight .-Color[class*=-C236] { + color: #303030 +} + +div.highlight .-Color[class*=-BGC236] { + background-color: #303030 +} + +div.highlight .-Color[class*=-C237] { + color: #3A3A3A +} + +div.highlight .-Color[class*=-BGC237] { + background-color: #3A3A3A +} + +div.highlight .-Color[class*=-C238] { + color: #444444 +} + +div.highlight .-Color[class*=-BGC238] { + background-color: #444444 +} + +div.highlight .-Color[class*=-C239] { + color: #4E4E4E +} + +div.highlight .-Color[class*=-BGC239] { + background-color: #4E4E4E +} + +div.highlight .-Color[class*=-C240] { + color: #585858 +} + +div.highlight .-Color[class*=-BGC240] { + background-color: #585858 +} + +div.highlight .-Color[class*=-C241] { + color: #626262 +} + +div.highlight .-Color[class*=-BGC241] { + background-color: #626262 +} + +div.highlight .-Color[class*=-C242] { + color: #6C6C6C +} + +div.highlight .-Color[class*=-BGC242] { + background-color: #6C6C6C +} + +div.highlight .-Color[class*=-C243] { + color: #767676 +} + +div.highlight .-Color[class*=-BGC243] { + background-color: #767676 +} + +div.highlight .-Color[class*=-C244] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC244] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C245] { + color: #8A8A8A +} + +div.highlight .-Color[class*=-BGC245] { + background-color: #8A8A8A +} + +div.highlight .-Color[class*=-C246] { + color: #949494 +} + +div.highlight .-Color[class*=-BGC246] { + background-color: #949494 +} + +div.highlight .-Color[class*=-C247] { + color: #9E9E9E +} + +div.highlight .-Color[class*=-BGC247] { + background-color: #9E9E9E +} + +div.highlight .-Color[class*=-C248] { + color: #A8A8A8 +} + +div.highlight .-Color[class*=-BGC248] { + background-color: #A8A8A8 +} + +div.highlight .-Color[class*=-C249] { + color: #B2B2B2 +} + +div.highlight .-Color[class*=-BGC249] { + background-color: #B2B2B2 +} + +div.highlight .-Color[class*=-C250] { + color: #BCBCBC +} + +div.highlight .-Color[class*=-BGC250] { + background-color: #BCBCBC +} + +div.highlight .-Color[class*=-C251] { + color: #C6C6C6 +} + +div.highlight .-Color[class*=-BGC251] { + background-color: #C6C6C6 +} + +div.highlight .-Color[class*=-C252] { + color: #D0D0D0 +} + +div.highlight .-Color[class*=-BGC252] { + background-color: #D0D0D0 +} + +div.highlight .-Color[class*=-C253] { + color: #DADADA +} + +div.highlight .-Color[class*=-BGC253] { + background-color: #DADADA +} + +div.highlight .-Color[class*=-C254] { + color: #E4E4E4 +} + +div.highlight .-Color[class*=-BGC254] { + background-color: #E4E4E4 +} + +div.highlight .-Color[class*=-C255] { + color: #EEEEEE +} + +div.highlight .-Color[class*=-BGC255] { + background-color: #EEEEEE +} diff --git a/branch/comms/_static/plus.png b/branch/comms/_static/plus.png new file mode 100644 index 0000000..7107cec Binary files /dev/null and b/branch/comms/_static/plus.png differ diff --git a/branch/comms/_static/pygments.css b/branch/comms/_static/pygments.css new file mode 100644 index 0000000..84ab303 --- /dev/null +++ b/branch/comms/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/branch/comms/_static/searchtools.js b/branch/comms/_static/searchtools.js new file mode 100644 index 0000000..b08d58c --- /dev/null +++ b/branch/comms/_static/searchtools.js @@ -0,0 +1,620 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/branch/comms/_static/sphinx-design.min.css b/branch/comms/_static/sphinx-design.min.css new file mode 100644 index 0000000..860c36d --- /dev/null +++ b/branch/comms/_static/sphinx-design.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative;font-size:var(--sd-fontsize-dropdown)}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary.sd-summary-title{padding:.5em .6em .5em 1em;font-size:var(--sd-fontsize-dropdown-title);font-weight:var(--sd-fontweight-dropdown-title);user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;list-style:none;display:inline-flex;justify-content:space-between}details.sd-dropdown summary.sd-summary-title::-webkit-details-marker{display:none}details.sd-dropdown summary.sd-summary-title:focus{outline:none}details.sd-dropdown summary.sd-summary-title .sd-summary-icon{margin-right:.6em;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary.sd-summary-title .sd-summary-text{flex-grow:1;line-height:1.5;padding-right:.5rem}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker{pointer-events:none;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker svg{opacity:.6}details.sd-dropdown summary.sd-summary-title:hover .sd-summary-state-marker svg{opacity:1;transform:scale(1.1)}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown .sd-summary-chevron-right{transition:.25s}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-right{transform:rotate(90deg)}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-down{transform:rotate(180deg)}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-bg: rgba(0, 113, 188, 0.2);--sd-color-secondary-bg: rgba(108, 117, 125, 0.2);--sd-color-success-bg: rgba(40, 167, 69, 0.2);--sd-color-info-bg: rgba(23, 162, 184, 0.2);--sd-color-warning-bg: rgba(240, 179, 126, 0.2);--sd-color-danger-bg: rgba(220, 53, 69, 0.2);--sd-color-light-bg: rgba(248, 249, 250, 0.2);--sd-color-muted-bg: rgba(108, 117, 125, 0.2);--sd-color-dark-bg: rgba(33, 37, 41, 0.2);--sd-color-black-bg: rgba(0, 0, 0, 0.2);--sd-color-white-bg: rgba(255, 255, 255, 0.2);--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem;--sd-fontsize-dropdown: inherit;--sd-fontsize-dropdown-title: 1rem;--sd-fontweight-dropdown-title: 700} diff --git a/branch/comms/_static/sphinx_highlight.js b/branch/comms/_static/sphinx_highlight.js new file mode 100644 index 0000000..8a96c69 --- /dev/null +++ b/branch/comms/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/branch/comms/_static/sphinx_lesson.css b/branch/comms/_static/sphinx_lesson.css new file mode 100644 index 0000000..14b20c6 --- /dev/null +++ b/branch/comms/_static/sphinx_lesson.css @@ -0,0 +1,51 @@ +/* sphinx_lesson.css */ + +body.wy-body-for-nav img.with-border { + border: 2px solid; +} + +.rst-content .admonition-no-content { + padding-bottom: 0px; +} + +.rst-content .demo > .admonition-title::before { + content: "\01F440"; /* Eyes */ } +.rst-content .type-along > .admonition-title::before { + content: "\02328\0FE0F"; /* Keyboard */ } +.rst-content .exercise > .admonition-title::before { + content: "\0270D\0FE0F"; /* Hand */ } +.rst-content .solution > .admonition-title::before { + content: "\02714\0FE0E"; /* Check mark */ } +.rst-content .homework > .admonition-title::before { + content: "\01F4DD"; /* Memo */ } +.rst-content .discussion > .admonition-title::before { + content: "\01F4AC"; /* Speech balloon */ } +.rst-content .questions > .admonition-title::before { + content: "\02753\0FE0E"; /* Question mark */ } +.rst-content .prerequisites > .admonition-title::before { + content: "\02699"; /* Gear */ } +.rst-content .seealso > .admonition-title::before { + content: "\027A1\0FE0E"; /* Question mark */ } + + +/* instructor-note */ +.rst-content .instructor-note { + background: #e7e7e7; +} +.rst-content .instructor-note > .admonition-title { + background: #6a6a6a; +} +.rst-content .instructor-note > .admonition-title::before { + content: ""; +} + + +/* sphinx_toggle_button, make the font white */ +.rst-content .toggle.admonition button.toggle-button { + color: white; +} + +/* sphinx-togglebutton, remove underflow when toggled to hidden mode */ +.rst-content .admonition.toggle-hidden { + padding-bottom: 0px; +} diff --git a/branch/comms/_static/sphinx_rtd_theme_ext_color_contrast.css b/branch/comms/_static/sphinx_rtd_theme_ext_color_contrast.css new file mode 100644 index 0000000..e68feb8 --- /dev/null +++ b/branch/comms/_static/sphinx_rtd_theme_ext_color_contrast.css @@ -0,0 +1,47 @@ +/* The following are for web accessibility of sphinx_rtd_theme: they + * solve some of the most frequent contrast issues. Remove when this + * solved: + * https://github.com/readthedocs/sphinx_rtd_theme/issues/971 + */ +/* background: #fcfcfc, note boxes #E7F2FA */ +a { color: #2573A7; } /* original #2980B9, #1F5C84; */ +body { color: #242424; } /* original #404040, #383838 */ +.wy-side-nav-search>a, .wy-side-nav-search .wy-dropdown>a { + color: #ffffff; +} /* original #fcfcfc */ +footer { color: #737373; } /* original gray=#808080*/ +footer span.commit code, footer span.commit .rst-content tt, .rst-content footer span.commit tt { + color: #737373; +} /* original gray=#808080*/ +.rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal { + color: #AB2314; +} +/* Sidebar background */ +.wy-side-nav-search { background-color: #277CB4;} + +/* Same, but for pygments */ +.highlight .ch { color: #3E7A89; } /* #! line */ +.highlight .c1 { color: #3E7A89; } /* also comments */ +.highlight .nv { color: #AD3ECC; } /* variable */ +.highlight .gp { color: #B45608; } /* prompt character, $*/ +.highlight .si { color: #3975B1; } /* ${} variable text */ +.highlight .nc { color: #0C78A7; } + +/* Sphinx admonitions */ +/* warning */ +.wy-alert.wy-alert-warning .wy-alert-title, .rst-content .wy-alert-warning.note .wy-alert-title, .rst-content .attention .wy-alert-title, .rst-content .caution .wy-alert-title, .rst-content .wy-alert-warning.danger .wy-alert-title, .rst-content .wy-alert-warning.error .wy-alert-title, .rst-content .wy-alert-warning.hint .wy-alert-title, .rst-content .wy-alert-warning.important .wy-alert-title, .rst-content .wy-alert-warning.tip .wy-alert-title, .rst-content .warning .wy-alert-title, .rst-content .wy-alert-warning.seealso .wy-alert-title, .rst-content .admonition-todo .wy-alert-title, .rst-content .wy-alert-warning.admonition .wy-alert-title, .wy-alert.wy-alert-warning .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-warning .admonition-title, .rst-content .wy-alert-warning.note .admonition-title, .rst-content .attention .admonition-title, .rst-content .caution .admonition-title, .rst-content .wy-alert-warning.danger .admonition-title, .rst-content .wy-alert-warning.error .admonition-title, .rst-content .wy-alert-warning.hint .admonition-title, .rst-content .wy-alert-warning.important .admonition-title, .rst-content .wy-alert-warning.tip .admonition-title, .rst-content .warning .admonition-title, .rst-content .wy-alert-warning.seealso .admonition-title, .rst-content .admonition-todo .admonition-title, .rst-content .wy-alert-warning.admonition .admonition-title { + background: #B15E16; } +/* important */ +.wy-alert.wy-alert-success .wy-alert-title, .rst-content .wy-alert-success.note .wy-alert-title, .rst-content .wy-alert-success.attention .wy-alert-title, .rst-content .wy-alert-success.caution .wy-alert-title, .rst-content .wy-alert-success.danger .wy-alert-title, .rst-content .wy-alert-success.error .wy-alert-title, .rst-content .hint .wy-alert-title, .rst-content .important .wy-alert-title, .rst-content .tip .wy-alert-title, .rst-content .wy-alert-success.warning .wy-alert-title, .rst-content .wy-alert-success.seealso .wy-alert-title, .rst-content .wy-alert-success.admonition-todo .wy-alert-title, .rst-content .wy-alert-success.admonition .wy-alert-title, .wy-alert.wy-alert-success .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-success .admonition-title, .rst-content .wy-alert-success.note .admonition-title, .rst-content .wy-alert-success.attention .admonition-title, .rst-content .wy-alert-success.caution .admonition-title, .rst-content .wy-alert-success.danger .admonition-title, .rst-content .wy-alert-success.error .admonition-title, .rst-content .hint .admonition-title, .rst-content .important .admonition-title, .rst-content .tip .admonition-title, .rst-content .wy-alert-success.warning .admonition-title, .rst-content .wy-alert-success.seealso .admonition-title, .rst-content .wy-alert-success.admonition-todo .admonition-title, .rst-content .wy-alert-success.admonition .admonition-title { + background: #12826C; } +/* seealso, note, etc */ +.wy-alert.wy-alert-info .wy-alert-title, .rst-content .note .wy-alert-title, .rst-content .wy-alert-info.attention .wy-alert-title, .rst-content .wy-alert-info.caution .wy-alert-title, .rst-content .wy-alert-info.danger .wy-alert-title, .rst-content .wy-alert-info.error .wy-alert-title, .rst-content .wy-alert-info.hint .wy-alert-title, .rst-content .wy-alert-info.important .wy-alert-title, .rst-content .wy-alert-info.tip .wy-alert-title, .rst-content .wy-alert-info.warning .wy-alert-title, .rst-content .seealso .wy-alert-title, .rst-content .wy-alert-info.admonition-todo .wy-alert-title, .rst-content .wy-alert-info.admonition .wy-alert-title, .wy-alert.wy-alert-info .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-info .admonition-title, .rst-content .note .admonition-title, .rst-content .wy-alert-info.attention .admonition-title, .rst-content .wy-alert-info.caution .admonition-title, .rst-content .wy-alert-info.danger .admonition-title, .rst-content .wy-alert-info.error .admonition-title, .rst-content .wy-alert-info.hint .admonition-title, .rst-content .wy-alert-info.important .admonition-title, .rst-content .wy-alert-info.tip .admonition-title, .rst-content .wy-alert-info.warning .admonition-title, .rst-content .seealso .admonition-title, .rst-content .wy-alert-info.admonition-todo .admonition-title, .rst-content .wy-alert-info.admonition .admonition-title { + background: #277CB4; } +/* error, danger */ +.rst-content .danger .admonition-title, .rst-content .danger .wy-alert-title, .rst-content .error .admonition-title, .rst-content .error .wy-alert-title, .rst-content .wy-alert-danger.admonition-todo .admonition-title, .rst-content .wy-alert-danger.admonition-todo .wy-alert-title, .rst-content .wy-alert-danger.admonition .admonition-title, .rst-content .wy-alert-danger.admonition .wy-alert-title, .rst-content .wy-alert-danger.attention .admonition-title, .rst-content .wy-alert-danger.attention .wy-alert-title, .rst-content .wy-alert-danger.caution .admonition-title, .rst-content .wy-alert-danger.caution .wy-alert-title, .rst-content .wy-alert-danger.hint .admonition-title, .rst-content .wy-alert-danger.hint .wy-alert-title, .rst-content .wy-alert-danger.important .admonition-title, .rst-content .wy-alert-danger.important .wy-alert-title, .rst-content .wy-alert-danger.note .admonition-title, .rst-content .wy-alert-danger.note .wy-alert-title, .rst-content .wy-alert-danger.seealso .admonition-title, .rst-content .wy-alert-danger.seealso .wy-alert-title, .rst-content .wy-alert-danger.tip .admonition-title, .rst-content .wy-alert-danger.tip .wy-alert-title, .rst-content .wy-alert-danger.warning .admonition-title, .rst-content .wy-alert-danger.warning .wy-alert-title, .rst-content .wy-alert.wy-alert-danger .admonition-title, .wy-alert.wy-alert-danger .rst-content .admonition-title, .wy-alert.wy-alert-danger .wy-alert-title { + background: #e31704; +} + +/* Generic admonition titles */ +.wy-alert-title, .rst-content .admonition-title { + background: #277CB4; } diff --git a/branch/comms/_static/tabs.css b/branch/comms/_static/tabs.css new file mode 100644 index 0000000..957ba60 --- /dev/null +++ b/branch/comms/_static/tabs.css @@ -0,0 +1,89 @@ +.sphinx-tabs { + margin-bottom: 1rem; +} + +[role="tablist"] { + border-bottom: 1px solid #a0b3bf; +} + +.sphinx-tabs-tab { + position: relative; + font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; + color: #1D5C87; + line-height: 24px; + margin: 0; + font-size: 16px; + font-weight: 400; + background-color: rgba(255, 255, 255, 0); + border-radius: 5px 5px 0 0; + border: 0; + padding: 1rem 1.5rem; + margin-bottom: 0; +} + +.sphinx-tabs-tab[aria-selected="true"] { + font-weight: 700; + border: 1px solid #a0b3bf; + border-bottom: 1px solid white; + margin: -1px; + background-color: white; +} + +.sphinx-tabs-tab:focus { + z-index: 1; + outline-offset: 1px; +} + +.sphinx-tabs-panel { + position: relative; + padding: 1rem; + border: 1px solid #a0b3bf; + margin: 0px -1px -1px -1px; + border-radius: 0 0 5px 5px; + border-top: 0; + background: white; +} + +.sphinx-tabs-panel.code-tab { + padding: 0.4rem; +} + +.sphinx-tab img { + margin-bottom: 24 px; +} + +/* Dark theme preference styling */ + +@media (prefers-color-scheme: dark) { + body[data-theme="auto"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); + } + + body[data-theme="auto"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); + } + + body[data-theme="auto"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 1px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); + } +} + +/* Explicit dark theme styling */ + +body[data-theme="dark"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); +} + +body[data-theme="dark"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); +} + +body[data-theme="dark"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 2px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); +} diff --git a/branch/comms/_static/tabs.js b/branch/comms/_static/tabs.js new file mode 100644 index 0000000..48dc303 --- /dev/null +++ b/branch/comms/_static/tabs.js @@ -0,0 +1,145 @@ +try { + var session = window.sessionStorage || {}; +} catch (e) { + var session = {}; +} + +window.addEventListener("DOMContentLoaded", () => { + const allTabs = document.querySelectorAll('.sphinx-tabs-tab'); + const tabLists = document.querySelectorAll('[role="tablist"]'); + + allTabs.forEach(tab => { + tab.addEventListener("click", changeTabs); + }); + + tabLists.forEach(tabList => { + tabList.addEventListener("keydown", keyTabs); + }); + + // Restore group tab selection from session + const lastSelected = session.getItem('sphinx-tabs-last-selected'); + if (lastSelected != null) selectNamedTabs(lastSelected); +}); + +/** + * Key focus left and right between sibling elements using arrows + * @param {Node} e the element in focus when key was pressed + */ +function keyTabs(e) { + const tab = e.target; + let nextTab = null; + if (e.keyCode === 39 || e.keyCode === 37) { + tab.setAttribute("tabindex", -1); + // Move right + if (e.keyCode === 39) { + nextTab = tab.nextElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.firstElementChild; + } + // Move left + } else if (e.keyCode === 37) { + nextTab = tab.previousElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.lastElementChild; + } + } + } + + if (nextTab !== null) { + nextTab.setAttribute("tabindex", 0); + nextTab.focus(); + } +} + +/** + * Select or deselect clicked tab. If a group tab + * is selected, also select tab in other tabLists. + * @param {Node} e the element that was clicked + */ +function changeTabs(e) { + // Use this instead of the element that was clicked, in case it's a child + const notSelected = this.getAttribute("aria-selected") === "false"; + const positionBefore = this.parentNode.getBoundingClientRect().top; + const notClosable = !this.parentNode.classList.contains("closeable"); + + deselectTabList(this); + + if (notSelected || notClosable) { + selectTab(this); + const name = this.getAttribute("name"); + selectNamedTabs(name, this.id); + + if (this.classList.contains("group-tab")) { + // Persist during session + session.setItem('sphinx-tabs-last-selected', name); + } + } + + const positionAfter = this.parentNode.getBoundingClientRect().top; + const positionDelta = positionAfter - positionBefore; + // Scroll to offset content resizing + window.scrollTo(0, window.scrollY + positionDelta); +} + +/** + * Select tab and show associated panel. + * @param {Node} tab tab to select + */ +function selectTab(tab) { + tab.setAttribute("aria-selected", true); + + // Show the associated panel + document + .getElementById(tab.getAttribute("aria-controls")) + .removeAttribute("hidden"); +} + +/** + * Hide the panels associated with all tabs within the + * tablist containing this tab. + * @param {Node} tab a tab within the tablist to deselect + */ +function deselectTabList(tab) { + const parent = tab.parentNode; + const grandparent = parent.parentNode; + + Array.from(parent.children) + .forEach(t => t.setAttribute("aria-selected", false)); + + Array.from(grandparent.children) + .slice(1) // Skip tablist + .forEach(panel => panel.setAttribute("hidden", true)); +} + +/** + * Select grouped tabs with the same name, but no the tab + * with the given id. + * @param {Node} name name of grouped tab to be selected + * @param {Node} clickedId id of clicked tab + */ +function selectNamedTabs(name, clickedId=null) { + const groupedTabs = document.querySelectorAll(`.sphinx-tabs-tab[name="${name}"]`); + const tabLists = Array.from(groupedTabs).map(tab => tab.parentNode); + + tabLists + .forEach(tabList => { + // Don't want to change the tabList containing the clicked tab + const clickedTab = tabList.querySelector(`[id="${clickedId}"]`); + if (clickedTab === null ) { + // Select first tab with matching name + const tab = tabList.querySelector(`.sphinx-tabs-tab[name="${name}"]`); + deselectTabList(tab); + selectTab(tab); + } + }) +} + +if (typeof exports === 'undefined') { + exports = {}; +} + +exports.keyTabs = keyTabs; +exports.changeTabs = changeTabs; +exports.selectTab = selectTab; +exports.deselectTabList = deselectTabList; +exports.selectNamedTabs = selectNamedTabs; diff --git a/branch/comms/_static/term_role_formatting.css b/branch/comms/_static/term_role_formatting.css new file mode 100644 index 0000000..0b66095 --- /dev/null +++ b/branch/comms/_static/term_role_formatting.css @@ -0,0 +1,4 @@ +/* Make terms bold */ +a.reference span.std-term { + font-weight: bold; +} diff --git a/branch/comms/_static/togglebutton.css b/branch/comms/_static/togglebutton.css new file mode 100644 index 0000000..54a6787 --- /dev/null +++ b/branch/comms/_static/togglebutton.css @@ -0,0 +1,160 @@ +/** + * Admonition-based toggles + */ + +/* Visibility of the target */ +.admonition.toggle .admonition-title ~ * { + transition: opacity .3s, height .3s; +} + +/* Toggle buttons inside admonitions so we see the title */ +.admonition.toggle { + position: relative; +} + +/* Titles should cut off earlier to avoid overlapping w/ button */ +.admonition.toggle .admonition-title { + padding-right: 25%; + cursor: pointer; +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:hover { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 1%); +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:active { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 3%); +} + +/* Remove extra whitespace below the admonition title when hidden */ +.admonition.toggle-hidden { + padding-bottom: 0; +} + +.admonition.toggle-hidden .admonition-title { + margin-bottom: 0; +} + +/* hides all the content of a page until de-toggled */ +.admonition.toggle-hidden .admonition-title ~ * { + height: 0; + margin: 0; + opacity: 0; + visibility: hidden; +} + +/* General button style and position*/ +button.toggle-button { + /** + * Background and shape. By default there's no background + * but users can style as they wish + */ + background: none; + border: none; + outline: none; + + /* Positioning just inside the admonition title */ + position: absolute; + right: 0.5em; + padding: 0px; + border: none; + outline: none; +} + +/* Display the toggle hint on wide screens */ +@media (min-width: 768px) { + button.toggle-button.toggle-button-hidden:before { + content: attr(data-toggle-hint); /* This will be filled in by JS */ + font-size: .8em; + align-self: center; + } +} + +/* Icon behavior */ +.tb-icon { + transition: transform .2s ease-out; + height: 1.5em; + width: 1.5em; + stroke: currentColor; /* So that we inherit the color of other text */ +} + +/* The icon should point right when closed, down when open. */ +/* Open */ +.admonition.toggle button .tb-icon { + transform: rotate(90deg); +} + +/* Closed */ +.admonition.toggle button.toggle-button-hidden .tb-icon { + transform: rotate(0deg); +} + +/* With details toggles, we don't rotate the icon so it points right */ +details.toggle-details .tb-icon { + height: 1.4em; + width: 1.4em; + margin-top: 0.1em; /* To center the button vertically */ +} + + +/** + * Details-based toggles. + * In this case, we wrap elements with `.toggle` in a details block. + */ + +/* Details blocks */ +details.toggle-details { + margin: 1em 0; +} + + +details.toggle-details summary { + display: flex; + align-items: center; + cursor: pointer; + list-style: none; + border-radius: .2em; + border-left: 3px solid #1976d2; + background-color: rgb(204 204 204 / 10%); + padding: 0.2em 0.7em 0.3em 0.5em; /* Less padding on left because the SVG has left margin */ + font-size: 0.9em; +} + +details.toggle-details summary:hover { + background-color: rgb(204 204 204 / 20%); +} + +details.toggle-details summary:active { + background: rgb(204 204 204 / 28%); +} + +.toggle-details__summary-text { + margin-left: 0.2em; +} + +details.toggle-details[open] summary { + margin-bottom: .5em; +} + +details.toggle-details[open] summary .tb-icon { + transform: rotate(90deg); +} + +details.toggle-details[open] summary ~ * { + animation: toggle-fade-in .3s ease-out; +} + +@keyframes toggle-fade-in { + from {opacity: 0%;} + to {opacity: 100%;} +} + +/* Print rules - we hide all toggle button elements at print */ +@media print { + /* Always hide the summary so the button doesn't show up */ + details.toggle-details summary { + display: none; + } +} \ No newline at end of file diff --git a/branch/comms/_static/togglebutton.js b/branch/comms/_static/togglebutton.js new file mode 100644 index 0000000..215a7ee --- /dev/null +++ b/branch/comms/_static/togglebutton.js @@ -0,0 +1,187 @@ +/** + * Add Toggle Buttons to elements + */ + +let toggleChevron = ` + + + +`; + +var initToggleItems = () => { + var itemsToToggle = document.querySelectorAll(togglebuttonSelector); + console.log(`[togglebutton]: Adding toggle buttons to ${itemsToToggle.length} items`) + // Add the button to each admonition and hook up a callback to toggle visibility + itemsToToggle.forEach((item, index) => { + if (item.classList.contains("admonition")) { + // If it's an admonition block, then we'll add a button inside + // Generate unique IDs for this item + var toggleID = `toggle-${index}`; + var buttonID = `button-${toggleID}`; + + item.setAttribute('id', toggleID); + if (!item.classList.contains("toggle")){ + item.classList.add("toggle"); + } + // This is the button that will be added to each item to trigger the toggle + var collapseButton = ` + `; + + title = item.querySelector(".admonition-title") + title.insertAdjacentHTML("beforeend", collapseButton); + thisButton = document.getElementById(buttonID); + + // Add click handlers for the button + admonition title (if admonition) + admonitionTitle = document.querySelector(`#${toggleID} > .admonition-title`) + if (admonitionTitle) { + // If an admonition, then make the whole title block clickable + admonitionTitle.addEventListener('click', toggleClickHandler); + admonitionTitle.dataset.target = toggleID + admonitionTitle.dataset.button = buttonID + } else { + // If not an admonition then we'll listen for the button click + thisButton.addEventListener('click', toggleClickHandler); + } + + // Now hide the item for this toggle button unless explicitly noted to show + if (!item.classList.contains("toggle-shown")) { + toggleHidden(thisButton); + } + } else { + // If not an admonition, wrap the block in a
block + // Define the structure of the details block and insert it as a sibling + var detailsBlock = ` +
+ + ${toggleChevron} + ${toggleHintShow} + +
`; + item.insertAdjacentHTML("beforebegin", detailsBlock); + + // Now move the toggle-able content inside of the details block + details = item.previousElementSibling + details.appendChild(item) + item.classList.add("toggle-details__container") + + // Set up a click trigger to change the text as needed + details.addEventListener('click', (click) => { + let parent = click.target.parentElement; + if (parent.tagName.toLowerCase() == "details") { + summary = parent.querySelector("summary"); + details = parent; + } else { + summary = parent; + details = parent.parentElement; + } + // Update the inner text for the proper hint + if (details.open) { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintShow; + } else { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintHide; + } + + }); + + // If we have a toggle-shown class, open details block should be open + if (item.classList.contains("toggle-shown")) { + details.click(); + } + } + }) +}; + +// This should simply add / remove the collapsed class and change the button text +var toggleHidden = (button) => { + target = button.dataset['target'] + var itemToToggle = document.getElementById(target); + if (itemToToggle.classList.contains("toggle-hidden")) { + itemToToggle.classList.remove("toggle-hidden"); + button.classList.remove("toggle-button-hidden"); + } else { + itemToToggle.classList.add("toggle-hidden"); + button.classList.add("toggle-button-hidden"); + } +} + +var toggleClickHandler = (click) => { + // Be cause the admonition title is clickable and extends to the whole admonition + // We only look for a click event on this title to trigger the toggle. + + if (click.target.classList.contains("admonition-title")) { + button = click.target.querySelector(".toggle-button"); + } else if (click.target.classList.contains("tb-icon")) { + // We've clicked the icon and need to search up one parent for the button + button = click.target.parentElement; + } else if (click.target.tagName == "polyline") { + // We've clicked the SVG elements inside the button, need to up 2 layers + button = click.target.parentElement.parentElement; + } else if (click.target.classList.contains("toggle-button")) { + // We've clicked the button itself and so don't need to do anything + button = click.target; + } else { + console.log(`[togglebutton]: Couldn't find button for ${click.target}`) + } + target = document.getElementById(button.dataset['button']); + toggleHidden(target); +} + +// If we want to blanket-add toggle classes to certain cells +var addToggleToSelector = () => { + const selector = ""; + if (selector.length > 0) { + document.querySelectorAll(selector).forEach((item) => { + item.classList.add("toggle"); + }) + } +} + +// Helper function to run when the DOM is finished +const sphinxToggleRunWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} +sphinxToggleRunWhenDOMLoaded(addToggleToSelector) +sphinxToggleRunWhenDOMLoaded(initToggleItems) + +/** Toggle details blocks to be open when printing */ +if (toggleOpenOnPrint == "true") { + window.addEventListener("beforeprint", () => { + // Open the details + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.dataset["togglestatus"] = el.open; + el.open = true; + }); + + // Open the admonitions + document.querySelectorAll(".admonition.toggle.toggle-hidden").forEach((el) => { + console.log(el); + el.querySelector("button.toggle-button").click(); + el.dataset["toggle_after_print"] = "true"; + }); + }); + window.addEventListener("afterprint", () => { + // Re-close the details that were closed + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.open = el.dataset["togglestatus"] == "true"; + delete el.dataset["togglestatus"]; + }); + + // Re-close the admonition toggle buttons + document.querySelectorAll(".admonition.toggle").forEach((el) => { + if (el.dataset["toggle_after_print"] == "true") { + el.querySelector("button.toggle-button").click(); + delete el.dataset["toggle_after_print"]; + } + }); + }); +} diff --git a/branch/comms/co-teaching/index.html b/branch/comms/co-teaching/index.html new file mode 100644 index 0000000..fee9eb9 --- /dev/null +++ b/branch/comms/co-teaching/index.html @@ -0,0 +1,301 @@ + + + + + + + Co-teaching — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Co-teaching

+
+

Objectives

+
    +
  • Get to know the principle of co-teaching: How we do it and how you can too.

  • +
  • Learn the team teaching concept and how to tailor it to your situation.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 15 min

  • +
  • Exercises: 10 min

  • +
  • Discussion: 5 min

  • +
+
+
+

Overview

+

CodeRefinery lessons benefit from the application of the concepts of co-teaching.

+
+

Co-teaching

+

Co-teaching can be defined as “the division of labor between educators to plan, organize, instruct and make assessments on the same group of students, generally in a common classroom, and often with a strong focus on those teaching as a team complementing one another’s particular skills or other strengths”.

+
+

Co-teaching can be used in various forms, some of which are present in our workshops:

+
    +
  • Teaching + support, e.g. one of the teachers leading instruction while the other watches over and maintains the collaborative document (HackMD/HedgeDoc/…).

  • +
  • Another similar example is remote learning groups that watch the streamed CodeRefinery lessons guided by the local instructors.

  • +
  • Having open-source material and planning jointly allows multiple instances of a lesson to be held by multiple teachers:

    +
      +
    • parallel teaching, to different audiences at the same time,

    • +
    • alternative teaching, to different audiences at the same or different time, with potential content adjustments (for example, different installation procedures).

    • +
    +
  • +
  • Team teaching, where the lesson is presented by multiple (in most cases, two) teachers who actively engage in conversation with each other. The team-teaching concept is explained in more detail in the CodeRefinery manual.

  • +
+

In reality, different forms are very often mixed or fused together, even within a single lesson.

+

Co-teaching is not an online-only concept. However, it is very practical in online teaching due to larger number of instructors and learners potentially available to join a teaching session.

+
+
+

Co-teaching and team teaching benefits

+
    +
  • It saves preparation time. Co-teachers can rely on each other’s strengths while creating/ revising the material as well as in unexpected situations during the lesson.

  • +
  • It helps with onboarding new instructors. One of the co-teachers can be learning at the same time, either the subtleties of the material taught (in this case literally being the “voice of the audience”) or the teaching process itself.

  • +
  • Team teaching looks more interactive and engaging to the audience in many cases, without forcing the learners to speak up if they can’t or don’t want to do so.

  • +
  • It also ensures responsive feedback and less workload by having more active minds.

  • +
+
+

Are there any downsides?

+

Not every learner and not every instructor might like the team-teaching approach.

+
    +
  • It might seem less structured, unprepared, and chaotic, even with preparation.

    +
      +
    • It might create situations where instructors accidentally talk over each other or “interrupt” and change the flow of the lesson.

    • +
    • For some instructors it can be stressful to not know in advance what questions they get asked from the co-instructor.

    • +
    • Sometimes when an unexpected question is asked that throws the other instructor off, it can add to the feeling of chaos and unpreparedness.

    • +
    +
  • +
  • It can be interactive and engaging but it can also end up awkward if the co-teachers don’t have a good synergy.

    +
      +
    • Can sound awkward: Main instructor talking all the time and at the end asking co-instructor whether everything is clear and co-instructor only saying “yes”.

    • +
    • Possibly more engaging: Co-instructor asking questions which help with the flow and a common understanding of the material.

    • +
    +
  • +
+
+
+
+

Team teaching specifics

+
    +
  • For successful team teaching, additional coordination is needed, first of all to agree on the teaching model (see below) and the person in control (the director) for the lesson or its parts.

  • +
  • It’s useful to keep track of the lecture plan. The discussion is a good way to make lesson more interactive and adjust to the audience, but deviating too much will become disorienting (for example, if someone dropped their attention for a minute and now is trying to catch-up by reading lecture notes).

  • +
  • Experienced solo teacher might have a habit to keep talking (lecturing), while the co-teacher might not want to “interrupt”. Therefore, it is important for the leading presenter to anticipate and allow for remarks/ questions, and this can be different from one’s previous teaching style at first.

  • +
+
+
+

Team teaching models

+

We propose two basic models, but of course there is a constant continuum.

+
+

Guide and demo-giver

+

One person serves the role of guide, explaining the big picture and context of the examples.

+

Another, the demo-giver,

+
    +
  • shows the typing and does the examples,

  • +
  • might take the role of a learner who is asking about what is going on, to actually explain the details, or to comment occasionally.

  • +
+

Hands-on demos and exercises work especially well like this.

+
+
+

Presenter and interviewer

+

In this case, one is the presenter who is mostly explaining (including demos or examples), and trying to move the forward through the material.

+

Another, the interviewer,

+
    +
  • serves as a learner or spotter,

  • +
  • fills in gaps by asking relevant questions,

  • +
  • tries to comment to the presenter when things are going off track.

  • +
+

This can be seen as closer to classical teaching, but with a dedicated and prepared “voice of the audience”.

+
+
+

Exercise

+
+

Discuss the models of team teaching (10 min)

+

While in breakout rooms, discuss one of the basic team-teaching models presented here:

+
    +
  • Have you already tried this or similar model in your teaching?

  • +
  • Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best?

  • +
+

Write your comments in the collaborative document.

+
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Co-teaching focuses on complementing individual skills and strengths in teaching process.

  • +
  • Co-teaching may save time, reduce teachers’ workload and make lessons more interactive/ engaging.

  • +
  • Team teaching requires some adjustments in lesson preparation and delivery.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/coderefinery-intro/index.html b/branch/comms/coderefinery-intro/index.html new file mode 100644 index 0000000..1e52a61 --- /dev/null +++ b/branch/comms/coderefinery-intro/index.html @@ -0,0 +1,280 @@ + + + + + + + About the CodeRefinery project and CodeRefinery workshops in general — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • + Edit on GitHub +
  • +
+
+
+
+
+ +
+

About the CodeRefinery project and CodeRefinery workshops in general

+
+

Objectives

+
    +
  • Discuss what CodeRefinery is and how we got here

  • +
  • Understand about the challenges to define our target audience

  • +
+
+

CodeRefinery is a +Nordic e-Infrastructure Collaboration (NeIC) +project that has started in October 2016 and is currently +funded until February 2025. We are working on the continuation plans.

+

The funding from 2022-2025 is designed to keep this project active +beyond 2025 by forming a support network and building a community of +instructors and contributors.

+
+

History

+

The CodeRefinery project idea grew out of two SeSE courses given at KTH Stockholm in 2014 and 2016. +The project proposal itself was submitted to NeIC in 2015, accepted in 2015, and started in 2016.

+

We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form.

+
+
+

Goals

+
    +
  • Develop and maintain training material on good enough software development practices for researchers that write code/scripts/notebooks.

  • +
  • Our material addresses all academic disciplines and tries to be as programming language-independent as possible.

  • +
  • Provide a code repository hosting service that is open and free +for all researchers based in universities and research institutes from Nordic countries.

  • +
  • Provide training opportunities in the Nordics using (Carpentries and) CodeRefinery training materials.

  • +
  • Evolve the project towards a community-driven project with a network of instructors and contributors.

  • +
+
+
+

Community

+
+../_images/community.png +
+

Image showing the key areas of the CodeRefinery community: Workshops, chat inlcuding help channel, online meetings and co-working, +other collaborative training, eg on High Performance Computing topics.

+
+
+

CodeRefinery is not just workshops, we are community and want you to be part of it!

+

There are many different levels of involvement, from the occasional commenter in chat, +CodeRefinery ambassador (people who like the project and workshops and help us spreading the word) or lesson issue creators and lesson contributors to +local host, co-instructor or co-organizer.

+

Best first step in any case is to join the CodeRefinery Zulip chat +or let us know about your interest at support@coderefinery.org.

+
+
+

Target audience

+

One common question we get is how do we relate to the Carpentries. +This section describes how we see it:

+
+

Carpentries audience

+

The Carpentries aims to teach computational competence to learners through an applied approach, +avoiding the theoretical and general in favor of the practical and specific.

+

Mostly, learners do not need to have any prior experience in programming. +One major goal of a Carpentries workshop is to raise awareness on the tools researchers can learn/use to speed up their research.

+

By showing learners how to solve specific problems with specific tools and providing hands-on practice, +learners develops confidence for future learning.

+
+

Novices

+

We often qualify Carpentries learners as novices: they do not know what they need to learn yet. +A typical example is the usage of version control: the Carpentries lesson +Version Control with Git +aims to give a +very high level conceptual overview of Git but it does not explain how it can be used in research projects.

+
+
+
+

CodeRefinery audience

+

In that sense, CodeRefinery workshops differ from Carpentries workshops as we assume +our audience already writes code and scripts and we aim at teaching them best software practices.

+

Our learners usually do not have a good overview of best software practices but are aware of the need to learn them. +Very often, they know of the tools (Git, Jupyter, etc.) we are teaching +but have difficulties to make the best use of them in their software development workflow.

+

Whenever we can, we direct learners that do not have sufficient coding experience to Carpentries workshops.

+
+

Competent practitioners

+

We often qualify CodeRefinery learners as competent practitioners because they already have an understanding of their needs.

+
+ +
+
+

Keypoints: CodeRefinery

+
    +
  • Teaches intermediate-level software development tool lessons

  • +
  • It is difficult to define “best practices”, we try to teach “good enough” practices

  • +
  • Training network for other lessons

  • +
  • Publicly-funded discrete projects (3 projects actually) transitioning towards an open community project

  • +
  • We have online material, teaching, and exercise sessions

  • +
  • Our main target audience are competent practitioners, but also novices and experts can get something out of the workshops

  • +
  • We want more people to work with us, and to work with more people

  • +
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/collaborative-notes/index.html b/branch/comms/collaborative-notes/index.html new file mode 100644 index 0000000..6062c6d --- /dev/null +++ b/branch/comms/collaborative-notes/index.html @@ -0,0 +1,530 @@ + + + + + + + Collaborative notes — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Collaborative notes

+
+

Objectives

+
    +
  • Be able to provide a highly interactive online workshop environment with collaborative documents

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Exercise: 15 min

  • +
  • Questions & Answers: 5 min

  • +
+
+
+

Introduction

+

The Collaborative document is how you interact with the participants. +The participants can ask questions and give feedback through the collaborative +document. During a CodeRefinery session there can be a large a volume of questions. +A dedicated person, a Collaborative document-manager, is needed to answer and edit the collaborative document. +Let us see how the collaborative document is used, then discuss the role of +the editor or collaborative document-manager.

+
+
+

Collaborative document mechanics and controls

+

Technologies that can be used as a collaborative document are Hackmd, HedgeDoc, +or Google Docs

+

Hackmd or HedgeDoc are real-time text editor online. We use it to:

+
    +
  • As a threaded chat, to answer questions and provide other information without +interrupting the main flow of the room.

  • +
  • provide everyone with a more equal opportunity to ask questions.

  • +
  • create notes which will be archived, for your later reference.

  • +
+

You do not need to login/create an account to be able to edit the document.

+
+

Basic controls

+
+../_images/hackmd--controls.png +
+

This may look slightly different on mobile devices and small windows.

+
+
+
    +
  • At the top (left or right), you can switch between view, +edit, and split view and edit modes.

  • +
  • You write in markdown here. Don’t +worry about the syntax, just see what others do and try to be like +that! Someone will come and fix any problems there may be.

  • +
  • Please go back to view mode if you think you won’t edit for a +while - it will still live update.

  • +
+
+
+

Asking questions

+

Always ask questions and add new sections at the very bottom. +You can also answer and comment on older questions, too.

+
+../_images/hackmd--questions2.png +
+

Questions and answers in bullet points

+
+
+

Since we plan to publish the questions and answers later as part +of the workshop page, we recommend to not use any names. You can indicate +your own name to make it easier to discuss more during the workshop but +then always use this form: [name=Myname]. This makes it easier for +us to automatically remove all names before publishing the notes.

+

Other hints:

+
    +
  • Use +1 to agree with a statement or question (we are more likely +to comment on it).

  • +
  • Please leave some blank lines at the bottom

  • +
  • NOTE: Please don’t “select all”, it highlights for everyone and adds a +risk of losing data (there are periodic backups, but not instant).

  • +
  • It can be quite demanding to follow the collaborative document closely. Keep an eye +on it, but consider how distracted you may get from the course. For +things beyond the scope of the course, we may come back and answer +later.

  • +
+
+
+

Don’t get overwhelmed

+

There can be a flood of information on the collaborative document. Scan for what is +important, then if you would like come back later. But it is +important to keep checking it.

+
+
+

Privacy

+
    +
  • Assume the collaborative document is public and published: you never +need to put your name there.

  • +
  • The collaborative document will be published on the website afterwards. We will +remove all non-instructors names, but it’s easier if you don’t add +it there in the first place.

  • +
  • Please keep the link private during the workshop, since since +security is “editable by those who have the link”.

  • +
  • You can use [name=YOURNAME], to name yourself. We will remove +all names (but not the comments) before archiving the notes (use +this format to make it easy for us).

  • +
+
+
+
+

Exercise

+
+

Discuss how to collaborate and handle questions (15 min)

+

Write down your conclusions in the shared document. Items to discuss are:

+
    +
  • What is your experience with questions and discussions while teaching?

  • +
  • How do you deal with them?

  • +
  • What kind of technologies do you prefer: chat, shared document, or voices +and discussion raised during instruction? And why?

  • +
+
+
+
+

Collaborative Document Manager

+

We have one person who is a “Collaborative Document helper”. This isn’t the only +person that should edit and answer, but one person shouldn’t have too +much else on their mind so can focus on it. They also make sure that +the collaborative document is updated with exercise, break, and other meta-information to +keep people on track.

+

Below, (*) = important.

+
+

Before the workshop

+
    +
  • Create a new collaborative document for the workshop

  • +
  • make sure that editing is enabled for anyone without login

  • +
  • Add workshop information, links to the workshop page and material +and an example question and answer to the top of the collaborative document(see below)

  • +
+
+
+

Most things to edit (everyone)

+

Make it easy to post after the course and consistent to follow:

+
    +
  • Tag all names with [name=XXX] (so they can be removed later), +remove other personal data or make it obvious.

  • +
  • Add in information on exercises (new section for them, link, end +time, what to accomplish)

  • +
  • Make a logical section structure (# for title, ## for sections, +### for episodes, etc. - or what makes sense)

  • +
+
+
+

General Collaborative Document practices

+
+../_images/hackmd--full-demo.png +
+

A live demo of a Collaborative Document during a Q&A time. The two instructors are +discussing some of the import answers. Multiple learners have asked +questions, multiple answers, and some remaining to be answered

+
+
+

Keep it formatted well:

+
    +
  • (*) Tag names you see with [name=XXX] so that we can remove it +later.

  • +
  • Heading level # is only the page title

  • +
  • Add a new ## heading when a new lesson or similar thing is +started (introduction, icebreaker, break between lessons, etc)

  • +
  • Add a new ### heading when a new episode, exercise, break +(within exercise session)

  • +
  • Ensure people are asking questions at the bottom, direct them there +if they aren’t.

  • +
  • (*) Ensure each question is a bullet point. Each answer or follow-up +should be a bullet point below.

    +
      +
    • Should you use more deeply nested bullet points, or have only one +level below the initial question? It depends on the context, but +if a conversation goes on too long, try not to let it go too +deep.

    • +
    +
  • +
+

Update with meta-talk, so that learners can follow along easily:

+
    +
  • Add Icebreaker and introductory material of the day. Try to talk to +people as they joined to get them to open the collaborative document and answer.

  • +
  • Anything important for following along should not be only said via +voice. It needs to be in the collaborative document, too.

  • +
  • New lessons or episodes, with links to them.

  • +
  • For exercises, link to exercise and add the duration, end time, +goals. If these are unclear, bring it up to the instructor by voice.

  • +
  • Add a status display about breaks.

  • +
+

Screenshare it when necessary:

+
    +
  • During breaks and other times, share the collaborative document(including the +notification about break, and when it ends).

  • +
  • It is nice if the arrangement allows some of the latest questions to +be seen, so people are reminded to ask there.

  • +
  • Someone else may do this, but should make sure it happens.

  • +
+

Answer questions

+
    +
  • If there is an question that should be answered by the instructor by +voice, bring it up (by voice) to the instructor immediately.

  • +
  • How soon do you answer questions? Two points of view:

    +
      +
    • Answer questions right away: can be really intense to follow.

    • +
    • Wait some so that we don’t overload learners: reduces the info +flow. But then do people need to check back more often.

    • +
    • You need to find your own balance. Maybe a quick answer right +away, and more detailed later. Or delay answers during the most +important parts of the lecture.

    • +
    +
  • +
  • Avoid wall-of-text answers. If reading an answer takes too long, it +puts the person (and other people who even try to read it) behind +even more by taking up valuable mental energy. If an answer needs a +wall of text, consider these alternatives:

    +
      +
    • Progressive bullet points getting more detailed (first ones +useful alone for basic cases)

    • +
    • Don’t be worried to say “don’t worry about this now, let’s talk +later.”

    • +
    • Figure out the root problem instead of answering every possible +interpretation

    • +
    • Declare it advanced and that you will come back later.

    • +
    +
  • +
+

Ensure it can be posted quickly:

+
    +
  • The collaborative document gets posted to the workshop webpage. For this, it needs some +minimal amount of formatting (it doesn’t need to be perfect, just +not horrible).

  • +
  • All names and private information needs to be stripped. This is why +you should rigorously tag all names with [name=XXX] so they can be +removed (see above).

    +
      +
    • Learner names can be completely removed. CR staff names can be +[name=CR] or something similar.

    • +
    • There may be other private URLs at the top or bottom.

    • +
    +
  • +
  • If possible, send the PR adding the collaborative document to the workshop webpage +(though others can do this, too).

  • +
+
+
+

Collaborative document format example

+
# Workshop, day 1
+
+
+## Lesson name
+https://coderefinery.github.io/lesson/
+
+### Episode name
+https://coderefinery.github.io/01-episode/
+
+- This is a question
+  - Anwser
+  - More detailed answer
+- question
+  - answer
+
+### Exercises:
+https://link-to-exercise/.../.../#section
+20 minutes, until xx:45
+Try to accomplish all of points 1-3.  Parts 4-5 are optional.
+
+Breakout room status:
+- room 2, need help with Linux permissions
+- room 5, done
+
+### Break
+:::danger
+We are on a 10 minute break until xx:10
+:::
+
+
+## Lesson 2
+https://coderefinery.github.io/lesson-2/
+
+
+
+
+
+

Posting the collaborative document to the website

+

The collaborative document should be posted sooner rather than later, and hopefully the +steps above will make it easy to do so quickly. You could wait a few +hours, to allow any remaining questions to be asked an answered.

+
    +
  • Download as markdown

  • +
  • Remove any private links at the top

  • +
  • Adjust headings so that they are reasonable

  • +
  • Look for private info and remove it

    +
      +
    • Search document for [name=???] (change to [name=staff] or +[name=learner])

    • +
    • Any names not tagged with [name=]

    • +
    • usernames in URLs

    • +
    • private links

    • +
    +
  • +
+
+
+

Feedback template

+
## Feedback, day N
+
+:::info
+### News for day N+1
+- .
+- .
+:::
+
+### Today was (multi-answer):
+- too fast: 
+- just right: 
+- too slow: 
+- too easy: 
+- right level: 
+- too advanced: 
+- I would recommend this course to others: 
+- Exercises were good: 
+- I would recommend today to others: 
+- I wouldn't recommend today: 
+
+### One good thing about today:
+- ...
+- ...
+
+### One thing to be improved for next time:
+- ...
+- ...
+
+### Any other comments:
+- ...
+- ...
+
+
+
+

Keypoints

+
    +
  • Having a collaborative document improves communication and interaction.

  • +
  • Answering questions requires a dedicated person - A Collaborative Document Manager.

  • +
  • The collaborative document should be posted on the web site as soon as possible.

  • +
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/comms/index.html b/branch/comms/comms/index.html new file mode 100644 index 0000000..ebe2303 --- /dev/null +++ b/branch/comms/comms/index.html @@ -0,0 +1,313 @@ + + + + + + + Communications with participants — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Communications with participants

+

Before the workshop

+

Hei,

+

thank you for your interest in the CodeRefinery train the trainer workshop!

+

We are excited to start the workshop next week and wanted to share some information with you:

+

Connection details

+

Zoom: XX

+

Collaborative notes

+

This document will be used during the course and contains all information around the workshop as well as the place to collect questions and answers: XX

+

Materials

+

Our materials are a work in progress, but will appear and also later remain available here: https://coderefinery.github.io/train-the-trainer/

+

Workshop plan

+

The workshop is split in four interactive sessions (9-12 CEST each Tuesday) which are independent from each other, so you may join all or just the ones that interest you or suit your schedule:

+
Session 1: About lesson design, deployment, and iterative improvement (Aug 13)
+Session 2: Tools and techniques adopted in CodeRefinery workshops (Aug 20)
+Session 3: About teaching & cool things we all would like to share (Aug 27)
+Session 4: Workshop streaming practices and post-workshop tasks (Sep 3)
+
+
+

Registration info

+

You can adapt your registration following the link in the registration confirmation e-mail.

+

Preparations

+

In general you will only need your brain for the exercises and discussions, but some will have the option to go deeper, which may require some accounts or tools to be set-up. We will inform about these things the week before each session.

+

For Session 1 we recommend to have a GitHub account (https://coderefinery.github.io/installation/github/#github). There will be an optional exercise where you can build a lesson locally. This requires a basic Python environment (https://github.com/coderefinery/sphinx-lesson-template/blob/main/requirements.txt), but do not worry if you cannot or do not want to set up these, there will be plenty of other exercises.

+

Questions?

+

If you have any questions, ideas, or suggestions, please contact us at support@coderefinery.org

+

We are looking forward to learning with you!

+

Kind regards, +XX on behalf of CodeRefinery

+
+

Morning before Day 1

+

Good morning,

+

the first session of the CodeRefinery train the trainer workshop will start at 9 CEST (Berlin, Stockholm time) / 10 EEST (Helsinki time) / 8 BST (British time) / 7 GMT+0 , i.e. in about 35 min. +Please join a bit early if you can, so that we can get started with the practicalities and introductions in time :)

+

And no worries if you cannot join today, but want to join other sessions: Each session is self contained, and the materials will stay available.

+

Zoom link: XX

+

Lesson materials: https://coderefinery.github.io/train-the-trainer/

+

Collaborative notes: XX

+

Looking forward to meeting you all!

+

Kind regards, +XX on behalf of CodeRefinery

+
+

After Day 1 before Day 2

+

Email: Sent to all currently registered participants on 16.8 at 14.20 EEST:

+

Hei,

+

If you joined us last week, we hope you enjoyed last weeks session. In any case we hope you will join us for the next session on next weeks +Tuesday August 20th at 9-12 Central European Summer Time (CEST, UTC+2).

+

The connection details stay the same:

+

Zoom: XX

+

We will also use again and learn more about our Collaborative notes : XX +One change to the previous session is that we will turn off Zoom chat and focus the discussion to the notes.

+

The materials are and will stay available: https://coderefinery.github.io/train-the-trainer/

+

As mentioned before, all our workshop sessions are independent of each other and of interactive nature. +In this upcoming session we will discuss “Tools and techniques adopted in CodeRefinery workshops”:

+
Brief introduction to the CodeRefinery project and its history.
+Collaborative notes in general as a tool to keep an online workshop interactive.
+Current CodeRefinery workshop setup, what roles we have, what tools we use, who and how we onboard and why this might be useful for you too outside of CR workshops.
+General discussion and practice about topics related to sound in online workshops.
+General discussion and practice about screenshare for online and streamed workshops.
+
+
+

Preparations

+

In general you will only need your brain for the exercises and discussions. To get the most out of this workshop day we recommend that you join the session with the same computer, display and microphone setup as you would usually use for teaching/ presenting. It may also help to get familar with the different options your computer and Zoom setup provides for screenshare and audio adjustments. +But it is not a must.

+

Questions?

+

If you have any questions, ideas, or suggestions, please contact us at support@coderefinery.org

+

We are looking forward to learning with you!

+

Kind regards, +XX on behalf of CodeRefinery

+
+

Morning before Day 2

+

Good morning,

+

the second session of the CodeRefinery train the trainer workshop will start at 9 CEST (Berlin, Stockholm time) / 10 EEST (Helsinki time) / 8 BST (British time) / 7 GMT/UTC+0 ; all AM; i.e. in about one hour. +Please join a bit early if you can, so that we can get started with the practicalities and introductions in time :)

+

And no worries if you cannot join today, but want to join other sessions: Each session is self contained, and the materials will stay available.

+

Zoom link: XX

+

Lesson materials: https://coderefinery.github.io/train-the-trainer/

+

Collaborative notes: XX

+

Looking forward to meeting you all!

+

Kind regards, +XX on behalf of CodeRefinery

+
+

After Day 2 before Day 3

+

Hei,

+

If you joined us any of the last weeks, we hope you enjoyed those sessions. In any case we hope you will join us for the next session on next weeks +Tuesday August 27th at 9-12 Central European Summer Time (CEST, UTC+2).

+

The connection details stay the same:

+

Zoom: XX

+

We will use our Collaborative notes for sharing links, notes and ask and answer questions : XX +We kindly ask everyone to focus the discussion to the notes.

+

The materials are and will stay available: https://coderefinery.github.io/train-the-trainer/

+

As mentioned before, all our workshop sessions are independent of each other and of interactive nature. +In this upcoming session we will discuss “About teaching and cool things we all would like to share”:

+
Introduction to computational thinking and how this relates to teaching computational topics
+Teaching philosophies: Personal stories and discovering your own
+Co-teaching: What it is, why we do it and challenges we have encountered
+Cool gems we all would like to share: Kinda "open mic" session for everyone to share some cool tool that you like to use when teaching/preparing materials or a nice anecdote from teaching, reports from the best course you ever visited, etc.
+
+
+

Preparations

+

In general you will only need your brain for the exercises and discussions. If you want to share some “cool gem” in the last episode of this workshop day, please update your registration (link to edit can be found in the registration confirmation e-mail sent by support@coderefinery.org or noreply@neic.org). This is very low barrier, you do not have to be the developer of a tool or technique to share with the group what makes it useful for you; and it does not even have to be cool, sometimes the small “normal” things are the best. You can check out some topics that have been proposed so far in this GitHub issue (#90), you can also comment there if you want to add or change your topic. These will be lightning talk length, so something between 2-5 min depending on how many are interested to share something, but we can collect them all in the collaborative notes for further exploration/reading. +But it is not a must.

+

Questions?

+

If you have any questions, ideas, or suggestions, please contact us at support@coderefinery.org

+

We are looking forward to learning with you!

+

Kind regards, +XX on behalf of CodeRefinery

+
+

Morning before Day 3

+

Good morning,

+

the third session of the CodeRefinery train the trainer workshop will start at 9 CEST (Berlin, Stockholm time) / 10 EEST (Helsinki time) / 8 BST (British time) / 7 GMT/UTC+0 ; all AM; i.e. in about 75 min.

+

Please join a bit early if you can, so that we can get started with the practicalities and introductions in time :)

+

And no worries if you cannot join today, but want to join other sessions: Each session is self contained, and the materials will stay available.

+

Zoom link: XX

+

Lesson materials: https://coderefinery.github.io/train-the-trainer/

+

Collaborative notes: XX

+

For the last episode of today, if you want to share some story or demo about any tools or techniques you like using when teaching, please add your name/initials and topic the collaborative notes: https://notes.coderefinery.org/TTT24?view#Teaching-gems .

+

Looking forward to learning with you today!

+

Kind regards, +XX on behalf of CodeRefinery

+
+

After Day 3 before Day 4

+

Email sent to all registered participants on 29.8 at 18 EEST:

+

Hei,

+

If you joined us any of the last weeks, we hope you enjoyed those sessions. In any case we hope you will join us for the next session on next weeks Tuesday September 3rd at 9-12 Central European Summer Time (CEST, UTC+2).

+

The connection details stay the same:

+

Zoom: XX

+

We will use our Collaborative notes for sharing links, notes and ask and answer questions : XX +We kindly ask everyone to focus the discussion to the notes.

+

The materials are and will stay available: https://coderefinery.github.io/train-the-trainer/

+

As mentioned before, all our workshop sessions are independent of each other and of interactive nature.

+

This upcoming session (session number 4) will cover the technical aspects of CodeRefinery-style online teaching. These topics have never before been covered in this much detail, so if it’s interesting to you, don’t miss it. (You might also want to pass this on to others who are interested in technical production of online events; registration is still open!).

+

First, we talk about why we stream (how we got here, advantages, disadvantages, how to be an instructor in a livestreamed workshop, and what it looks like from a broad level from the production side)

+

Then, we show how we are able to release videos so quickly. This is useful far beyond CodeRefinery, and there are also some hands-on exercises. Come prepared to set up a Python environment and the ffmpeg command line tool if you want to try these.

+

Finally, we see details about how to set up Zoom→Livestream environment for yourself. There isn’t time to do this as a proper exercise, but it’s the starting point and the instructor will offer help after the course for those interested. If you want to try this out during the session, install OBS Studio in advance.

+

Questions?

+

If you have any questions, ideas, or suggestions, please contact us at support@coderefinery.org .

+

We are looking forward to learning with you!

+

Kind regards, +XX on behalf of CodeRefinery

+
+

Morning before Day 4

+

Good morning,

+

the fourth session of the CodeRefinery train the trainer workshop will start at 9 CEST (Berlin, Stockholm time) / 10 EEST (Helsinki time) / 8 BST (British time) / 7 GMT/UTC+0 ; all AM; i.e. in about one hour.

+

Please join a bit early if you can, so that we can get started with the practicalities and introductions in time :)

+

And no worries if you cannot join today, all materials will stay available.

+

Zoom link: XX

+

Lesson materials: https://coderefinery.github.io/train-the-trainer/

+

Collaborative notes: XX

+

Kind regards, +XX on behalf of CodeRefinery

+
+

After workshop email

+

TBD

+
+ + +
+
+
+ +
+ +
+

© Copyright CodeRefinery project.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/computational-thinking/index.html b/branch/comms/computational-thinking/index.html new file mode 100644 index 0000000..26bd609 --- /dev/null +++ b/branch/comms/computational-thinking/index.html @@ -0,0 +1,189 @@ + + + + + + + Computational thinking — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Computational thinking

+
+

Objectives

+
    +
  • Explain what is computational thinking

  • +
  • Get to know how the theory of computational thinking can be used in teaching

  • +
  • Short exercise

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 10 min

  • +
+
+

Materials available as slides.

+
+

Keypoints

+
    +
  • Computational Thinking consists of 4 main parts: decomposition, pattern recognition, abstraction and algorithmic design.

  • +
  • How can this be a useful framework for solving problems?

  • +
  • How can this be used practically?

  • +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/cool-gems/index.html b/branch/comms/cool-gems/index.html new file mode 100644 index 0000000..d173047 --- /dev/null +++ b/branch/comms/cool-gems/index.html @@ -0,0 +1,181 @@ + + + + + + + Sharing teaching gems — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Sharing teaching gems

+
+

Objectives

+
    +
  • Our goal is to share our teaching tricks and tools and demonstrate them in +very short presentations/discussions.

  • +
+
+
+

Instructor note

+
    +
  • Demonstrations: 35 min

  • +
+
+

Here we encourage participants to take the screen share for 3 minutes and +demonstrate either some tool or trick they found useful for their teaching or +something from a course you liked.

+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/feedback-and-impact/index.html b/branch/comms/feedback-and-impact/index.html new file mode 100644 index 0000000..37a1f37 --- /dev/null +++ b/branch/comms/feedback-and-impact/index.html @@ -0,0 +1,421 @@ + + + + + + + How we collect feedback and measure impact — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

How we collect feedback and measure impact

+
+

Objectives

+
    +
  • Discuss how one can collect feedback from learners (“what can we improve?”).

  • +
  • Discuss how we convert feedback into actionable items.

  • +
  • Discuss how we measure the impact of teaching (“did we achieve our goals?”).

  • +
  • Discuss the “why”.

  • +
  • Get to know the reasons and sources of inspiration behind major lesson and workshop updates.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 20 min

  • +
  • Exercises: 10 min

  • +
+
+
+

Asking questions before the workshop

+ +
+
+

Collecting feedback as we teach

+
    +
  • Each day we ask for feedback in the collaborative notes.

    +
      +
    • One good thing about today.

    • +
    • One thing to improve for next time.

    • +
    • Any other comments?

    • +
    +
  • +
  • During the workshop we sometimes check in and ask about the pace, example:

    +
    How is the speed so far? (add an "o")
    +- Too fast:   oooooo
    +- Too slow:   ooo
    +- Just right: ooooooooooooooooooo
    +
    +
    +
  • +
  • We publish all questions, answers, and feedback. Example: https://coderefinery.github.io/2024-03-12-workshop/questions/

  • +
  • How we follow up:

    +
      +
    • Some problems we can fix already before the next workshop day.

    • +
    • We convert feedback/problems into GitHub issues and track these close to the lesson material.

    • +
    +
  • +
+
+
+

Trying to measure impact with longer-term surveys

+ +
+
+

Lessons learned

+
    +
  • Think about how to measure impact/success from the beginning.

  • +
  • Make the feedback and survey results public.

  • +
  • Make the results persistent and citable.

  • +
  • Have a mechanism to follow-up on feedback.

  • +
  • Anonymization is more than just removing or dissociating names.

  • +
  • Take time designing your survey and collect feedback on the survey itself.

  • +
+
+
+

Take time designing your survey

+

We are not experts in survey design but we reached out to RISE Research +Institutes of Sweden to get feedback on our survey questions. They provided us +with a lot of valuable feedback and suggestions for improvements. +Below are few examples.

+
+

Example 1

+

First version of our survey question about impact:

+
    +
  • “Do our workshops help to save time in future?” Please quantify in hours saved: …

  • +
+

Feedback:

+
    +
  • Difficult to answer.

  • +
  • Since when? Until all eternity?

  • +
+
+Screenshot of earlier version of the survey question about impact. +
+

Earlier version of the survey question about impact.

+
+
+

Feedback:

+
    +
  • The question “Do our workshops help to save time in future?” is unspecified, +unnecessary, and leading.

  • +
  • “No time saving” does not match the wording “save time” in the question.

  • +
+
+Screenshot of later version of the survey question about impact. +
+

Later version of the survey question about impact.

+
+
+
    +
  • The wording “have you saved” now matches “No time saved”.

  • +
+
+
+

Example 2

+
    +
  • Earlier version:

    +
    Would you judge your code to be better reusable/reproducible/modular/documented
    +as a result of attending the workshop?
    +
    +- More reusable
    +- More reproducible
    +- More modular
    +- Better documented
    +- None of the above
    +
    +
    +
  • +
  • Feedback: The question is not neutrally formulated and risks leading to +over-reporting of yes answers. Consider balancing so that the questions are +formulated more neutrally.

  • +
  • Reformulated to:

    +
    After attending the workshop, would you judge your code to be
    +more reusable or not more reusable?
    +
    +- My code is more reusable
    +- My code is not more reusable
    +- Not sure
    +
    +
    +
  • +
+
+
+

Example 3

+
    +
  • Early version:

    +
    What else has changed in how you write code since attending the workshop?
    +
    +[free-form text field]
    +
    +
    +
  • +
  • Feedback: Leading and assumes that something has changed.

  • +
  • Reformulated to:

    +
    Has anything else changed in how you write code for your research after
    +attending the workshop?
    +
    +[free-form text field]
    +
    +
    +
  • +
+
+
+

Example 4

+
    +
  • Earlier version:

    +
    Has it become easier for you to collaborate on software development with your
    +colleagues and collaborators?
    +
    +- Yes
    +- Not sure
    +- No
    +
    +
    +
  • +
  • Feedback:

    +
      +
    • Leading question.

    • +
    • Avoid “Yes” and “No” response options because respondents tend to answer +“Yes” if that option is available, leading to a risk of measurement error +(acquiescence bias).

    • +
    • Do not place “Not sure” in the middle of the scale because it captures +participants who actually don’t know and should therefore be placed at the +bottom instead of in the middle of the scale.

    • +
    +
  • +
  • Reformulated to:

    +
    After attending the workshop, has it become easier or not for you to
    +collaborate on software development with your colleagues and collaborators?
    +
    +- Collaboration is easier
    +- Collaboration is not easier
    +- Not sure
    +
    +
    +
  • +
+
+
+
+

Exercise: Group discussion (10 min)

+
+

Group discussion using the collaborative notes

+
    +
  • What tricks/techniques have you tried in your teaching or seen in someone +else’s teaching that you think have been particularly effective in collecting +feedback from learners?

  • +
  • Can you give tips or share your experiences about how to convert feedback +into actionable items?

  • +
  • How do you measure the impact of your teaching? Any tips or experiences about +what you have tried or seen other courses do?

  • +
  • Anybody knows of good resources on survey design? Please link them in +the collaborative notes.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/genindex/index.html b/branch/comms/genindex/index.html new file mode 100644 index 0000000..ab6bc31 --- /dev/null +++ b/branch/comms/genindex/index.html @@ -0,0 +1,170 @@ + + + + + + Index — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/branch/comms/guide/index.html b/branch/comms/guide/index.html new file mode 100644 index 0000000..9586f8a --- /dev/null +++ b/branch/comms/guide/index.html @@ -0,0 +1,260 @@ + + + + + + + Instructor guide — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Instructor guide

+
+

Target audience

+
    +
  • Everyone teaching online workshops about computational topics or interested in teaching.

  • +
  • Previous and future instructors and helpers of CodeRefinery workshops.

  • +
+
+
+

Timing

+

Session 1

+
    +
  • 15 min: Intro

  • +
  • 45 min: Lesson design and development

  • +
  • 15 min: Break

  • +
  • 45 min: Lesson template

  • +
  • 15 min: Break

  • +
  • 30 min: How we collect feedback and measure impact

  • +
  • 10 min: Outro and feedback

  • +
+

Session 2

+
    +
  • 15 min: Intro

  • +
  • 10 min: About the CodeRefinery project and CodeRefinery workshops in general

  • +
  • 30 min: Collaborative notes and interaction

  • +
  • 15 min: Break

  • +
  • 35 min: Workshop overview, roles, onboarding/installation, helpers

  • +
  • 20 min: Sound

  • +
  • 15 min: Break

  • +
  • 30 min: Screenshare

  • +
  • 10 min: Outro and feedback

  • +
+

Session 3

+
    +
  • 15 min: Intro

  • +
  • 30 min: Computational thinking

  • +
  • 15 min: Break

  • +
  • 30 min: Teaching philosohies

  • +
  • 30 min: Co-teaching

  • +
  • 15 min: Break

  • +
  • 35 min: Sharing teaching tips, tricks, tools etc

  • +
  • 10 min: Outro and feedback

  • +
+

Session 4

+
    +
  • 15 min: Intro

  • +
  • 10 min: Why we stream

  • +
  • 20 min: Behind the stream

  • +
  • 15 min: Video editing (part 1)

  • +
  • 15 min: Break

  • +
  • 25 min: Video editing (part 2, exercise)

  • +
  • 20 min: OBS introduction

  • +
  • 15 min: Break

  • +
  • 30 min: OBS setup

  • +
  • 15 min: What’s next?

  • +
+
+
+

Talking points for each sessions intro

+
    +
  • Brief CodeRefinery intro

  • +
  • Instructors intros

  • +
  • Notes intro

    +
      +
    • Check-in

    • +
    • Icebreaker

    • +
    • Participant intros in breakoutrooms (Random assign first, then same for whole session)

    • +
    +
  • +
  • Daily schedule, learning objectives

  • +
  • Code of conduct

  • +
  • Chat (please use collaborative notes)

  • +
+
+
+

Participant preparations for each session

+

Copied from e-mail communication with participants before each session.

+

Session 1: +In general you will only need your brain for the exercises and discussions, but some will have the option to go deeper, which may require some accounts or tools to be set-up. We will inform about these things the week before each session.

+

For Session 1 we recommend to have a GitHub account (https://coderefinery.github.io/installation/github/#github). There will be an optional exercise where you can build a lesson locally. This requires a basic Python environment (https://github.com/coderefinery/sphinx-lesson-template/blob/main/requirements.txt), but do not worry if you cannot or do not want to set up these, there will be plenty of other exercises.

+

Session 2: +In general you will only need your brain for the exercises and discussions. To get the most out of this workshop day we recommend that you join the session with the same computer, display and microphone setup as you would usually use for teaching/ presenting. It may also help to get familar with the different options your computer and Zoom setup provides for screenshare and audio adjustments. +But it is not a must.

+

Session 3: +In general you will only need your brain for the exercises and discussions. If you want to share some “cool gem” in the last episode of this workshop day, please update your registration (link to edit can be found in the registration confirmation e-mail sent by support@coderefinery.org or noreply@neic.org). This is very low barrier, you do not have to be the developer of a tool or technique to share with the group what makes it useful for you; and it does not even have to be cool, sometimes the small “normal” things are the best. You can check out some topics that have been proposed so far in this GitHub issue (#90), you can also comment there if you want to add or change your topic. These will be lightning talk length, so something between 2-5 min depending on how many are interested to share something, but we can collect them all in the collaborative notes for further exploration/reading. +But it is not a must.

+

Session 4: +This upcoming session (session number 4) will cover the technical aspects of CodeRefinery-style online teaching. These topics have never before been covered in this much detail, so if it’s interesting to you, don’t miss it. (You might also want to pass this on to others who are interested in technical production of online events; registration is still open!).

+

First, we talk about why we stream (how we got here, advantages, disadvantages, how to be an instructor in a livestreamed workshop, and what it looks like from a broad level from the production side)

+

Then, we show how we are able to release videos so quickly. This is useful far beyond CodeRefinery, and there are also some hands-on exercises. Come prepared to set up a Python environment and the ffmpeg command line tool if you want to try these.

+

Finally, we see details about how to set up Zoom→Livestream environment for yourself. There isn’t time to do this as a proper exercise, but it’s the starting point and the instructor will offer help after the course for those interested. If you want to try this out during the session, install OBS Studio in advance.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/index.html b/branch/comms/index.html new file mode 100644 index 0000000..5f2b3e4 --- /dev/null +++ b/branch/comms/index.html @@ -0,0 +1,275 @@ + + + + + + + Train the trainer workshop — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Train the trainer workshop

+
+

August/September 2024 CodeRefinery train the trainer workshop

+

Do you teach the use of computers and computational tools? Are you curious about scaling your training and learn about tested and proven practices from CodeRefinery workshops and other trainers? Join us for the CodeRefinery train the trainer workshop: four self-contained sessions on tools and techniques for computational training offer a great chance to enhance your teaching skills and learn about new tools and practices. What you will learn is also used a lot outside CodeRefinery, whenever good beginner friendly training is needed.

+

Learning objectives:

+
    +
  • Learn about tools and techniques and practice to create engaging online teaching experiences (screenshare, audio, etc.).

  • +
  • Become mentally ready to be an instructor in a collaborative interactive online workshop (not only large workshops but in general).

  • +
  • Learn how to design and develop lesson material collaboratively.

  • +
+

Target audience:

+
    +
  • Everyone teaching online workshops about computational topics or interested in teaching.

  • +
  • Previous and future instructors and helpers of CodeRefinery workshops.

  • +
+

Prerequisites: +An interest in teaching.

+

Workshop structure: +We aim for a mix of modular presentations and work in small groups. The latter will be done in breakoutrooms - +be prepared to switch on your camera and have a fruitful exchange with fellow participants!

+

Organizers and instructors:

+

The workshop is organized by partner organizations of the CodeRefinery project.

+

Facilitators and instructors:

+
    +
  • Radovan Bast

  • +
  • Richard Darst

  • +
  • Bjørn Lindi

  • +
  • Dhanya Pushpadas

  • +
  • Jarno Rantaharju

  • +
  • Stephan Smuts

  • +
  • Stepas Toliautas

  • +
  • Samantha Wittke

  • +
+

Content and timing:

+

The workshop consists of four sessions every Tuesday between August +13th and September 3rd 2024, + to +:

+
    +
  • Session 1: About lesson design, deployment and iterative improvement (Aug 13)

  • +
  • Session 2: Tools and techniques adopted in CodeRefinery workshops (Aug 20)

  • +
  • Session 3: About teaching & cool things we all would like to share (Aug 27)

  • +
  • Session 4: Workshop streaming practices and post-workshop tasks (Sep 3)

  • +
+

You can join all sessions, or the just the ones that interest you. More details on each session will be shared later.

+

The workshop is free of charge for everyone, please register below to get the Zoom link and other useful information for the workshop.

+

The workshop is over and registration is closed now.

+

If you have any questions, please write to support@coderefinery.org.

+
+ + + + + +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/lesson-development/index.html b/branch/comms/lesson-development/index.html new file mode 100644 index 0000000..ba986b1 --- /dev/null +++ b/branch/comms/lesson-development/index.html @@ -0,0 +1,424 @@ + + + + + + + Lesson design and development — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Lesson design and development

+
+

Objectives

+
    +
  • We share our design processes for teaching material and presentations.

  • +
  • Learn how to design lessons “backwards”, starting from learning objectives +and learner personas.

  • +
  • Learn good practices for improving existing material based on feedback.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 20 min

  • +
  • Exercises: 35 min

  • +
+
+
+

Exercise: How do you design your teaching material?

+
+

We collect notes using a shared document (5 min)

+
    +
  • When you start preparing a new lesson or training material, where do you start?

  • +
  • What tricks help you with “writer’s block” or the empty page problem?

  • +
  • Maybe you haven’t designed training material yet. But how do you start when creating a new presentation?

  • +
  • If your design process has changed over time, please describe what you used to do and what you do now instead.

  • +
  • What do you know now about preparing lessons/training/presentations that you wish you knew earlier?

  • +
+
+
+
+

Creating new teaching material

+
+

Typical problems

+
    +
  • Someone creates a lesson, but they think about what is interesting to them, +not what is important for the learners.

  • +
  • “I want to show a number of things which I think are cool about +tool X - how do I press these into 90 minutes?”

  • +
  • Write down material you want to cover and then sprinkle in some exercises.

  • +
  • Thinking about how I work, not how the learners work.

  • +
  • Trying to bring learners to their level/setup, not trying to meet the learners +where they are.

  • +
  • Not really knowing the learning objectives or the learner personas.

  • +
+
+
+

Better approach

+

Good questions to ask and discuss with a group of colleagues from diverse backgrounds:

+
    +
  • What is the expected educational level of my audience?

  • +
  • Have they been already exposed to the technologies I am planning to teach?

  • +
  • What tools do they already use?

  • +
  • What are the main issues they are currently experiencing?

  • +
  • What do they need to remember/understand/apply/analyze/evaluate/create +(Bloom’s taxonomy)?

  • +
  • Define learner personas.

  • +
  • It may be an advantage to share an imperfect lesson with others early to +collect feedback and suggestions before the lesson “solidifies” too much. +Draft it and collect feedback. The result will probably be better than +working in isolation towards a “perfect” lesson.

  • +
+
+
+

The process of designing a lesson “backwards”

+

As described in “A lesson design process” in the book Teaching Tech +Together:

+
    +
  1. Understand your learners.

  2. +
  3. Brainstorm rough ideas.

  4. +
  5. Create an summative assessment to know your overall goal.

    +
    +

    [Think of the things your learners will be able to do at the end of the lesson]

    +
    +
  6. +
  7. Create formative assessments to go from the starting point to this.

    +
    +

    [Think of some engaging and active exercises]

    +
    +
  8. +
  9. Order the formative assessments (exercises) into a reasonable order.

  10. +
  11. Write just enough material to get from one assessment (exercise) to +another.

  12. +
  13. Describe the course so the learners know if it is relevant to them.

  14. +
+
+
+
+

Improving existing lessons

+
+

All CodeRefinery lessons are on GitHub

+ +
+

Collect feedback during the workshop:

+
    +
  • Collect feedback from learners and instructors (Example from a past +workshop).

  • +
  • Convert feedback about lessons and suggestions for improvements into issues +so that these don’t get lost and stay close to the lesson material.

  • +
+

Collect feedback before you start a big rewrite:

+
    +
  • First open an issue and describe your idea and collect feedback before you +start with an extensive rewrite.

  • +
  • For things still under construction, open a draft pull/merge request to collect +feedback and to signal to others what you are working on.

  • +
+

Small picture changes vs. big picture changes:

+
    +
  • Lesson changes should be accompanied with instructor guide changes (it’s like +a documentation for the lesson material).

  • +
  • Instructor guide is essential for new instructors.

  • +
  • Before making larger changes, talk with somebody and discuss these changes.

  • +
+
+
+

Use case: our lessons

+

As an example to demonstrate the process of designing and improving lessons, we +will have a look at one of our own lessons: Introduction to version control +with Git.

+
    +
  • Initial 2014-2016 version

    + +
  • +
  • Some time in 2014-2015 attended Carpentries instructor training.

  • +
  • 2016: CodeRefinery started.

  • +
  • 2017: Started a new repository based on the Carpentries lesson template (at the time using Jekyll).

    +
      +
    • Exercises become part of the lesson.

    • +
    • We start in the command line and only later move to GitHub.

    • +
    +
  • +
  • 2019: A lot more thought about learning objectives and personas.

    +
      +
    • Also license change to CC-BY.

    • +
    +
  • +
  • 2022: Convert lesson from Jekyll to Sphinx.

    +
      +
    • Using the tools that we teach/advocate.

    • +
    • We can have tabs and better code highlighting/emphasis.

    • +
    • Easier local preview (Python environment instead of Ruby environment which we were not used to in our daily work).

    • +
    +
  • +
  • 2024: Big redesign. We move the lesson closer to where learners are.

    +
      +
    • Start from GitHub instead of on the command line.

    • +
    • Start from an existing repository instead of with an empty one.

    • +
    • Offer several tracks to participate in the lesson (GitHub, VS Code, and command line) and learners can choose which one they want to follow.

    • +
    • Blog post: We have completely changed our Git lessons. Hopefully to the better.

    • +
    +
  • +
  • Next steps?

    +
      +
    • Making the lesson citable following +our blog post.

    • +
    • Improvements based on what we learn from this workshop.

    • +
    +
  • +
+

The overarching trend was to make the lesson simpler and more accessible - to +meet the learners where they are instead of pulling them to the tool choices of +the instructors. Looking back, we learned a lot and the learning process is +not over yet.

+
+
+

Exercise: Discussion about learning objectives and exercise design

+
+

We work in groups but use the shared document as result (20 min)

+
    +
  1. As a group pick a lesson topic. It can be one of the topics listed here but +you can also choose something else that your group is interested in, or a topic +that you have taught before or would like to teach. Some suggestions:

    +
      +
    • Git: Creating a repository and porting your project to Git and GitHub

    • +
    • Git: Basic commands

    • +
    • Git: Branching and merging

    • +
    • Git: Recovering from typical mistakes

    • +
    • Code documentation

    • +
    • Jupyter Notebooks

    • +
    • Collaboration using Git and GitHub/GitLab

    • +
    • Using GitHub without the command line

    • +
    • Project organization

    • +
    • Automated testing

    • +
    • Data transfer

    • +
    • Data management and versioning

    • +
    • Code quality and good practices

    • +
    • Modular code development

    • +
    • How to release and publish your code

    • +
    • How to document and track code dependencies

    • +
    • Recording environments in containers

    • +
    • Profiling memory and CPU usage

    • +
    • Strategies for parallelization

    • +
    • Conda environments

    • +
    • Data processing using workflow managers

    • +
    • Regular expressions

    • +
    • Making papers in LaTeX

    • +
    • Making figures in your favorite programming language

    • +
    • Linux shell basics

    • +
    • Something non-technical, such as painting a room

    • +
    • Introduction to high-performance computing

    • +
    • A lesson you always wanted to teach

    • +
    • +
    +
  2. +
  3. Try to define 2-3 learning objectives for the lesson and write them down. +You can think of these as “three simple enough messages that someone will +remember the next day” - they need to be pretty simple.

  4. +
  5. Can you come up with one or two engaging exercises that could be used to +demonstrate one of those objectives? +They should be simple enough people can actually do them. Creating simple exercises is not easy. +Some standard exercise types:

    +
      +
    • Multiple choice (easy to get feedback via a classroom tool - try to design each wrong answer so that it identifies a specific misconception).

    • +
    • Code yourself (traditional programming)

    • +
    • Code yourself + multiple choice to see what the answer is (allows you to get feedback)

    • +
    • Inverted coding (given code, have to debug)

    • +
    • Parsons problems (working solution but lines in random order, learner must only put in proper order)

    • +
    • Fill in the blank

    • +
    • Discussions, self directed learning exercises

    • +
    +
  6. +
+
+
+
+

Great resources

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/lesson.pdf b/branch/comms/lesson.pdf new file mode 100644 index 0000000..43f6f0d Binary files /dev/null and b/branch/comms/lesson.pdf differ diff --git a/branch/comms/lessons-with-git/index.html b/branch/comms/lessons-with-git/index.html new file mode 100644 index 0000000..01601a5 --- /dev/null +++ b/branch/comms/lessons-with-git/index.html @@ -0,0 +1,433 @@ + + + + + + + Lessons with version control — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Lessons with version control

+
+

Objectives

+
    +
  • Understand why version control is useful even for teaching material

  • +
  • Understand how version control managed lessons can be modified.

  • +
  • Understand how the CodeRefinery lesson template is used to create new lessons

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 25 min

  • +
  • Exercises or demos: 20 min

  • +
+
+
+

Why version control?

+
    +
  • If you are in CodeRefinery TTT, you probably know what version +control is and why it is important.

  • +
  • The benefits of version control also extend to lessons:

    +
      +
    • Change history

    • +
    • Others can submit contributions

    • +
    • Others can make derived versions and sync up later

    • +
    • Same workflow as everything else

    • +
    • Write it like documentation: probably more reading after than +watching it as a presentation.

    • +
    +
  • +
  • Disadvantages

    +
      +
    • “What you see is what you get” editing is hard

    • +
    • Requires knowing version control

    • +
    +
  • +
+
+

Accepting the smallest contribution

+

Question: if someone wants to make a tiny fix to your material, can they?

+
+
+
+

Tour of lesson templates options

+

There are different ways to make lessons with git. Some dedicated to +teaching:

+ +

Our philosophy is that anything works: it doesn’t have to be just +designed for lessons

+
    +
  • Jupyter Book

    +
      +
    • Example: https://jupyterbook.org/

    • +
    • Note: is based on sphinx, many extensions here are used in CR lessons

    • +
    +
  • +
  • Various ways to make slides out of Markdown

  • +
  • Cicero: GitHub-hosted Markdown to slides easily

    + +
  • +
  • Whatever your existing documentation is.

  • +
+

We like the CodeRefinery format, but think that you should use +whatever fits your needs the most.

+
+
+

Sphinx

+
    +
  • We build all our lesson material with Sphinx

  • +
  • Generate HTML/PDF/LaTeX from RST and Markdown.

  • +
  • Many Python projects use Sphinx for documentation but Sphinx is not limited to Python.

  • +
  • Read the docs hosts public Sphinx documentation for free!

  • +
  • Also hostable anywhere else, like Github pages, like our lesson material

  • +
  • For code a selling point for Sphinx is that also API documentation +is possible.

  • +
+

Sphinx is a doc generator, not HTML generator. It can:

+
    +
  • Markdown, Jupyter, and ReST (and more…) inputs. Executable inputs.

    +
      +
    • jupyter-book is Sphinx, so anything it can do we can do. This was one of the +inspirations for using Sphinx

    • +
    +
  • +
  • Good support for inline code. Much more than static code display, if +you want to look at extensions.

  • +
  • Generate different output formats (html, single-page html, pdf, epub, etc.)

  • +
  • Strong cross-referencing within and between projects

  • +
+
+
+

CodeRefinery lesson template

+

It is “just a normal Sphinx project” - with extensions:

+
    +
  • Sphinx lesson extension

    +
      +
    • adds is various directives (boxes) tuned to lesson purposes

    • +
    • provides a sample organization and template repo you can use so that lessons look consistent

    • +
    +
  • +
  • Sphinx gives us other nice features for free

    +
      +
    • Tabs: they are very important for us and allow us to customize in-place instead of copying everything and fragmenting lessons

    • +
    • Emphasize lines: they make it easier to spot what has changed in longer code snippets

    • +
    • Various input formats

      +
        +
      • Markdown (via the MyST-parser), ReStructured text, Jupyter +Notebooks.

      • +
      +
    • +
    • Many other features designed for presenting and interacting with code

    • +
    +
  • +
  • It’s fine if you use some other static site generator or git-based lesson method.

  • +
+
+

Instructors go through the building and contributing process

+

Depending on the course, instructors will demo what is roughly +exercise 4 below. Or a course might go straight to exercises.

+
    +
  • Instructors decide what change they would want to make

  • +
  • Instructors clone the repository

  • +
  • Instructors make the change

  • +
  • Instructors set up the build environment

  • +
  • Instructors build and preview

  • +
  • Instructors command and send upstream

  • +
+
+
+
+

Exercises

+

Some exercises have prerequisites (Git or Github accounts). Most +instances of this course will have you do 1 and 2 below.

+
+

Lesson-VCS-1: Present and discuss your own lesson formats

+

We don’t want to push everyone towards one format, but as long as you +use Git, it’s easy to share and reuse.

+
    +
  • Discuss what formats you do use

  • +
  • Within your team, show examples of the lessons formats you use +now. Discuss what is good and to-be-improved about them.

  • +
  • Look at how they source is managed and how easy it might be to edit.

  • +
+
+
+

Lesson-VCS-2: Tour a CodeRefinery or Carpentries lesson on Github

+
    +
  • Look at either a CodeRefinery or Carpentries lesson

    + +
  • +
  • Can you find

    +
      +
    • Where is the content of the lessons?

    • +
    • What recent change propsals (pull requests) have been made?

    • +
    • What are the open issues?

    • +
    • How you would contribute something?

    • +
    • How would you use this yourself?

    • +
    +
  • +
+
+
+

Lesson-VCS-3: Modify a CodeRefinery example lesson on Github

+

In this, you will make a change to a lesson on Github, using only the +Github interface. (Github account required, and we assume some +knowledge of Github. Ask for help in your team if it is new to you!)

+
    +
  • Navigate to the example lesson we have set up: +repo, web

  • +
  • Go to some page and follow the link to go to the respective page on +Github. (Alternatively, you can find the page from the Github repo directly).

  • +
  • Follow the Github flow to make a change, and open a Pull Request +with the change proposal:

    +
      +
    • Click on the pencil icon

    • +
    • Make a change

    • +
    • Follow the flow to make a commit and change. You’ll fork the +repository to make your own copy, add a message, and open a pull +request.

    • +
    +
  • +
+

We will look at these together and accept some changes.

+
+
+

Lesson-VCS-4: Clone and build a CodeRefinery lesson locally

+

In this exercise, you will use Git to clone one a CodeRefinery lesson +and try to preview it locally. It assumes installation and knowledge +of Git.

+
    +
  • Use this sample repository: +git-intro (or whatever +else you would like)

  • +
  • Clone the repository to your own computer

  • +
  • Create a virtual environment using the requirements.txt +contained within the repository.

  • +
  • Build the lesson.

    +
      +
    • Most people will probably run: sphinx-build content/ _build/

    • +
    • If you have make installed you can make html

    • +
    • Look in the _build directory for the built HTML files.

    • +
    +
  • +
+

Overall, this is pretty easy and straightforward, if you have a Python +environment set up. The CodeRefinery documentation +lesson teaches +this for every operating system.

+

This same tool can be used to build documentation for other software +projects and is pretty standard.

+
+
+

Lesson-VCS-5: (advanced) Create your own lesson using the CodeRefinery format

+

In this lesson, you’ll copy the CodeRefinery template and do basic +modifications for your own lesson.

+
    +
  • Clone the lesson template: +https://github.com/coderefinery/sphinx-lesson-template

  • +
  • Attempt to build it as it is (see the previous exercise)

  • +
  • How can you do tabs?

  • +
  • How can you highlight lines in code boxes?

  • +
  • How can you change color, logo and fonts?

  • +
  • What directives are available?

  • +
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Version control takes teaching materials to the next level: +shareable and easy to contribute

  • +
  • There are different formats that use version control, but we like +Sphinx with a sphinx-lesson extension.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/notes-archive/index.html b/branch/comms/notes-archive/index.html new file mode 100644 index 0000000..084aa0b --- /dev/null +++ b/branch/comms/notes-archive/index.html @@ -0,0 +1,2862 @@ + + + + + + + Collaborative notes archives from workshops — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Collaborative notes archives from workshops

+
+

August/September 2024

+
+

Day1: Session 1 (13.08.24) - About lesson design, deployment and iterative improvement

+
+

:calendar: Schedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 10.00

Lesson design and development

10.15 - 11.00

8.15 - 9.00

10.00 - 10.15

Break

11.00 - 11.15

9.00 - 9.15

10.15 - 11.00

Lessons with version control

11.15 - 12.00

9.15 - 10.00

11.00 - 11.15

Break

12.00 - 12.15

10.00 - 10.15

11.15 - 12.00

How we collect feedback and measure impact

12.15 - 13.00

10.15 - 11.00

+
+
+

:icecream: Icebreaker

+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :Decaffed … and going strong …

  • +
  • :coffee: 🤔

  • +
  • :100: (ironically!) :coffee: intake happening

  • +
  • :smile:

  • +
  • :tired_face:

  • +
  • :coffee: :party:

  • +
  • :coffee: :happy:

  • +
  • 😪

  • +
  • just got zoom installed / before my coffee

  • +
  • :smil-

  • +
  • :sweat_smile: (+)

  • +
  • :yawning_face:

  • +
  • :is it morning already?

  • +
  • :smile:

  • +
  • :yawning_face:

  • +
  • :nerded_face:

  • +
  • 🥵

  • +
  • :smile:

  • +
  • :sleeping:

  • +
  • :sleepy: :coffee: :smiley_cat:

  • +
  • 🥳

  • +
  • :coffee:

  • +
  • :coffee:

  • +
+
+
+
Introduction in breakoutrooms.
+
    +
  • Name / Affiliation / Location

  • +
+
+
+
About teaching
+

What is the hardest thing about teaching for you?

+
    +
  • Knowing how “it’s going”, whether learners are happy or not (especially when teaching online) :+1:

  • +
  • The preparation the night before. It is always much more that I would hope, no matter how prepared I want it to be :+1: :+1:

  • +
  • Managing groups with vastly different academic backgrounds

  • +
  • Teaching wide spectrum of skill level at the same time. :+1: :+1: :+1: :+1:

  • +
  • Time management! (Knowing how much can fit in a sessions) :+1: :+1:

  • +
  • General preparation time, how to fit it into the regular work schedule, and estimate how much time is needed for prep.

  • +
  • How to reduce too much text into just the right amount

  • +
  • Preparation of the session material and estimating the right amount of time for each section

  • +
  • Getting learners to take the first step: sign up for and attend a workshop, when they don’t think programming is a skill they can learn

  • +
  • Getting learners to take the second step: translating what they’ve learned in a workshop into something they can apply

  • +
  • preparation and time management

  • +
  • Engaging with the students which was much easier for me when I used to coach

  • +
  • Finding the right depth for an unknown audience for “my topic”

  • +
  • education background of participants and their learning objectives

  • +
+

What is the best thing about teaching for you?

+
    +
  • Seeing when learner gets interested/curious about something and takes inspiration from the course. :+1:

  • +
  • Seeing it works and someone can do something new.

  • +
  • Motivated students grasping new stuff

  • +
  • Students picking up and running with the matertial and skills I give them and using it for their own work. :+1:

  • +
  • The “ah-ha!” moment when a student gets it! :+1::100: :+1:

  • +
  • Learning from students who know about some topic more than you do. :+1:

  • +
  • Being able to help people reach their goals, by showing them something new.

  • +
  • Teaching is optimism acted out in the hope of making a difference both ways I suppose.

  • +
  • The feeling of accomplishment when you see learning grow and implement the learnings :book:

  • +
  • mutual learning and impact on learners :+1:

  • +
  • Results and feedbacks / Mutual interests and interesting discussions

  • +
  • mutual learning and I can also learn lots of things and new ideas from participants

  • +
+
+
+
+

:question: Questions

+
+
General / Practicalities
+
    +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms? I’m not in a place where I can talk, so if we’re going to talk a lot I’ll need to move offices

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    +
  • +
  • +
+
+
+
Episode 1: Lesson design and development
+

Materials: https://coderefinery.github.io/train-the-trainer/lesson-development/ +Discussion:

+
    +
  • When you start preparing a new lesson or training material, where do you start?

    +
      +
    • I look at existing materials on the same topic, but chose/refine topics based on the perceived needs/interests of the presumed audience

    • +
    • Outline of structure and Material collection for a new lesson :+1:

    • +
    • What material I have already? (what other material is already out there?)

    • +
    • Start by looking for related resources (documents, videos, courses, etc) to have a base data and better understanding of what have been done around the topic

    • +
    • Know your audience

    • +
    • Review existing material

    • +
    • Think about learning objectives (to keep focus on essential things)

    • +
    • Think of three things simple enough that they will be remembered the next day. Design around that.

    • +
    • I write down the thoughts that I have and then go back and structure it.

    • +
    +
  • +
  • What tricks help you with “writer’s block” or the empty page problem?

    +
      +
    • Write anything down that comes to mind, sometimes draw something, looking out the window :)

    • +
    • Do a mind map - what concepts do I want to get across?

    • +
    • Starting small, for example a list of headings and then building around it. :+1:

    • +
    • What does one know about the target audience and why should they be spending longer than 1 minute listening to what they will eventually get to hear?

    • +
    • Get some inspiration from another source.

    • +
    • Start with the three things above

    • +
    • Start with the plan and the overview design

    • +
    • Some kind of outline / main message(s)

    • +
    • Start with three things. Three supporting points for each of these.

    • +
    +
  • +
  • Maybe you haven’t designed training material yet. But how do you start when creating a new presentation?

    +
      +
    • Think about the learning objectives and try to break them down into steps

    • +
    • Title, Objectives, target audience and Plan

    • +
    • Some kind of outline / main message(s). Get as many images as I can, instead of words

    • +
    • Draft an outline and use chatgpt to fill in details

    • +
    • Example of how the teaching content is applied in a real-world context

    • +
    +
  • +
  • If your design process has changed over time, please describe what you used to do and what you do now instead.

    +
      +
    • I look more at existing materials and try to get more information about the audience. Unfortunately getting information about the audience before the event is hard

    • +
    • I used to start from the begginning and get from there but that often meant a very polished start and a rushed end. Now I try an overview first, then fil out sparsed details at every section

    • +
    • Updating the data and tweak the presentation

    • +
    • If I am teaching a small group (or one to one) talk to them before hand - find out what they know already, what they want to learn.

    • +
    +
  • +
  • What do you know now about preparing lessons/training/presentations that you wish you knew earlier?

    +
      +
    • less is more. It’s better to have 2-3 main messages rather than trying to show everything in one go :+1: :+1: :+1: :+1:

    • +
    • how much practice time the learners need to master what’s taught

    • +
    • Don’t worry about something going wrong. It often makes the lesson (and thus the material) more presistent in memory. :+1:

    • +
    • Try and remove everything except what you want the person to learn

      +
        +
      • That’s a very tough part for me in the sense that I never know how much of an underlying “black box” is still ok….

      • +
      +
    • +
    • Designing intermediate materials is hard, and requires putting some “gatekeeping” making sure that learners are directed to appropriate courses

    • +
    • When I see a cool graphic, concept, slide, etc., download it and save it in my ‘new-materials’ folder to use later on!

    • +
    • I have come to the conclusion that perhaps a more “agile” approach to developing materials (try to do design/teaching iterations quickly) might be the best way to go, but there are risks with this approach too

    • +
    +
  • +
+

Questions

+
    +
  • From zoom chat: Can you expand on what a learner persona is?

    +
      +
    • A defined example person described in terms of the materials you are preparing, making up a story about the background and interest of t

    • +
    • Answer from chat: A learner persona is a blackbox which has a very simple algorithm inside: GIGO.

    • +
    • Answer from chat: I think it’s the same as ICP (Ideal customer persona) where you describe the learner as a customer

    • +
    • Answer from chat: I’m a big fan of “How Learning Works” by Ambrose et al https://bookshop.org/p/books/how-learning-works-eight-research-based-principles-for-smart-teaching-michele-dipietro/18640868?ean=9781119861690

    • +
    • See also book: Teaching tech together

    • +
    +
  • +
+
+

CodeRefinery lessons: https://coderefinery.org/lessons/

+
+
    +
  • From chat: Do you have an example of an instructor guide?

    + +
  • +
  • From zoom chat: Do you have a “measure” of how better are the new lesson compared to the old ones? Does it make sense to talk about measurements here?

    +
      +
    • So far we only have daily feedback that we collect at the end of the day and we can compare that to earlier daily feedbacks. More about that in the last episode of today. But measuring this is indeed not easy and it also takes time to capture the effect during longer-term surveys. Some of the changes were more leap-of-faith than based on data.

    • +
    • I guess that sometimes one can use “compelling arguments” instead of data to justify a decision

    • +
    +
  • +
  • Software Carpentry does teach using the command line, and gives a session on the command line before. What do you think about this approach? Are you stating that a 3-hour lesson about CLI is not sufficient to make people comfortable enough to use that for version control?

    +
      +
    • Yes, good question. For CR we consider it a more advanced step: we do think people should learn command line, but it’s for a different course. We accept some people might not know it or want to know it so adapt to that.

    • +
    • In general, we’ve found the “you need X, but have to learn A, B, and C first” approach should be avoided if possible: people are busy, try to reach people where they are.

    • +
    +
  • +
+
+

Exercise in breakoutrooms

+
+
    +
  • Room 1

    +
      +
    • Research data management

    • +
    • Objectives

      +
        +
      • Research life cycle

      • +
      • FAIR principles (Findable, Accessible, Interoperable, Reusable)

      • +
      +
    • +
    • Exercise

      +
        +
      • develop a data management plan (DMP) that outlines how their research data will be handled throughout its lifecycle.

      • +
      +
    • +
    +
  • +
  • Room 2: What is the difference between eating breakfast and sitting through a lecture? (Tip: Start by listing the similarities …)

  • +
  • Room2 : Making papers in LaTeX +- What is LaTex and how is it different from editors like Word +- Basic Structures +- How to find and use a template +- Including figure & table +- How to use references and labels +- Exercise: to create a new LaTeX document & edit it +- Excercise: common error messages: can you find the error in this code? +- Exce

  • +
  • Room 3

    +
      +
    • GPU Programming (1 hour intro)

    • +
    • Learning objectives:

      +
        +
      • What is GPU programming.

      • +
      • When is it usable, beneficial to use GPU programming?

      • +
      • What are technologies to do GPU programming?

      • +
      • [What are and how to manage typical issues]

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • Git / Figures / Project management / data cleaning

    • +
    • Chose data cleaning

    • +
    • Three learning objectives:

      +
        +
      1. What do we mean by “clean”? How to identify it?

      2. +
      3. Identify some common problems in a dataset

      4. +
      5. Identifying and handling missing values/fields

      6. +
      +
    • +
    • Exercise

      +
        +
      1. Discuss problems, find the most common ones

        +
          +
        • In small groups

        • +
        • What problems have you run into with datasets you’ve worked with?

        • +
        • What problems can you imagine, or have you heard about from colleagues/news/social media?

        • +
        • Report back, instructor collects all problems into a list

        • +
        +
      2. +
      3. Have a dataset to clean; a clean and a messy example

        +
          +
        • (identifying) Using a visualisation or overviewing tool?

        • +
        +
      4. +
      +
    • +
    +
  • +
  • Room 5

    +
      +
    • Jupyter Notebooks

    • +
    • Learning Objectives

      +
        +
      • Can setup an enviroment you can reuse / can share with others / a project.

      • +
      • The order you run the commands in needs to match the order of the code in the Notebook - otherwise you end up in a pickle.

      • +
      • Why use a Jupyter Notebook? What are the advantages? Easy to use environment.

      • +
      +
    • +
    • Exercise

      +
        +
      • Print variable assignments from different cells - show that the order you run the code is important.

      • +
      • hand out a domain specific notebook that does some calculations and visualization to run and modify, to show that you can share easily

      • +
      • show !pip install to add dependencies/features

      • +
      +
    • +
    +
  • +
  • Room 6

    +
      +
    • Using GitHub without the command line

    • +
    • Learning Outcomes:

      +
        +
      • Be able to discuss changes before merging changes into the main repository.

      • +
      • Publish a personal repository page ( I think its called intro repository)

      • +
      • Share their script/notebook/code/small data on GitHub

      • +
      • Homepage using GitHub pages or the README that becomes the “index page” of the GitHub user account page

      • +
      +
    • +
    • Learner personas:

      +
        +
      • Check the Personas of the learners

        +
          +
        • Somebody who has seen/heard of GitHub but hasn’t used it yet

        • +
        • Someone using it for their own work but struggling with collaboration

        • +
        +
      • +
      +
    • +
    • Exercises:

      +
        +
      • Upload/share an example dataset or script

      • +
      • Review another collaborators pull request.

      • +
      • Take part in the discussion on a pull request.

      • +
      +
    • +
    +
  • +
  • Room 7 +Linux shell basics: why do we want to teach them? +(this took most of the time for the discussion)

    +
      +
    • Learning objectives:

      +
        +
      1. Filesystem: Directory (CLI) - Folder (GUI) analogy

      2. +
      3. Basic commands (which commands are basic? make a survey of shell histories and get the most common ones)

      4. +
      5. Basic constructs (e.g., for loops, pipes, while loops… which ones are basic? See above)

      6. +
      +
    • +
    +
  • +
+
+

Note from chat: Zoom timer: https://support.zoom.com/hc/en/article?id=zm_kb&sysparm_article=KB0068677

+
+
+
+
Episode 2: Lessons with version control
+

Materials: https://coderefinery.github.io/train-the-trainer/lessons-with-git/

+

Poll options: I want to hear about:

+
    +
  • A: Why use version control for teaching materials

  • +
  • B: Different template options

  • +
  • C: How CodeRefinery does it; CodeRefinerys lesson template

  • +
+

Poll vote (multi-select): add a o to your answer +- A: ooo +- B: oooooo +- C: oooooooo :ghost:

+

Question to audience: if someone wants to make a tiny fix to your material, how hard is it?

+
    +
  • If my material is only in pdf format which is not online, then it is hard.

  • +
  • I hope it is easy - my material is in GitHub. Nobody has ever done that though!

  • +
  • Slides: hard to find, easy to edit; Git repos somewhat easy, unless they have to be built locally or with an action; HackMD easiest to edit.

    +
      +
    • if you use something like google slides they are not that difficult to find

    • +
    • known permanent address. Google docs et al fail on that/same for many pads.

    • +
    +
  • +
  • For this material today - very easy! e.g. https://github.com/coderefinery/train-the-trainer/pull/128

  • +
  • Template with an edit button in the HTML pointing to the source-code in the repo.

  • +
+

Questions/Discussion topics

+
+

Upcoming CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/ +Please share with your networks, and let us know if you would like to co-teach a lesson (to support@coderefinery.org or in our Zulip chat)

+
+
    +
  • Changes to the material are sometimes not just tiny fixes. For example, one wants to present a slightly different selection of topics, but maybe some topics are “coupled” (perhaps naturally or perhaps just because of how they are presented), or change the general “theme” (e.g., life sciences vs theoretical physics) while keeping the actual topics the same. How could a lesson be developed to avoid having to do a huge rewrite?

    +
      +
    • You can try to modularize your material and keep non topic specific parts non themed. E.g. where you explain the functionality, don’t make reference to the example (not simple), so the example can be changed depending on the audience.

    • +
    +
  • +
  • What are the pros/cons of renaming a course / changing a repo name in GitHub?

    +
      +
    • It should be relatively unproblematic since GitHub will forward to the new name.

      +
        +
      • How long does Github keep the “old” name linked? Is there a max time it’s blocked, or changed as soon as a new one appears with the name?

        +
          +
        • in my experience it forwards “forever” until I create a new repo with the old name which will break the forward

        • +
        +
      • +
      +
    • +
    +
  • +
  • what should be in the readme for the git repo? (canonical address? contact points? license!)

    +
      +
    • https://coderefinery.github.io/mini-workshop/2/documentation/#often-a-readme-is-enough-checklist

      +
        +
      • I miss the url to the (main) repo in the readme

        +
          +
        • Do you mean the link to the rendered (lesson) page?

        • +
        +
      • +
      +
    • +
    • Link to rendered page: We often have this in the “about” section of the readme (see up right: https://github.com/coderefinery/train-the-trainer)

    • +
    • this gets lost in a fork, doesn’t it? so 20 folks forking and or reuploading the repo somewhere means the url gets lost?

      +
        +
      • True, but they might want to have their own version rendered?

        +
          +
        • yes, I have had issues finding and contributing to the “master” repo so all benefit. Else it gets cluttered. Both is valid

          +
            +
          • Good point though, the link to rendered page should probably also be included in the readme for completeness; ah and the link to the repository too, yes

            +
              +
            • so realistically we need a content folder and some more next to the readme as a best practice. sounds good!

            • +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • Is myst (markdown renderer) enabled by default in sphinx now?

    +
      +
    • to my knowledge no. we add the “myst_parser” extension to conf.py.

    • +
    +
  • +
+
+

Cicero: https://cicero.readthedocs.io/ +Sphinx documentation: https://www.sphinx-doc.org/en/master/ +Carpentries workbench for creating Carpentries lessons: https://carpentries.github.io/workbench/ +This is the testing lesson Richard showed: https://coderefinery.github.io/testing/ +And the corresponding repository: https://github.com/coderefinery/testing +You can lean back and watch, exercise coming in a bit :) +Richard will now edit our train the trainer material repository: https://github.com/coderefinery/train-the-trainer +The Sphinx extension for CodeRefinery lessons: https://github.com/coderefinery/sphinx-lesson +Empty lesson template to build your own lesson: https://github.com/coderefinery/sphinx-lesson-template

+
+

More questions

+
    +
  • Does the coderefinery.org page built on sphinx?

    +
      +
    • It’s built also from markdown but it uses https://www.getzola.org/ (which is more optimized to render websites, but we could do teaching also with Zola or create the project page using Sphinx)

    • +
    +
  • +
  • Is there a way to build and preview CR lessons without the command line?

    +
      +
    • The GitHub workflow we use creates HTML from all branches. This means that one can push a branch to GitHub, preview it there, and then open a pull request. One thing that would be nice but we don’t have yet is if a bot automatically posts the link to the preview to a pull request.

    • +
    +
  • +
  • For VCS-2, for the Carpentries Linux shell example, Lesson, Github repo, to me it seemed as though the Sandpaper setup they have makes a very nice interface, complicates the relationship between source and output. E.g on the soucre page https://github.com/swcarpentry/shell-novice/blob/main/index.md I could only see to ‘Prerequisits’ and not ‘Download files’ on the page https://swcarpentry.github.io/shell-novice/. Perhaps I have missed something?

    +
      +
    • I am sorry I don’t know the new Sandpaper setup well enough to answer this question.

    • +
    +
  • +
  • Do we have the instructions to build the lessons available somewhere to try out later?

    +
      +
    • https://github.com/coderefinery/sphinx-lesson

    • +
    +
  • +
+
+

Exercise VCS-1 (and VCS-2 (if time)) (https://coderefinery.github.io/train-the-trainer/lessons-with-git/#exercises) in breakoutrooms until xx:05

+

then short summary in main room and then break.

+

Use the notes below. Collect a list of lesson formats and discuss what you like about each of them.

+
+
    +
  • PDF slides by a presentation program

  • +
  • pdf slides with beamer in latex under source control.

  • +
  • Markdown slides via Github

  • +
  • CodeRefinery template

  • +
  • Carpentries template

  • +
  • Google Slides

  • +
  • git-book

  • +
  • Jupyter Book - allows creating a structured reference website using RST/Markdown, including Jupyter Notebooks to show result of running code

  • +
  • mdbook - create simple/minimal website using Markdown

  • +
  • Binder - allows learners to run their own live version of a github repository with Jupyter Notebooks, with only a web browser

  • +
  • Jupyter notebooks and jupyterhub platform

  • +
  • Jupyter + Nbviewer and custom css (read only) + Binder link (hands on)

  • +
  • RMarkdown

  • +
  • Quarto Slides

  • +
  • Reveal.js - write slides in HTML (also supports markdown)

    +
      +
    • Example: https://bl-presentations.erambler.co.uk/2024-02-21-idcc24/

    • +
    +
  • +
  • Remark.js - write slides in markdown

    +
      +
    • Example: https://bl-presentations.erambler.co.uk/2024-02-19-idcc-pids-workshop/

    • +
    +
  • +
+

Room discussions:

+
    +
  • Room 1

    +
      +
    • (https://smc-aau-cph.github.io/SPIS/README.html)

    • +
    • CodeRefinery template

    • +
    • Shared notes & blogs

    • +
    +
  • +
  • Room 2

    +
      +
    • demo the exercise

    • +
    +
  • +
  • Room 3

    +
      +
    • Mix of JupyterLab, Terminal within that, and traditional slides

    • +
    • Jupyter + RISE (benefit: slides that are editable and executable live)

    • +
    • Challenges

      +
        +
      • present code in an interactive way

      • +
      • handle lots of images/ figures without too much additional overhead when setting up the material

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • Material and tools depend on instructors

    • +
    • Some slide building tools

      +
        +
      • https://revealjs.com/

      • +
      • https://remarkjs.com/

      • +
      • https://github.com/rust-lang/mdBook

      • +
      +
    • +
    • Using flat git repos without fancy styling to make it easier to edit but still version controlled

    • +
    +
  • +
  • Room 5

    +
      +
    • Using R as a GIS: https://github.com/nickbearman/intro-r-spatial-analysis

      +
        +
      • Workbook: RMarkdown, Slides: Quarto

      • +
      • No continuous intergration

      • +
      +
    • +
    • Having a jupyter nbinder link to test the notebook

    • +
    • repo lives on codeberg in this example

    • +
    +
  • +
  • Room 7

    +
      +
    • Ex 1:

      +
        +
      • Sphinx, similar to CR

      • +
      • Sometimes pdfs generated with beamer package (or from pptx and odt), but blows up repository size if in version control

      • +
      +
    • +
    • Ex 2:

      +
        +
      • Content

        +
          +
        • CR: Content commonly found int the content folder

        • +
        • SC: Mostly under episodes

        • +
        +
      • +
      +
    • +
    • Question that came up:

      +
        +
      • is CR/Sphinx approach mostly for technical topics? What about language.

      • +
      • I guess by our nature it’s focused there. But probably could be used for others (I guess it it’s much easier to use git in a technical audience.)

      • +
      +
    • +
    +
  • +
+
+
+
Episode 3: How we collect feedback and measure impact
+

Materials: https://coderefinery.github.io/train-the-trainer/feedback-and-impact/

+

Questions to audience

+
    +
  • What tricks/techniques have you tried in your teaching or seen in someone else’s teaching that you think have been particularly effective in collecting feedback from learners?

    +
      +
    • preparing a survey and emailing it to participants as soon as the event ends (usually get <50% of answers but it’s a representative enough sample)

    • +
    • do engage with the audience, give them the time to get the courage to speak up

    • +
    • Be the audience yourself

      +
        +
      • yes! some problems/issues I don’t notice as instructor, only as listener

      • +
      +
    • +
    • Have time (e.g. 5 min) in the session to fill out the feedback form

    • +
    • If the course/workshop has several days/sections do a couple questions every change, then a full one afterwards

    • +
    • “Traffic light” feedback (e.g. for pacing or progress on exercises): give each learner two different coloured post-it notes for in-person, or use emoji for online, to indicate a current status

    • +
    +
  • +
  • Can you give tips or share your experiences about how to convert feedback into changes or actionable items?

    +
      +
    • ask questions about things you know you don’t know

    • +
    • “Don’t let the noise of others’ opinions drown out your own inner voice.” — Steve Jobs

    • +
    +
  • +
  • When people ask questions / get stuck with a specific step. Is there a typo I can change there and then in the workbook?

    +
      +
    • Being able to fix small things on the fly helps sometimes, otherwise open issues if working on github

    • +
    • If multiple people have the same question, then this is an indication that I should look at this in more detail

    • +
    +
  • +
  • How do you measure the impact of your teaching? Any tips or experiences about what you have tried or seen other courses do?

    +
      +
    • “How likely are you to recommend this workshop to others? (0/5)”

    • +
    • Check the ‘Garbage Out’ bin, what you find there will be what went across. The rest will be history…

    • +
    +
  • +
  • Anybody knows of good resources on survey design? Please link them here.

    +
      +
    • “Our job is to figure out what they’re going to want before they do… Our task is to read things that are not yet on the page.” - Steve Jobs

    • +
    +
  • +
+

Questions/Discussion points

+
    +
  • Feedback is necessary to design good lessons. Improvement can only be done iteratively. So the faster the iteration (design/teach), the better. But on the other hand, I cannot constantly bomb our community with training event emails. So I would like to try proposing a course many times a year, but I don’t want to spam everybody many times a year.

    +
      +
    • :+1:

    • +
    • With CR we also have a calendar that can be imported to different calendar applications, where we add all workshops: https://github.com/coderefinery/calendar/

    • +
    +
  • +
  • Does an even split of too fast / too slow mean speed is about right?!

    +
      +
    • I take it to mean “it’s roughly where it should be”. Would be better to accomdate the sides better though… (we do try to design for a broad audience: some easy stuff, some advanced stuff, so people can make their own path)

    • +
    • It could also indicate that the prerequisites/scope are not well defined :+1:

      +
        +
      • Based on long term surveys we also know though that even though the workshop might have been to fast, people appreciate having “heard things before and know where to find them later”

      • +
      +
    • +
    • perhaps the even split between too fast/too slow is ok only if the majority of votes goes for “just right” :+1:

    • +
    +
  • +
  • One of the most important disciplines in journalism is to challenge your working premises. (Bill Keller) This applies equally to learning as well.

    +
      +
    • Participants can be encouraged to write some posts on LinkedIn. If it is helpful some blurbs can be created for pre and post-workshop to generate more traction for Code Refinery and future participation.

    • +
    • Ask participants if they use Dev.to, hashnode etc to blog their work or use twitter etc to have a memory of their work.

    • +
    +
  • +
  • Do you have any suggestions for prerequisites? I try to make them clear, but occasionally people attend who clearly do not meet them. :+1:

    +
      +
    • I guess it depends how much it matters for the workshop itself. If you have group exercises etc, it probably matters? , lecture style maybe not so much?; important is that the participants themselves know that prerequisites exist and if they meet them

    • +
    • Sometimese people that do not meet the prerequisites join to get to “know what they don’t know”, find out where to find information on topics they might get interested in future etc

    • +
    • Other suggestions? Viewpoints? :)

    • +
    • Thank you - things for me to think about there :-)

    • +
    • With CR’s latest ideas, we try to make the prerequisites clear, but there is no capicity limit: it’s OK if people drop by and are less than prepared: it’s livestream, anyone can come. We try to have something for these people, too: learn what you are missing, why you might want to study more in the future.

    • +
    • Any thoughts on applying this to a more practical focused course, with a total capacity limit (i.e. not like CodeRefinery).

    • +
    +
  • +
  • Everytime you do a course on CodeRefinery, think of it as trying to bake a new cake with an old recipe with no idea about the individual taste preferences of the one you bake the cake for. Then, you will not experience too many surprises. Fine-tuning the recipe for one cohort still remains the ‘old recipe’ as far as the next ‘new cohort’ will be concerned. C’est la vie.

    +
      +
    • nice analogy!

    • +
    +
  • +
  • Question from chat: For examples 2 & 4, would you also consider using something like a Likert scale? E.g. Rate how well you agree with the statement “My code is more reusable as a result of attending a CodeRefinery workshop” (from 1 Strongly disagree to 5 Strongly agree)

    +
      +
    • Thanks! I am new to Likert scale and will read up on it. In my experience numbered answers can be useful for reporting. But I also like questions where we ask for what actually to change.

    • +
    +
  • +
  • Comment from chat: Richard, your point crowns the point of having CodeRefinery, With Radovan’s and Samantha’s acquiescence assured, I would like to suggest you wear a crown going forward, especially for the CodeRefinery session. Do we have a deal ?

    +
      +
    • I don’t quite understand this

    • +
    • I think it’s a tongue-in-cheek-comment (joke) but I am not sure…..

    • +
    +
  • +
  • What is the ideal way to allow people to interact while course is going on in the main online session, i.e. without a breakout room? Taking a pause or discussion in the background?

    +
      +
    • I’ve had some success with WhatsApp groups for a course - particually ones that run over 4 (or 2) sessions.

    • +
    • A quick survey/quiz

    • +
    • Question to the audience that we take time to answer but it helps to show the answers

    • +
    +
  • +
+
+
+
+
+
+

Wrapup

+
    +
  • Thank you for active participation :)

    +
      +
    • We’ll continue answering questions after the workshop and make the cleaned up (no names etc) available from the materials

    • +
    +
  • +
  • Next session Tuesday August 20, 9 CEST: Tools and techniques adopted in CodeRefinery workshops

    +
      +
    • we will talk about on-boarding, install help, roles, screensharing, sound, collaborative notes

    • +
    +
  • +
  • All workshop materials will stay available (after the full workshop also on Zenodo :tools:)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • If you want to co-teach with us in the upcoming (or next) CodeRefinery workshop (https://coderefinery.github.io/2024-09-10-workshop/); or just want to learn more about this opportunity: Send your name and e-mail address to support@coderefinery.org; we will contact you!

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • Lesson design approach

  • +
  • I liked the backwards lesson design, gives a name to a practice I’ve already been doing :+1: :+1:

  • +
  • Lessons from code refinery on lesson design. Learning about Sphinx.

  • +
  • Collaborative notes and anonymized archive of notes.

  • +
  • it’s nice to have a community to discuss these kinds of problems

  • +
  • Hearing the variety of tools people use for slides (PDF, Quarto, Beamer etc.)

  • +
  • Good intro of the tools, the jargon and the pedagogical philosophy of teaching tech.

  • +
  • The absolute openess in having everything publicly available - materials ofc but also questions, discussions, feedback, …

  • +
  • Thinking about all content being available publicly and as a git repo

  • +
  • Thanks for explaining the HedgeDoc interface, with view and edit options

    +
      +
    • Is there anyway to come back to this document later (e.g. tomorrow) and see what has changed since now? So I can see if any other questions have been asked/answered?

      +
        +
      • There is a “revision” point under “Menu” up right, which shows you different versions of this document

      • +
      +
    • +
    +
  • +
  • Modesty: the gentle art of enhancing your charm by pretending not to be aware of it. - Oliver Herford

  • +
  • +
+

What one thing would you improve about this session?

+
    +
  • Perhaps some more interactivity but can be hard to plan and time

    +
      +
    • We’ll see what we can do.

    • +
    +
  • +
  • Maybe mix the breakout groups up for each breakout session (although there are advantages to consistency too) :+1:

    +
      +
    • yes, pros and cons! For me, having consistency worked well this time.

    • +
    • Likely we will have different participants next week, and a bit of mixing will happen naturally.

    • +
    +
  • +
  • The pace of the presentations could be a little tighter (the pace is good for a discussion though)

  • +
  • Richard’s voice was only 80% audible

    +
      +
    • Sorry to hear that. It seemed fine on my end. Will check better for next session.

    • +
    +
  • +
  • Hands on simulation and collaborative notes

  • +
  • I found it difficult to follow the presentation and the collaborative notes at the same time

    +
      +
    • We will highlight the collaborative notes more in the next session. Our strategy usually is to say to focus on the “teaching part” and use the notes only when needed. Since you can go back and also check the notes later.

      +
        +
      • My problem is that I want to follow both since I don’t want to miss out on anything. As such, I have both windows (zoom and the notes) open side-by-side. Since there is near-constant real-time typing in the editor, and as such visible movement on screen, I get constantly distracted. This makes following the event quite exhausting.

      • +
      +
    • +
    +
  • +
  • Heads up to participants on using the break out rooms on voice interaction and screen sharing.

    +
      +
    • Do you mean that we should have mentioned it more clearly in the pre workshop email?

    • +
    +
  • +
  • I found it hard to follow with so many things going on at once…

    +
      +
    • A collaborative document being changed at the same time as…

    • +
    • Someone speaking and explaining content at the same time as…

    • +
    • Chat in a different application at the same time as…

    • +
    • Content changing in a termin application.

      +
        +
      • Thank you for the feedback. We will remove the Zoom chat out for the next session and explain the use of the collaborative notes more.

      • +
      +
    • +
    +
  • +
  • Make more use of defining and then making sure the learning objectives are met

    +
      +
    • True we did not talk about them much, will pick that up better for next session.

    • +
    +
  • +
  • UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. - Dennis Ritchie. You need to do a lot to prove that to be wrong, simply put.

  • +
  • Allocate some time for learners to type in the answers so that we don’t have to listen and type at the same time.

  • +
+

Any other comments?

+
    +
  • It’s great to hear other people’s experience

    +
      +
    • Good to hear :)

    • +
    +
  • +
  • Looking to meet you onsite if there are any events and get more emails from you :)

    +
      +
    • We will keep you informed :)

    • +
    +
  • +
  • Thanks for putting this together, I got a lot of inspiration for my own courses

    +
      +
    • Good to hear :)

    • +
    +
  • +
  • I didn’t know where to ask questions. It would work best for me to do it in zoom chat as that’s the application that I’m watching in..

    +
      +
    • Sorry for that, just to figure out why: Did you join a bit late?

      +
        +
      • No. Perhaps I just missed that or it was too quick for me or something?

        +
          +
        • Ok, sorry. Will try to make this more clear in next session.

        • +
        +
      • +
      • Perhaps also because there were so many things going on and jumping around. For me, the zoom chat is the constant (and obvious) place to ask questions while watching a shared screen, trying to find the right place in a moving collaborative document is difficult. It tears my attention into too many pieces. :+1:

      • +
      +
    • +
    +
  • +
  • Had a lot of content that assumed extant knowledge that I didn’t have. This wasn’t in the pre-requisites.

    +
      +
    • Do you have examples?

      +
        +
      • Yes! The code refinery templates and even just the way of doing that. I was expecting more on “when designing a lesson you should think about these steps” rather than this is how we do it and this is our tool for doing it. I guess I should have read the pre-workshop content better?

      • +
      • Ok, thank you for your feedback. You are right that we actually had some content that for sure would have been easier to follow for people with background knowledge about a certain topic.

      • +
      • “If you are in CodeRefinery TTT, you probably know what version control is and why it is important.” - extant knowledge, why not just add a sentence or two?

        +
          +
        • Please can you update in preparation for the next workshops so that I can decide whether or not they will be right for me?

          +
            +
          • Yes, we will think more thoroughly about this and send the info in the next email going out Wed/Thu

            +
              +
            • Thank you!

            • +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • Lots of the content was relevant to code refinery but not the wider topic (e.g. it was how to design a code refinery lesson and not how to design a lesson as stated in the session title)

    +
      +
    • We thought of the content of showing one way of doing things, ie “what we have learned”, if you have suggestions on how we could make that more clear on the event page, please let us know :)

      +
        +
      • “in a code refinery lesson” in the lesson/workshop description?

      • +
      +
    • +
    +
  • +
  • When you have pre-written “thank you for your active participation” it feels fake!

    +
      +
    • He, that is true, did not think about that. Thank you for the feedback. I would not have added it if Radovan and Richard would not have provided good feedback from circling the rooms.

    • +
    +
  • +
  • I found it vague and disorganised and difficult to follow. It felt like the instructors were presenting the content for the first time and didn’t know what to do next.

    +
      +
    • Thank you for your feedback. This is not the first time we have this training, but it is the first time in this constellation/way. The way of teaching may also sometimes make it seem new to instructors.

    • +
    +
  • +
  • I really liked the active exchange with other participants, but I also would have enjoyed a bit more technical content in the presentations. In a sense it felt less like a ‘training’ and more like a get-together :+1:.

    +
      +
    • Thank you for your feedback. We thought the name “workshop” would combine the training and exchange nature of this event. But maybe it didn’t do so enough? Do you have suggestions on how to clarify it on the event page?

      +
        +
      • Well, the ‘train the trainer’ title created the anticipation of being trained ;) don’t get me wrong, I liked the exchange, but I felt that the training aspect fell a little short. imho the workshop would benefit from a little more (instructional) content that is presented in a more structured way by the instructors (as opposed to ‘crowd-sourced knowledge’ that is collated in a loose collection of questions, notes and links)

      • +
      • Other than that, you could add another section on the main page, sth like ‘Workshop structure: we aim for a mix of modular presentations and work in small groups. The latter will be done in breakout rooms - be prepared to switch on your camera and have a fruitful exchange with fellow participants!’

        +
          +
        • Thank you for the suggestions, will add something like this :tools:

          +
            +
          • +

            Added : https://github.com/coderefinery/train-the-trainer/commit/03308595436e636b3bb37ed9d1f0dee39eeccd0f

            +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • My understanding (so far) of what (unlike the competition) CodeRefinery DOES NOT seek to exemplify - +https://images.ctfassets.net/rxqefefl3t5b/2k45BFtw4sBMlBfjr1OZ90/5c6ecd3628a43b0cdc79815f665e224a/Screenshot_2023-05-02_at_09.35.23.png?fl=progressive&q=80

  • +
  • My understanding of what (unlike the competition) today’s session of CodeRefinery DID exemplify - Definition of ‘Workshop’ from the Oxford dictionary of the English language “a period of discussion and practical work on a particular subject, in which a group of people share their knowledge and experience”

  • +
  • In my experience, even for the most seasoned Programmer coding, by its very nature, is nothing trivial, this being a simple straightforward fact just like there is no such thing as an egg which is a cube. I mean there is a reason why not just about everybody is a poet either. But, other minds have pointed this out without having to first explain why the universe is what it is in a way that could be understood without effort … https://i.pinimg.com/originals/7b/7e/c4/7b7ec4b91d2cf9d8e1b064678d205467.jpg

  • +
  • The inclusive environment feels very welcoming. Keep up the good work!

  • +
+

Thank you all for your feedback! Highly appreciated!

+
+
+
+

Day 2 : Session 2 (20.08.24)- Tools and techniques adopted in CodeRefinery workshops

+
+

:calendar: Schedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 9.25

About CodeRefinery workshops

10.15 - 10.25

8.15 - 8.25

9.25 - 9.55

Collaborative notes and interaction

10.25 - 10.55

8.25 - 8.55

9.55 - 10.10

Break

10.55 - 11.10

8.55 - 9.10

10.10 - 10.45

Workshop overview, roles, onboarding

11.10 - 11.45

9.10 - 9.45

10.45 - 11.05

Sound

11.45 - 12.05

9.45 - 10.05

11.05 - 11.20

Break

12.05 - 12.20

10.05 - 10.20

11.20 - 11.50

How to prepare a quality screen-share

12.20 - 12.50

10.20 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+

:icecream: Icebreaker

+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :-)

  • +
  • https://media.istockphoto.com/id/148421550/vector/bored-emoticon.jpg?s=612x612&w=0&k=20&c=uo5KBTqdJZbBQb_Xldhzuovx5t08fHfGR7dw7TCk90I=

  • +
  • :saluting_face:

  • +
  • :sleepy:

  • +
  • :coffee:

  • +
  • :umbrella:

  • +
  • :cocktail: :coffee:

  • +
  • :seedling:

  • +
  • :tired_face:

  • +
  • :sun_with_face:

  • +
  • 🥴 (:woozy_face: not converted?)

  • +
  • :coffee:

  • +
  • :sunflower: :book:

  • +
  • :satisfied:

  • +
  • :coffee:

  • +
  • :coffee:

  • +
  • 🥱:tired_face:

  • +
  • :bread: - I am baking bread today so I have been kneading dough while listening!

  • +
+
+
+
Introduction in breakoutrooms
+

Name / Affiliation / Location

+
+
+
Teaching
+
    +
  • Do you teach and organize teaching alone or with others? What would you prefer and why?

    +
      +
    • Coming together is a beginning; keeping together is progress; working together is success. – Edward Everett Hale

    • +
    • These days always with others. Alone is easier to prepare but almost always is harder during it.

    • +
    • Teaching with very diverse partners, it can be challenging to find a common language with people very different than you.

    • +
    • I teach alone, in the future there will be more collaboration with multiple team members. Both approaches have their pros and cons.

    • +
    • Both has its own distinct advantages

    • +
    • Most of my teaching is on my own, as a freelancer its more expensive to work with colleagues than to deliever a course on my own.

    • +
    • Teaching together, learns from each other, feedbacks to improve

    • +
    • Not formally taught yet, only given presentations actually .

    • +
    • collective teaching would benefit the teachers with collaborative curriculumn and experiences sharing.

    • +
    +
  • +
  • If applicable, have you seen any challenges when teaching together and how to overcome them?

    +
      +
    • It actually requires preparation,

    • +
    • Is it about teaching or about inspiring ? Discover the answer and get inspired …

    • +
    • It’s like being in a band: you might be great at improvising and your band-partners might be great at improvising too, but a bit of rehearsing makes even the impro gig much better

    • +
    • Need to plan before session, difficult if people don’t ‘plan’ in the same way, e.g. with the same time frame.

    • +
    • Heterogeneity in learners make it impossible to get the same result from everyone.

      +
        +
      • In fact, the same applies to teachers :D

      • +
      +
    • +
    • Teaching together requires to have similar opinions on how to teach. I share vews only with ~40% of my colleagues I think.

    • +
    +
  • +
  • No Teaching experience but it is good to give the outline of the lessons beforehand and learning goals.

  • +
+
+
+
+
+

:question: Questions

+
+
General / Practicalities
+
    +
  • What is this document for?

    +
      +
    • Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts)

    • +
    +
  • +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms?

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    • BR 1 : The Zoom chat does not work for the breakout room so we should take note of that. No webcam/mic = expect silence.

      +
        +
      • Thanks for notifying! This was not intended. Turned the chat back on.

      • +
      +
    • +
    +
  • +
+
+
+
+
+

Episode 1: CodeRefinery

+

Materials: https://coderefinery.github.io/train-the-trainer/coderefinery-intro/

+
    +
  • (questions continue here)

  • +
  • Is there the plan to build capacity / be paid to deliever courses?

    +
      +
    • We’ve discussed it but right now we don’t have many people who could accept money to do this (and maybe shouldn’t, because of their jobs). But, we would encourage others to use our materials as “independents” to deliver paid courses

    • +
    • One idea we have had is that paid courses could be delivered through the DRA (link below), who we know. Basically, DRA could find instructors and handle the money transfers (If someone wanted a paid course, we could help find someone to do it through DRA or independently)

    • +
    • :smile:

    • +
    +
  • +
  • Have you come across DRA, https://digital-research.academy/, Heidi Seibold, Joyce Kao who are doing similar work? I can connect you if you like.

    +
      +
    • Yes we have been discussing about possible future collaborations and are already sending possible clients their way (we, as a project cannot take money) :+1:

      +
        +
      • Excellent! :-D :smile:

      • +
      +
    • +
    +
  • +
  • .

  • +
+
+
+

Episode 2: Collaborative Notes

+

Materials: https://coderefinery.github.io/train-the-trainer/collaborative-notes/

+
    +
  • So anyone can type anonymously?

    +
      +
    • Yes, as long as you do not log in, you are Guest XXX

    • +
    • And at least in our hedgedoc case you cannot log in so you will always be anonymous. You can do [name=xxx], to add your name to a comment

    • +
    +
  • +
  • Test of +1

    +
      +
    • +1 :+1: :+1:

    • +
    • :-1: a test

    • +
    +
  • +
  • You are hosting your own version of HedgeDoc, and Hackmd.io is a similar (free) option. What are the limitations of the free hackmd.io? Should each center install their own HedgeDoc instance?

    +
      +
    • It seems the free version of HackMD has gotten worse lately. It works still well enough with a few people editing at the same time.

    • +
    +
  • +
  • Have there every been problems with the anonymity and CoC?

    +
      +
    • We haven’t had any issues so far.

    • +
    • With a different anonymous tool in a bachelor course, we had issues with anonymous participants (participants were posting slurs and unsafe links). The course organiser decided to stop allowing anonymous tools.

    • +
    +
  • +
  • Why not google documents?

    +
      +
    • Google documents are actually setting a hard limit for simultaneous writing, no more than 100 concucurrent editors. I am unsure if microsoft onedrive word documents would allow more users writing at the same time.

    • +
    +
  • +
  • What’s the most people you have every had on HackMD / Hedgedoc?

    +
      +
    • I believe about 200 active participants?

    • +
    +
  • +
  • What are your thoughts on using the build-in Zoom Q&A?

    +
      +
    • We haven’t tried this, in part because the way we do streaming now (you’ll see in session 4), participants aren’t in Zoom so don’t have access to that. The doc-format works pretty well though, when we keep it in this limited “write at end” format.

    • +
    +
  • +
  • How do you see what has changed? e.g. if leave the session at the end, can I come back tomorrow and see X has been added? e.g. a diff for this maybe?

    +
      +
    • In the menu up right there is revision, it does show the document and changes at different time step :+1: Thanks!

    • +
    • We recommend people only write at the bottom (and since we answer things live), so as a first level approximation you find where you were and read below that. Think of it more like chat than a full document. (Yes, we do revise questions at the end)

    • +
    +
  • +
  • How about flinga boards or similar tools?

    +
      +
    • My take is that the simplicity of a simple text document wins over free-form in-person-workshop-like tools.

    • +
    • There’s miro, can be a bit confusing though

    • +
    +
  • +
  • How does this work with small groups, e.g. 10-15 people?

    +
      +
    • Good question: it can be hard if people aren’t rigorous about it, people start only using chat/voice. So there seems to be some lower bound in size but we haven’t tested this much

    • +
    • And if the instructors never screenshare it to show what goes on it, then seems to be less used.

    • +
    • And if there aren’t other people to read/answer it during the session (perhaps less likely in a small course), it seems to be less used.

    • +
    +
  • +
+
+

Breakoutrooms until xx:55

+

Exercise/discussion: https://coderefinery.github.io/train-the-trainer/collaborative-notes/#exercise

+
+
    +
  • Breakout room 1:

    +
      +
    • Use of etherpad for collaborative discussion.

    • +
    • Use of slido for polling and quizzing.

    • +
    • Presemo as a slido alternative (https://www.aalto.fi/en/services/presemo-a-fully-web-based-classroom-participation-system)

    • +
    • Use of text based approach for questions rather than live can be helpful if there is a language barrier issue.

    • +
    +
      +
    • A good teaching session which had many questions coming spontaneously to the teacher is a non-entity of sorts. If the overall flow of feedback / questions increases it could indicate that the session will not prove to be a helpful experience. A signal that generates noise is, well, noise, if calling a spade a spade signals anything. Note that the ‘overall’ bit and the ‘to the teacher’ aspect are important. Both the best and the worst teaching session have two things in common: a teacher, and the fact that NO Materials of any kind are used, ie speech is the only channel of communication via a common language. The only difference is that it is not the same teacher, at least not in the same session at the same time.

    • +
    +

    Another less mentioned, but perhaps more relevant indicator of a great session is the simple fact that at the end of the session EVERYONE feels empowered, NOT tired. This is not an easy to quantify thing, but screams out the quality of the experience loud. More often then not, such sessions differ little from each other, apart from in terms of the theme / topic and the participant mix. It ends up being the ‘keep your cake and eat it too,’ of sorts, not quite the far less amusing post-bombardment devastation scenario in the wake of a take it or leave it go at anything.

    +
      +
    • profanity in collaborative documents where people can add content anonymously could be a problem (happens very rarely, fortunately and somewhat surprisingly)

    • +
    +
  • +
  • Breakout Room 2:

    +
      +
    • Good experiences with Zoom polls

    • +
    • Handling questions in hybrid setups: all participants (on-site and online) ask questions in written form

    • +
    • Collaborative notes can be challenging when conducting a course alone (without teaching assistants) :+1:

    • +
    • Providing a method to ask questions anonymously can make asking easier for shy participants

    • +
    • Questions can give valuable feedback on how the course is going

    • +
    • Online collaborative whiteboarding platforms such as Miro

      +
        +
      • Large monitors are useful for this not to have to drag a “periscope” around

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • good experience with whatsapp chat for questions. since most learners have the app already and one thing less to install and set up

      +
        +
      • reply to question is a way to handle multiple questions at the same time but it works well for smaller groups

      • +
      +
    • +
    • experience with collaborative docs in in-person workshops: voice questions might “win” over the document

    • +
    • “seeding” questions may help to not have an empty document

    • +
    • it can help somebody to start and create a structure which helps others to see and follow

    • +
    • we discussed the Carpentries sticky notes system (red sticky note: signal tech issues and use for feedback, green sticky note: signal that exercise worked and for positive feedback)

      +
        +
      • Nice summary of sticky notes system: https://teachtogether.tech/en/#s:classroom-sticky-notes :+1:

      • +
      +
    • +
    • What is the success rate of in-person workshops after COVID? Discussion: Teachers prefer in person and learners prefer remote or recorded to spool back and relearn.

    • +
    +
  • +
  • Room 5

    +
      +
    • Good experience with Collaborative tools as HackMD and HedgeDoc while teaching with no bad feedback

      +
        +
      • When used with smaller groups works best as one-way, like sharing links with students and so on

      • +
      • Needs to be done as a team, quite difficult if teaching alone

      • +
      • Most useful when online/hybrid

      • +
      +
    • +
    • Anonymisity is important for transparent feedback and no biasis in classrooms

    • +
    • Not very collaborative but useful to share history or jupyter notebooks live https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush

    • +
    • Used Flinga before that seems like Figma and also onsite teaching using sticky notes

      +
        +
      • There’s miro.com but can be a bit confusing, more for brainstorming than for teaching

      • +
      +
    • +
    • Using quizzes apps like Kahoot is beneficial while teaching to have more engaging students

    • +
    • +
    +
  • +
  • Room 6

    +
      +
    • teaching teenagers (in presence) but using shared pad becomes quickly very chaotic, so only usable for short moments when answering very precise questions

      +
        +
      • Yeah, I can imagine. For CR we try to keep it in this very limited format (all questions bullet points, only add to the end) and I think that helps.

      • +
      +
    • +
    • using shared notepad for small workshop (5-10 people) to explore common thematic (mainly technical) to keep a shared notes and condense aftwerward (and publish on wiki to archive)

    • +
    • Difference between teaching in person and online. Some people prefer in-person and sometimes you have no option but to organise it online.

    • +
    • There are sometimes cultural differences and learners feel shy to ask / question the knowledge of the Teacher, so shared notes are a good way to safely ask questions.

    • +
    +
  • +
+

Questions continue:

+
    +
  • Have we demonstrated how we do polls in HedgeDoc? Add your vote by adding an o

    +
      +
    • yes: oooo (in session 1)

    • +
    • no:

    • +
    • :smile:

    • +
    • not sure: o

    • +
    +
  • +
+
+
+

Episode 3: One workshop, many perspectives

+

Materials: https://coderefinery.github.io/train-the-trainer/overview/ +Next CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/

+
+

Exercise until xx:39

+

https://coderefinery.github.io/train-the-trainer/overview/#discussion

+
+
    +
  • Room 1

    +
      +
    • Send pre-workshop email with pre-requisite instructions on what should be set-up beforehand.

      +
        +
      • But, also mention that if help is needed for set-up, we will be ready before the session officially starts.

      • +
      +
    • +
    • Discussion on whether we push to work in a pre-ready environment (e.g. Binder, Colab) or in their own environment.

    • +
    • Lots of help needed both before and after.

    • +
    • Installations: as much as we can provide ready made environments for the learners, maybe installations will be something that the learners will face sooner or later. Maybe one should teach more about installations?

    • +
    • My only cherished role in a teaching-learning session is the that of one who is living the moment as if there were no tomorrow. What cuts all ways really is that “By failing to prepare, you are preparing to fail.” ― Benjamin Franklin. A helpful motto: “When one teaches, two learn.” — Robert Heinlein. The best experience cannot be given, it can only be allowed to flow its way, so get out of its way.

    • +
    +
  • +
  • Room 2

    +
      +
    • Frequently, a single person fills all the roles for a single or multi-day workshop

    • +
    • Collaboration with different centers/ universities can be challenging

    • +
    • Preparing participants: it’s essential for the instructor to go through the demos and be sure that they will work (no unpleasant surprises live). This can be extended to advance-prep for participants.

    • +
    • Best experience is to hear (live or in feedback notes) some positive things directed at you :)

    • +
    • Fully prepared environments (eg self-hosted JupyterHub) can make preparation for participants easy

    • +
    +
  • +
  • Room 3

    +
      +
    • Some students have problems with setuping the environment. Maybe having a step by step instructions could help. But some students don’t want to “start” the course before hand.

    • +
    • Preparing the environemnt before hand ensures everyone is onboard from day 1. The same thing happend in CSC training sessions and another session Peng attended.

    • +
    • Had experience in attending as teacher and student in previous workshops

    • +
    +
  • +
  • Room 4

    +
      +
    • knowing the background of the audience is helpful

      +
        +
      • Try and ask in advance of the background of the audience. Do a poll at the start of the workshop. In person one can do it interactive.

      • +
      +
    • +
    • among co-instructors: discuss topics and flow

    • +
    • if more people are involved, it can help changing roles from time to time to see different perspectives

    • +
    • preparation is key

    • +
    • Circulate instructions beforehand

      +
        +
      • Do a poll before session: Have you installed (QGIS) successfully?

      • +
      • Push hard to do this in the welcome email

      • +
      +
    • +
    • communicate clearly to the participants

    • +
    • +
    +
  • +
  • Room 5

    +
      +
    • We’ve all taken most roles

    • +
    • How to prepare in advance?

      +
        +
      • Meet and discuss once or twice

      • +
      • Make a pre-survey to check for interest and background

      • +
      • Going through the materials

      • +
      • Checking the toolkit (zoom)

      • +
      • Agree on the reponsibilities and back-up plans (bit of scenarios planning)

      • +
      +
    • +
    • How to prepare trainings in advance?

      +
        +
      • Collect resources and prepare the workshop plan

      • +
      • Having the material readily available online ans sharing it

      • +
      • Making a pre-survey

      • +
      +
    • +
    • What was the best workshop experience for you as learner, helper or instructor? What made it great?

      +
        +
      • learner

        +
          +
        • Engaging and practical workshop with more exercices and follow-up theoretical part explanations

        • +
        +
      • +
      • helper

        +
          +
        • When the instructor is well prepared and as helper ther’s only typos to fix and interesting questions to answer

        • +
        • Assist the instructor, coordinate the collaborative notes, and make sure that the time is respected

        • +
        +
      • +
      • instructor

        +
          +
        • I have a colleague whom I’ve ran the same workshop a few times already, goes quite smoothly now and we’ve made a few changes. Hard to reach that point with new colleagues but getting there

        • +
        • Students/participants were engaging with the material and many good feedback collected even some of them asked for the next workshop

        • +
        +
      • +
      +
    • +
    +
  • +
  • Room 6

    +
      +
    • What has made a great experience for you as a learner/helper/instructor?

    • +
    • Common ground between learners & teachers

      +
    • +
    • Motivation

      +
        +
      • Teaching is much more enjoyable when the learners want to be there

      • +
      • I spend a lot of time at the start of a workshop making sure learners feel that the content is possible for them to understand and master

      • +
      +
    • +
    +
  • +
+

Poll: I have joined a CodeRefinery workshop before: (add an o for your answer)

+
    +
  • yes (within last 2 years): ooooooo

  • +
  • yes (longer time ago): oo

  • +
  • no: oooooooo

  • +
  • +
+

(questions would continue below:)

+
    +
  • What is the motivation / advantages of streaming workshop versus using zoom?

    +
      +
    • We’ll cover this more in week 4, but roughly: zoom became unmanageable and essentially quiet once things got big. Streaming allowed “one to many” communication with no limit, and collab notes allowed better interaction anyway. By separating the rooms, it was more pleasant to teach. Videos could be released immediately since there was no risk of privacy of participants. There could still be in-person/online small groups who have “watching parties.”

    • +
    +
  • +
  • What are the blue red and green font colors here, does it symbolify anything or just a convention HedgeDoc uses?

    +
      +
    • Visual separation of formatting, mostly. (It helps to quickly realize you’ve missed/ mistyped a control Markdown symbol etc.)

    • +
    • Yeah, it’s bascically “code highlighting” for markdown. No special meaning but quite convenient for us.

    • +
    +
  • +
  • Is this next workshop only for team leads or also open for helpers and coordinators?

    +
      +
    • You mean the next session of this workshop or the upcoming “CodeRefinery workshop”(this one: https://coderefinery.github.io/2024-09-10-workshop/)?

      +
        +
      • The upcoming workshop coordinators are alredy working, but can be joined if you are interested

      • +
      • As helper roles we currently only have “collaborative notes helper”, which is all about helping to answer questions in the collaborative notes

      • +
      • We do have some co-teaching slots open :)

      • +
      • If interested: join the discussion in our chat: https://coderefinery.zulipchat.com/#narrow/stream/316508-coderefinery-tools-workshop/topic/Fall.202024.20CodeRefinery.20workshop

      • +
      +
    • +
    +
  • +
  • Can a person have multiple roles in a workshop as a helper and a teacher?

    +
      +
    • Yes, many teachers also contribute to the rest of the workshop by answering questions in collaborative notes. :+1:

    • +
    • Some teachers also host a local classroom in week one and do their teaching in week two of the workshop

    • +
    • Roles that do not go well together are broadcaster/director/host and instructor (goes well until there is a problem; co-teaching solves that partly)

    • +
    +
  • +
+
+
+

Episode 4: Sound

+

https://coderefinery.github.io/train-the-trainer/sound/

+
    +
  • To me, Richard is a bit quieter than the other two :+1: :+1: :+1:

    +
      +
    • to elaborate: I think that the audio coming from him is missing some mids

    • +
    • Do you have any links about this kind of evaluation and adjustment?

    • +
    +
  • +
  • Do you suggest / recommend a specific headset(s) with mounted microphone?

    +
      +
    • in our experience headsets with a microphone will almost always be better than a separate microphone sitting on the desk or in the monitor

    • +
    • +
    +
  • +
  • Speakers have different tones of voice and speaking styles, is there a recommendation or experience from CR workshops for how this is adjusted and catered to environemnts for listeners?

    +
      +
    • Yeah, people’s voices are different and we haven’t gone as far as voice training or improving.

    • +
    +
  • +
  • How to change the volume for speakers? Tried Zoom settings and system settings and didn’t help.

    +
      +
    • From linux I can use different pulsemixers pavucontrol, pulsemixer to set the gain to above 100%. I’m not sure the equivalent on other OSs but

    • +
    +
  • +
+
+
+

Exercise until xx:10 +https://coderefinery.github.io/train-the-trainer/sound/#exercises

+
+
    +
  • room 1

    +
      +
    • Practically, no typical headset is designed or can capture the technical purity of human voice within its natural environment. But one needs to understand the polar pattern of the (specific) microphone or how much of the signal will be picked up by the microphone from different directions, a sine qua non when it comes to mitigating unwanted sound sources to bleed into the signal.

    • +
    +
  • +
+

For best results, keep the right direction & distance to your (directional) mic. Usually, that’s between 15-30 cm to get get a natural sound. A microphone records everything it can, also silence, so check the headphone output BEFORE adjusting the gain, in some specific cases aim for a dry sound, ie the influence of the room or how audible the room is on the recording ! Finally, adjust the mix between dry and room sound, or change the frequency response in tandem using a compressor to reduce the dynamic range of a signal for a more consistent listening experience = the quietest parts of your signal will appear louder by reducing the loudest parts.

+

It is all about one thing and one thing only - love your voice, let people fall in love with the acoustic quality of your charm. So remember: GIGO, it matters!

+
    +
  • Room 3

    +
      +
    • Had different headsets and we could see the difference (bluetooth low quality)

    • +
    • How to change the volume?

      +
        +
      • It’s surprisingly hard to get more control than the basic slider you see in the apps! You need to look.

      • +
      +
    • +
    +
  • +
  • room 4

    +
      +
    • headset is probably better listening experience but they can be uncomfortable to wear during long meeting days :+1:

      +
        +
      • Yeah. Luckily only instructors

      • +
      • Therefore breaks are non-negotiable

      • +
      +
    • +
    • loud keyboard can be an issue

    • +
    • if one has a silent room that does not echo, it can be ok to teach without headset

    • +
    • on Linux I am using pulsemixer to adjust levels and pavucontrol to change outputs/sources

    • +
    • mic modes on mac

    • +
    • check default microphone for zoom.

    • +
    +
  • +
  • room 5

    +
      +
    • Most tricks help tuning yourself but hard to do it as a group. Perhaps doing a short recording.

      +
        +
      • Yeah. Some independent recording/playing aronud, but also asking for advice. I would do small group/one-on-one things.

      • +
      +
    • +
    • Background noises cancellation tools or wise choice of quiet environments

    • +
    • Audio check with colleagues or through the app with the audience saying numbers for example

    • +
    • Zoom or Teams have sound checks but work different in the app than the browser. They also work different across Operating systems

    • +
    • Some sound issues might be related to network speed or stability, also to RAM available. Worthwhile to try and control those as well

    • +
    • Make it welcoming for the audience to give you feedback on the audio and other settings, give reminders

    • +
    +
  • +
+
+
+

Episode 5: How to prepare a quality screen-share

+

Materials: https://coderefinery.github.io/train-the-trainer/screenshare/

+
    +
  • If your Zoom does not support “share portion of screen”, sharing a tab and resizing it to portrait for yourself is a possible workaround (this at least works when joining the call from Chromium browser)

    +
      +
    • Another workaround is to use an editor/IDE that displays multiple panels in one window and can show a web page, code files and terminal session +10

    • +
    +
  • +
  • Is ‘share a portion of your screen’ where you draw a box in Zoom to share a section?

    +
      +
    • yes :+1:

    • +
    +
  • +
  • When using zsh, one can run something like this in a terminal

    +
    tail -n $NLASTCOMMANDS -f ~/.zsh_history | sed 's/^.............../LAST COMMAND:/g'
    +
    +
    +

    (I place this in a window under the main terminal, I use i3)

    +
  • +
  • I am a bit confused on what platform you are putting this code?

    +
      +
    • Radovan is using Linux with (I think) the “i3 window manager”. It can be quite involved and there is lots of personal customization here.

    • +
    +
  • +
  • When teaching with a custom prompt, is it worth starting with the default (that your learners will see) and explicitly mentioning “I change these things to make it clearer when teaching”

    +
      +
    • One should always comment on what may be different. Thing is “default” may look different for many people :+1:

    • +
    • “I am not going to teach you how to customise your prompt, but here’s an online tutorial, be prepared to lose several days of your life…” :laughing:

    • +
    +
  • +
  • Now I can’t see the last line in the terminal

    +
      +
    • Yep, that’s a problem. It can be good to keep a buffer on the bottom of the screen.

    • +
    • If you move your mouse outside the Zoom window, the controls should go away. But still a good note.

      +
        +
      • My mouse was on another screen.

      • +
      • Ok, thanks.

      • +
      +
    • +
    • I think one can also make the zoom bars not auto-hide (then it won’t display under), but that is annoying also since it wastes space.

    • +
    +
  • +
  • Does anybody still use shellshare? Does it work?

    +
      +
    • We in CR haven’t used it much but we have seen it.

    • +
    +
  • +
  • Does the stacking of the screens work on windows?

    +
      +
    • Don’t know unfortunately

    • +
    +
  • +
+
+

Exercises (done together) +https://coderefinery.github.io/train-the-trainer/screenshare/#exercises

+

Write your cool tips and ideas below. +Stay after xx:00, to

+
+
    +
  • To be safe, I have created on my computer an account that I use only for teaching, so I do not need to do any manual set up

  • +
  • share history or jupyter notebooks live (5-10 secs refresh rate) into a git repo. Share the link with the learners so they can catch up https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush

  • +
+
+
+
+
+

Wrapup

+
    +
  • Next session Tuesday August 27 9 CEST: About teaching & cool things we all would like to share

  • +
  • All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • Cool gems session: If you want to share something, please edit your registration and fill it in there (link to modify in registration confirmation); or e-mail to support@coderefinery.org

  • +
  • If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14:00 (Europe/Stockholm time)

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • Sound and screen share optimization as well as relevant tools and good practices for online instruction. “While you may be unable to control your users’ mindset, you can anticipate it, and make sure that your user experience caters to it.” - Jonathan Cherki

  • +
  • Nice opportunity to (re)think about my online teaching setup :+1: :+1: :+1:

  • +
  • Other ways to display command history :+1:

  • +
  • Did not know that bluetooth gear had so much latency! :+1:

  • +
  • A good reminder about headsets with microphones

  • +
  • Nice and friendly teaching. Thank you!

  • +
  • Screen share with command history and terminal customisation

  • +
  • Really useful tips on sound and screen sharing :+1:

  • +
  • Nice experience share

  • +
  • very useful and practical tips!

  • +
  • Easy to follow along and filled with useful tips on sound, video etc.

  • +
  • +
+

What one thing would you improve about this session?

+
    +
  • Just digging to find something: I have read some of the things you have talked about here already in some blog posts, so perhaps these sessions are not as shokingly full of new content as I imagined (but actually sharing experiences is something I can’t do by reading a blog post)

    +
      +
    • Perhaps: could you link some blog posts or other sources for what you have discussed so far? If it makes sense. Not sure.

    • +
    +
  • +
  • Talking about interface optimization approaches, which applies to sound as much as to visuals or any other aspect either for that matter, it might offer a perspective to bear in mind the concept of introducing asymptotic complexity increment. The latter would mean the goal is measuring how fast the effort of engaging, on one or more of the three parallel levels of interaction, must change to reach higher levels of partial certainty on the correctness of the implementation of the method in question, in this case the pedagogical paradigm. For the former, lower is better I guess, or in this case, in the intended sense, slower is faster. Let us consider an abstract example: People liked using the search engine Google (a Google session to put it in a fancy way) in the early days because it was as simple as it could get, a literally featureless entry point with no bells and whistles. That was the level of its visible complexity, or rather Google set a bar as low as it one could have, and then any higher point of VISIBLE complexity that was to be introduced, such a move would only be on the path of an asymptotic curve curving towards the set bar, never reaching it, as far as the entry point is concerned. We still see the same level of complexity when we fire up google and we never feel distracted to start with, except for the rather forgivable nuisance of the GDPR conformity pop-up notice which appears only AFTER the first move has been made, and thankfully it works plain and simple from there on (unless one starts feeling lucky, pun intended). Now, think about Youtube … the user experience complexity is a totally different matter, the same company today (unfortunately) yet one now has a steadily worsening engagement experience. Good learning sessions tend to be more of the Google search engine experience and a far cry from the current Youtube trend I would opine. Or, to sum it up and keep it sweet and simple, it helps to identify the limits of human-human and human-technology interaction, within the framework of any applicable technology-technology interaction and joy is the result of respecting those limits. Wishful thinking ?

  • +
  • Bring the cat back!

    +
      +
    • I wish it came, but it’s been resting all morning! I don’t bother it or stage apperances…

    • +
    +
  • +
  • Maybe having a digest/ summary of previous iterations of this session might be interesting. I feel a lot of experiences have been exchanged and a lot of techniques/ tools have been mentioned. Spending some time in compiling this into a selected list and adding it as content to the course itself might be worthwhile.

    +
      +
    • Good idea! We will write a blog post about this workshop and will include a summary of all discussions there :)

    • +
    +
  • +
  • Possibly have some command line examples from Windows rather than (just) *nix? I will look at the screenshots after the session. :+1: :+1:

    +
      +
    • Also, a thought if you do do breakout sessions with this work, do one for Unix, one for Windows, one for Mac as an option.

    • +
    +
  • +
  • I could not follow the part Radovan showed codes (Radovan is using Linux with (I think) the “i3 window manager”.)

  • +
  • ..

  • +
+

Any other comments?

+
    +
  • Looking forward to the topics of following sessions.

  • +
  • Looking forward to the next sessions!

  • +
  • Thank you!

  • +
  • Relax, nothing else matters, live a life and have fun ! If you obey all the rules you may end up missing all the fun. ‘The best way to predict your future is to create it.’ - Abraham Lincoln :+1:

  • +
+
+
+

Day 3 : sessiion 3 (27.08.24) - “About teaching and cool things we all would like to share”

+
+

:calendar: Schedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 9.45

Computational thinking

10.15 - 10.45

8.15 - 8.45

9.45 - 10.00

Break

10.25 - 11.00

8.25 - 9.00

10.00 - 10.30

Teaching philosophies

11.00 - 11.30

9.00 - 9.30

10.30 - 11.00

Co-teaching

11.30 - 12.00

9.30 - 10.00

11.00 - 11.15

Break

12.00 - 12.15

10.00 - 10.15

11.15 - 11.50

Sharing teaching gems (voluntary)

12.15 - 12.50

10.15 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+

:icecream: Icebreaker

+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • +
  • :sleeping:

  • +
  • :coffee:+2

  • +
  • :robot:

  • +
  • Still little sleeppy :)

  • +
  • 🥴 (:woozy_face: still not converted 🤷‍♂️)

  • +
  • Our planet could be a cube. It has six sides to it. It must be a cube. A cube it is, this Blue Planet … just wondering …

  • +
  • 🦾

  • +
  • :sweat_smile:

  • +
  • computer says no :-) some network trouble

  • +
  • running late, and participating from a :train2:

  • +
+
+
+
Introduction in breakoutrooms
+

Name / Affiliation / Location

+
+
+
Best classroom experiences
+

As a learner or teacher; what was the best workshop/lesson/seminar you have attended? What made the experience great?

+
    +
  • Room 1

    +
      +
    • First summer HPC streamed workshop (as a teacher). Somehow the first felt the best

    • +
    • CSC HPC summer workshop

    • +
    • story telling teaching approach

    • +
    +
  • +
  • Room 2

    +
      +
    • NVIDIA DLI Course on Deep Learning

      +
        +
      • very enthusiastic instructor

      • +
      • intuitive and very accessible way of showing technical details and fostering deeper understanding

      • +
      • a lot of hands-on material and smaller coding exercises

      • +
      +
    • +
    • Anything as long as its interactive and somehow enjoyable from both teacher and learner sides

    • +
    +
  • +
  • Room 4:

    +
      +
    • EPCC MPI Distributed training workshop.

      +
        +
      • Lots of hand on coding / experience gained.

      • +
      • Very interactive instructor who also discussed ideas for more personalised cases of distributed computing.

      • +
      +
    • +
    • Coderefinery RSE course

      +
        +
      • relevance of topic to my current work.

      • +
      • Dynamic / friendly / positive teaching style.

      • +
      • Modular Code Development; very instructive

      • +
      +
    • +
    • Some CSC courses / LinkedIn learning courses

      +
        +
      • up to date materials and topics.

      • +
      • Good way to merge theory with practicalities without making learner feel bored (Example: Jonathan Reichental)

      • +
      • Challenging information to learn more and research about the topic

      • +
      • Trainers are the experts in the field

      • +
      +
    • +
    +
  • +
+
+

Episode on teaching gems

+

If you want to share or demo something about tools and techniques you have found helpful in your teaching, please add your name/initials and rough topic below for smooth transition.

+
+

Note: It does not have to be your tool or your idea, this episode is meant to share experiences and discover new things. You also do not need any slides or materials, a story will do fine :) +Length of the stories will be depending on interest, but be prepared to fit it into 3 min (shortest possible).

+
+ +
+
+
+
+
+
+

:question: Questions

+
+

General / Practicalities

+
    +
  • What is this document for?

    +
      +
    • Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts)

    • +
    +
  • +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms?

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    +
  • +
+
+
+
+

Episode 1 : Computational thinking

+

Materials: https://coderefinery.github.io/train-the-trainer/computational-thinking/ (Link to slides in the middle of material)

+
+
Questions to audience
+

How might breaking down a complex problem into smaller parts change your approach to problem-solving in your current projects?

+
    +
  • Avoids cognitive overload

  • +
  • I used to give an example about this in workshops of cutting long tree into pieces from top to avoid that it falls and destroy a house bloc.

  • +
  • Easier to start on something small

  • +
  • Each individual part is familiar and can take existing solutions.

  • +
  • Only focus on the new things

  • +
  • One can lose oversight of where is supposed to be getting to due to problems with summation of biases introduced during the solving of the parts.

  • +
  • .

  • +
+

Can you think of a research project where identifying patterns in your data led to new insights or breakthroughs?

+
    +
  • Multi-targeted drug design where you need to identify both chemical and biological pathways/patterns

  • +
  • Distilling complex physics problems into simpler 1D statistics is very often done.

  • +
  • I used to do bioinformatics, pretty much everything in biology is about patterns in strings of charachters (DNA, proteins). Finding those patterns and using them is the way to go

  • +
  • Pattern recognition DOES NOT lead to new insight, it is new insight which allows for the recognition of a ‘pattern’, the latter being an allocation of possible bias.

  • +
  • +
  • ..

  • +
+

What challenges do you face when trying to simplify complex concepts in your field, and how do you decide which details to focus on?

+
    +
  • Absence of a terminology / jargon to describe a new idea. :+1:

  • +
  • Similar to above, when teaching often students know what they want to achive, but don’t have the termonology to express it, so working through what they want is helpful, after teaching them some termonology.

  • +
  • Whatever is most useful to the learner first?

  • +
  • I work with researchers in different fields. I don’t always fully understand their domain knowledge but I can take the basiscs or generalities and get code that works for them

  • +
  • A very practical problem is trying to resist going for a coffee in the midst of taking a shot at a complex concept, in the hope that the true details are to be found in the coffee.

  • +
  • not all information is easy to find or a lot of conflicting information or even sometimes imformation explosion

  • +
+

How do you determine the priority of tasks when designing algorithms for your academic projects, and what criteria do you use to ensure that the most critical tasks are addressed first?

+
    +
  • Working chronologically when going through a problem - start at the beginning.

  • +
  • What gives the more insight with the least effort can be a nice start

  • +
  • Talk to colleagues and Subject matter experts to understand various perspective to decide and prioritize.

  • +
  • Logic will get you from A to B. Imagination will take you everywhere. - Albert Einstein.

  • +
  • ..

  • +
+
+
+
Questions from the audience
+
    +
  • About the 4 core concepts, is this based on the model of how human brain works and perceives vision / abstract ideas?

  • +
  • I don’t know if it’s based on how the brain works, but it’s related to creating a framework for solving programming programs that has been extrapolated to solve any other problem as well.

  • +
  • Devil’s advocate question: cooking (by recipe) actually employs all four principles outlined here and has done so since before the advent of computers. Why then is this concept presented as “computational”?

    +
      +
    • Random aside, this is an interesting connection to our “cooking metaphor to HPC”

    • +
    +
  • +
  • Devil’s answer to the Devil’s advocate: Great question, cooking, as far as the act happens in the Devil’s kitchen, does not employ numerical algorithms. The Devil introduced the computer precisely to make man lose apetite for that what is cooked in the Devil’s kitchen to be served to all. Only then can the Devil eat the cake and keep it too …

    +
      +
    • Well, an algorithm without numbers is still an algorithm, i.e. a set of rules :)

    • +
    +
  • +
  • Are there other names for this technique? I may have missed something crucial, but it strikes me as ‘logical thinking’ in a way.

    +
      +
    • Yes, you could also just see it as problem solving. Most people know how to do it and if you’ve worked with programming, you’ve probably applied it. It can be the case that it’s very obvious to some, but not to others.

    • +
    +
  • +
  • Any chance we can ge a link to the slides?

    +
      +
    • They are in the course material: https://coderefinery.github.io/train-the-trainer/computational-thinking/ :thumbs_up:

    • +
    +
  • +
+
+
+
Exercise questions to discuss
+
    +
  1. Conceptually would the strategies provided by computational thinking help you in completing tasks more efficiently?

  2. +
+
    +
  • Room 1:

    +
      +
    • divide and conquer technique

    • +
    • We discussed what happens if you don’t use these, since they are so natural

    • +
    +
  • +
  • Room 2:

    +
      +
    • in some cases yes, if the task is not too small

    • +
    • not sure if more efficiently but it does help at least getting strted

    • +
    • Computational thinking is an extension of what others have called solutionism: the belief that any given problem can be solved by the application of computation. Whatever the practical or social problem we face, there is an app for it. - James Bridle

    • +
    +
  • +
  • Room 3:

    +
      +
    • Helps in starting the task.

    • +
    • For many it is the normal way to do problem solving. Also in Agile & Scrum methodlogies.

    • +
    +
  • +
  • Room 4:

    +
      +
    • Yes, it helped me during my scientific research to manage multiple projects and research publications simultaneously.

    • +
    • +
    +
  • +
+
    +
  1. Do you think that the effectiveness of computational thinking depends on the person’s personality type?

  2. +
+
    +
  • Room 1:

    +
      +
    • yes, we agree it’s quite different. But good vision and motivation this can be effective

    • +
    +
  • +
  • Room 2:

    +
      +
    • yes, laying out all the steps necessary to achieve an overall goal can be very daunting; some people are not good at/ comfortable with following fine-grained instructions

    • +
    • once the problem is broken down, different personalities might choose different ways to tackle the parts

    • +
    • The degree to which something, that is a result of what one means by ‘Computational Thinking,’ is successful in producing a desired result, that is success, cannot be a function of personality.

    • +
    +
  • +
  • Room 3:

    +
      +
    • Yes. Different people have different ways to communicate.

    • +
    • Online tools vs pen and paper

    • +
    +
  • +
  • Room 4:

    +
      +
    • We are all agree that it depends on the personality type but it could be learned and trained

    • +
    +
  • +
+
    +
  1. Would this type of thinking be an option for you to integrate into your current workflow?

  2. +
+
    +
  • Room 1:

    +
      +
    • Yes; we didn’t know the name explicitly; but we use it

    • +
    • It’s quite important for

    • +
    +
  • +
  • Room 2:

    +
      +
    • I’m already doing it implicitly :smile: :+1: :+1:

    • +
    • Writing a program is like writing a song, its all about the tune, lyrics are merely the necessary nuisance a coder needs to put up with. The latter can, if so written, result in a lot of noise.

    • +
    +
  • +
  • Room 3:

    +
      +
    • Easy if you are working alone. But different team may have their own ways of working (inertia). One way would be then to gradually show the rest of the team its effectiveness.

    • +
    • https://teamtopologies.com/key-concepts

    • +
    +
  • +
  • Room 4:

    +
      +
    • We are using it in our daily life so it’s already an option for us, only the terminologies are a bit new.

    • +
    +
  • +
+
+
+
+

Episode 2 : Teaching philosophies

+

Materials: https://coderefinery.github.io/train-the-trainer/teaching-philosophies/

+

Questions to discuss:

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+

Breakout Room exercise

+
    +
  • Room1

    +
      +
    • Motivation

      +
        +
      • For best practices in teaching, learning from each other, collaboration

      • +
      +
    • +
    • Learning applied tech is like an apprecentiship: there is theory, but real learning happens by co-working with others.

    • +
    • Worse is better: teach what can be used more quickly and it can be improved later

    • +
    • +
    • I think there are two bits of teaching - teach the basics and terminology so people know what they want to know, and then teaching how to find out how to do things like Richard said - how to find answers yourself.

    • +
    • Using Jupyter notebooks - good for learning a technique, but not for learning the basics.

    • +
    • Possibly command line usage has a branding problem - “programming other programs”?

    • +
    • the skills we learn in CR training are expected to stay , it is not exam oriented

    • +
    +
  • +
  • Room 2

    +
      +
    • State objectives clearly and repeat them a few times

    • +
    • Try to keep it informal, interactive, flexible

    • +
    • Helps when having practical tasks in mind for the materials taught

    • +
    • Leave some reasoning to the learner, not always giving full answers

      +
        +
      • How to deal with frustration though: try some personal approaches, more clues…

      • +
      +
    • +
    • The mediocre teacher tells. The good teacher explains. The superior teacher demonstrates. The great teacher inspires. — William Arthur Ward

    • +
    • Teaching kids to count is fine, but teaching them what counts is best. –Bob Talbert

    • +
    +
  • +
  • Room 4

    +
      +
    • Question 1: What is your motivation for taking this training?

      +
        +
      • Currently do instruction, wanting to improve as an instructor and helper when conducting software carpentries.

      • +
      • Planning to start some side hustles providing online courses and why not joining the CR in the near future

      • +
      +
    • +
    • Question 2: How structured or informal are your own teaching needs?

      +
        +
      • More recently, follow software carpentries, but look into what aspects can be tailored to keep to different time slots.

      • +
      • I used to be more informal in the past, repetetive practice sessions. Would like to be more structured given the teaching tools.

      • +
      • I’ve done life-coaching and some teaching but I feel i’m both of them

      • +
      +
    • +
    • Question 3: What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

      +
        +
      • Smaller size, and more targetted.

      • +
      • Collaborative tools and targeted audience working with small groups

      • +
      • Academic probably focuses on an audience with a more focused/narrow background, while this style encompasses a wider audience.

      • +
      • Academic teaching keeps theory and practical lab sessions very separate, whereas carpentries combine both.

      • +
      +
    • +
    • Question 4: What other skills need to be taught, but academic teaching isn’t the right setting?

      +
        +
      • Public speaking, collaborative meeting skills

      • +
      • Industrial cases and related work skills

      • +
      +
    • +
    +
  • +
+
+
+

Episode 3: Co-teaching

+

Materials: https://coderefinery.github.io/train-the-trainer/co-teaching/

+
    +
  • In general: Co-teaching is a beast with at least two personalities each of which

    +
      +
    • demand higher preparation requirements

    • +
    • face remarkable complexity in terms of coteacher coordination

    • +
    • in the virtual component face shortcomings related to the technical equipment and the failure of the human factor

    • +
    +
  • +
+
    +
  • Co-teaching requires the framework of co-operative learning. Team teaching does not by default translate into parallel learning, and vice versa.

  • +
+
    +
  • Re: CodeRefinery in-person beginnings – I agree with the “didn’t work so well in-person”, I’m not sure if it’s that we weren’t as ready for it, or that the different characteristics made it not work so much

  • +
  • How do the downsides compare to a single instructor monologuing?

    +
      +
    • That’s a great question! The main difference is that a single instructor can teach himself to be good (i.e. not just boring monologuing) alone, while for teams of 2+ to work well, everyone needs to be baseline-competent. So the effort to avoid downsides gets reduced if (and only if) all team members share it.

    • +
    +
  • +
+
+

Exercise/Discussion: https://coderefinery.github.io/train-the-trainer/co-teaching/#exercise

+

Questions:

+
    +
  • Have you already tried this or similar model in your teaching?

  • +
  • Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best?

  • +
  • Have you tried or seen a different model for two instructors to present? Please share with us how it works.

  • +
+
+
    +
  • room 1

    +
      +
    • We have tendend to do presenter/interviewer more

    • +
    • challenges are co-teaching with different personalities

    • +
    +
  • +
  • room 2

    +
      +
    • Main challenge: finding enough personell :smile:

    • +
    • It’s not always possible/feasible to have colleagues co-teaching

    • +
    • A combination of both, but presenter and interviewer could be difficult to plan an to follow

    • +
    • Guide and demo-giver with technical / non-technical roles could be nice

      +
        +
      • How to plan the guide and demo-giver

        +
          +
        • First guide, then demo

        • +
        • Demo, then guide describes

        • +
        +
      • +
      +
    • +
    • Alternative model: main presenter + ‘technical expert’

      +
        +
      • main presenter introduces concepts from a birdseye view and passes on to the technical expert for additional details, experiences and answers to questions from the audience

      • +
      +
    • +
    • We frequently do a classical division: on person in presenting, one or more are answering questions in the chat; there is rarely any interaction between them however

    • +
    +
  • +
+
    +
  • As has been pointed out by Paolo Freire, in general, ‘education is suffering from narration sickness’ … ‘The outstanding characteristic of this narrative education, then, is the sonority of words, not their transforming power’. Perhaps one approach could be to rephrase the question after having the answer: It is not apriori about the model implemented, it is about whether that what was implemented was judged aposteriori to have succeeded in becoming, or at least could pretend to have done so, the intended context matched model implementation it probably was computed to be.

  • +
+
    +
  • room 4

    +
      +
    • the co-teaching approach does not seem to be widely practiced

    • +
    • it can be interesting to see “mistakes” which are less likely to happen in solo-teaching?

    • +
    • co-teaching can be nicer for audience but maybe more stress/anxiety for instructors to prepare? more stress in terms of not knowing all the questions in advance. less stress worrying about forgetting something.

    • +
    +
  • +
+
+
+

Teaching gems

+

(scroll up to find the green box “Episode on teaching gems”)

+

What’s your favorite way of teaching? Any nice tools you use?

+

Has anyone found a nice online tool to draw?

+
    +
  • I love this tool suite https://excalideck.com/

    +
      +
    • For drawing https://excalidraw.com/

    • +
    +
  • +
  • I have seen Miro …

  • +
  • I think the Code Refineries use something for their graphics that looks a bit ‘cartoony’ - but I cannot remember what it is called!

    +
      +
    • Drawn on remarkable and then coloured and tidied up in Inkscape. :+1:

    • +
    +
  • +
  • I am a big fan of remarkable. I think sharing option is fairly good. Unfortunately bit expensive tool.

    +
      +
    • true, for me it was worth it already for the pdf annotation for research papers, cannot read on computer screen

    • +
    +
  • +
  • https://webwhiteboard.com/

  • +
  • https://www.youtube.com/watch?v=4-l8MY5kYGc

  • +
  • Figma and Kahoot are useful as well

  • +
+

Screenkey: Screenkey for showing keyboard shortcuts

+
    +
  • Is there a Windows version people can recommend?

    +
      +
    • I found this list of alternative for windows users like me: https://alternativeto.net/software/screenkey/ :+1:

    • +
    +
  • +
  • I sometimes use the on-screen keyboard already provided by the OS :+1:

  • +
+
+
+
+

Wrapup

+
    +
  • Next session Tuesday September 3rd 9 CEST: About teaching & cool things we all would like to share

  • +
  • All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14 CEST

  • +
  • Preparations for next week will be sent out by e-mail

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • The co-teaching lesson and experiences from others

  • +
  • Discussions were quite good, had a nice group

  • +
  • Breakout rooms and collaborative tools

  • +
  • Computational thinking and co-teaching are interesting ideas! I have seen it before, but never knew or even recognized it was a method.

  • +
  • Thanks for group discussions working with my chat only interaction! :smile:

  • +
  • ..

  • +
+

What one thing would you improve about this session?

+
    +
  • Minor point - it would be useful to have the teaching gmes box at the bottom of the document rather than the top - tricky to scroll between! In the end I opened two windows which was easier.

    +
      +
    • Thanks, yes agree. Also had that problem, but did not want to move it in between.

    • +
    +
  • +
  • The meaning of teaching “philosophy” wasn’t very clear, felt more like teaching “styles”

    +
      +
    • Thank you, we will take that into consideration

    • +
    +
  • +
  • Some prepared slides to present for an intro about the topics

    +
      +
    • You mean in addition to the materials? To use in the beginning of each session?

    • +
    +
  • +
  • The instructor views segment could be named as additional material, if it was not meant to be discussed within the course.

    +
      +
    • Thank you, we will take that into consideration

    • +
    +
  • +
+

Any other comments?

+
    +
  • Keeping it short and sweet: If at first you don’t succeed in teaching, try to explain it like you’re talking to a room full of cats. Caveat: In a room full of computational thinkers maybe if you tell students that the brain is a computational device that is forbidden, they might get excited and start using it.

  • +
+
+
+

Day4: Session 4 (3.09.24) - Streaming and video editing

+
+

:calendar: Schedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 10.00

Why we stream & Behind the scenes

10.15 - 11.00

8.15 - 9.00

10.00 - 10.15

Break

11.00 - 11.15

9.00 - 9.15

10.15 - 10.35

Video Editing

11.15 - 11.35

9.15 - 9.35

10.35 - 10.55

Exercise: Video Editing

11.35 - 11.55

9.35 - 9.55

10.55 - 11.10

Break

11.55 - 12.10

9.55 - 10.10

11.10 - 11.30

Open Broadcaster Software(OBS) introduction

12.10 - 12.30

10.10 - 10.30

11:30 - 11:50

OBS setup & what next

12.30 - 12.50

10.30 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+

:icecream: Icebreaker

+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :coffee: +

  • +
  • :runner:

  • +
  • :tired_face: Tired!

  • +
  • :nerd_face:

  • +
  • +
  • :cloud: :tea:

  • +
+
+
+
Introduction in breakoutrooms
+
    +
  • Name / Affiliation / Location

  • +
+

What’s the most number of people you have taught to?

+
    +
  • 20 at a time, with 1 asleep, 2 fidgiting with some silly device and the rest were… well… staring at their good luck… straight ahead it was of course, right before them.

  • +
  • ~35

  • +
  • ~80 in a lecture in a previous (lecturer) role, 26 in a training course setting

  • +
  • ~30

  • +
  • ~50 in training spaces and more than 100 for public audience talk

  • +
  • 35 (software carpentry)

  • +
  • CodeRefinery answer: The biggest ones are maybe 200-300 people. “small” for a stream is ~100 people.

  • +
+

What’s the most number of people you have taught with?

+
    +
  • 5 or so

  • +
  • 2 or 3 in total

  • +
  • 3, as in three, none of them smiling. I wish I could figure out why… it was such fun really…

  • +
  • 7

  • +
  • 2 or 3

  • +
  • 3 (helpers, not really co-teaching)

  • +
  • CodeRefinery answer: our biggest workshops are something like 10-20 people helping out in many different roles.

  • +
+

How can you divide teaching into separate independent tasks?

+
    +
  • By content blocks, having roles like main and assistant…

  • +
  • Having responsibility for different sections of the course.

  • +
  • Wow, now thats what we call a question… bravo… indeed, how does one separate sleeping and snoring into separate independent tasks…

  • +
  • Course, exercices, resources, tools and forms.

  • +
  • Different people teach different topics

  • +
  • CodeRefinery answer: the big logical blocks are instructors, in-person and breakout room helpers, and Notes-questions answers.

  • +
+

What’s the most interesting or useful thing you’ve learned from an online workshop, and how have you applied it/planning to apply in your life or work

+
    +
  • Having breaks every hour or so

  • +
  • New approach to screensharing, using the ‘portrait’ approach

  • +
  • Manage breathing: reduce stress and use silence to let the audience grasp what you’re saying

  • +
  • Well, the most interesting or useful thing I’ve learned from online workshops is how not to conduct a workshop, or at least some elements of the same, and I have applied this understanding by engaging in the global effort to discover more about how not to conduct a workshop, or at least some elements of the same, with the motto: That’s one small step for a man, one giant leap for mankind..

  • +
+
+
+
+

:question: Questions

+
+
+

Why we stream

+
    +
  • If during streaming there is no interaction between the teacher and the audience, why don’t we just record the lectures and stream them? So one can do a better job, perhaps?

    +
      +
    • Streaming it making it a “thing” that’s a group experience. It feels good to be a part of it, so we hope that encourages people to actually attend. All the mass Q&A is fun, and the audience helps to make it easier to present. Still, this is a good question.

    • +
    • I really appriciate it being “a thing”. If it was just recorded, I would say I would watch it tomorrow, and then I never would.

      +
        +
      • But then you can just fake it, and still have all the breakout rooms and collaborative document and so on. I appreciate the value of having a proper “event”.

        +
          +
        • I think I follow you, but if you pre-recorded the talking bits, then the presentors couldn’t change what they do based on the feedback in the shared document.

          +
            +
          • true, but I assumed that the teachers were too busy to actually do that. The more (less )division of labor between the teachers and the helpers (or collaborative document editors), the more (less) sense it makes to pre-record - IMHO

          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • What interaction options do ‘streamers’ use, e.g. on Twitch/YouTube (not Code Refinary)?

    +
      +
    • I’m besides chat and things that happen in chat, I’m not sure. The Notes-doc is definitely unique to us.

    • +
    +
  • +
  • Streaming is a kind of exercise for the movie star type. If you cannot be one, act like one, pretend, fool the listener into thinking you are one, take their brains and emotions under control. And if they don’t leave the session with tears of love for learning running down their chubby cheeks you know who to kick for doing a job just that bit worse than it should have been necessary.

  • +
  • Have you kept track of streming stats? like how many people logged in and stayed troughout, how many interacted?

    +
      +
    • Yes please, it would be good to see the stats

    • +
    • Here is stats repo

    • +
    • Thanks, I get a 404 error, is it private?

    • +
    • No, I don’t think so. https://github.com/coderefinery/workshop-stats

    • +
    • Still get 404. Does it work for anyone else?

      +
        +
      • Yeah I think it’s private. We need to fix this…

      • +
      +
    • +
    +
  • +
  • How big is small (10-15), medium (~30-40)?

    +
      +
    • I would say below 50 is small.

    • +
    +
  • +
  • Have you considered scaling to more events instead of to a larger audience? I mean, this seems the opposite of scaling, but this kind of content would be more useful the more often is it taught (“I need to learn GIT/Python/* in December!”)

    +
      +
    • We would, but right now we simply don’t have enough time and people to do more small events. But yes, “scheduling conflict” is a big problem - the best we can do right now is written material+videos to follow up on (and hope it’s interesting enough)

    • +
    • Python for Scientific Computing 5-7/November/2024

      +
        +
      • This was just an example. I mean, if I am a PHD student that needs to start working on a topic on Month X which happens to be inconveniently placed in the year, I will not benefit as much from having a workshop at Month X+3

        +
          +
        • The materials are open and the videos are publically available on YouTube channel

          +
            +
          • What’s the ratio of people watching videos afterwards vs people attending the event? That ratio can give an idea of the popularity of the two possible approaches.

          • +
          +
        • +
        +
      • +
      +
    • +
    • The more you scale up the less interactive the course / workshop will need to be. It then becomes a question of priorities, and if teaching is a lower priority then learning than I guess there really should be no prizes for guessing which approach should reign the airwaves.

    • +
    +
  • +
  • I guess outside Europe / Africa, time zones could be a problem?

    +
      +
    • yes, that is true

    • +
    • +
    +
  • +
  • Sorry, I might have missed this: have you been rehearsing and/or doing dry runs?

    +
      +
    • With instructors I like to try to do a dry run. I often don’t do a live broadcast dry run these days since I’m confidente enough, but when you are just starting, it’s a good idea.

    • +
    +
  • +
  • Do you always use Zoom for the ‘presenter end’ or have you tried other things? Teams? Jitsi? etc.?

    +
      +
    • we use mostly zoom

    • +
    • It was first pioneered using Jitsi. You can probably use others, too.

    • +
    +
  • +
  • A comment: for deRSE24 we have been using the GWDG streaming service and OBS, it worked quite well (with a 20s delay or so)

    +
      +
    • Cool! Yes, there is plenty of livestreaming options. Twitch+our OBS config gives us 2-3s of latency (which is low enough for live Notes interaction). You might be able to tune this if needed.

    • +
    +
  • +
+
+
+

Behind the stream

+
    +
  • Does OBS take a lot of RAM or CPU? what are the specs on your machine?

    +
      +
    • Richard have a relatively powerful computer with 8 AMD CPUs.

    • +
    • 4 CPUs are relatively enough for a good OBS setup, most important is a stable internet connection (ideally wired).

    • +
    • An extra monitor is recommended for the setup

    • +
    • See the hardware notesrecommendation here

    • +
    +
  • +
  • Do you do a screenshare from Zoom -> OBS or OBS -> Zoom?

    +
      +
    • Instructors share to Zoom, OBS captures Zoom, OBS sends to the world.

    • +
    • When I am using OBS sfor a single-person presentation recording, I go the other way: OBS captures my desktop/camera, OBS generates the preview window, and then Zoom captures and broadcasts the preview window.

    • +
    +
  • +
+
+
+

Video editing

+
+
Poll
+
    +
  • Have you tried video editing? Add ano as answer below

    +
      +
    • yes: ooooo

    • +
    • no :

    • +
    • Video editing makes all the difference. I have never known a way to avoid this sacred of steps, so to speak. In short, no recording can ever be production ready by default in the books of the wiser among the streamers. In fact, during the editing one can considerably refine and improve the learning experience in great ways. But then one would need to invest both time and effort.

    • +
    +
  • +
  • If yes Which are the tools you use?

    +
      +
    • Windows Movie Maker / ClipChamp

    • +
    • (raw stream from Zoom)

    • +
    • I think it was shotcut - I did only basic trimming

    • +
    • Kdenlive

    • +
    • Clipchamp, OpenShot, Sony Vegas

    • +
    • also ffmpeg from command line to cut beginning and end

    • +
    +
  • +
+
+
+
Questions
+
    +
  • What is Whisper?

    +
      +
    • Open-source model from OpenAI that converts speech to text transcripts.

    • +
    • this one? https://openai.com/index/whisper/

    • +
    • curious if anyone has tried it with languages other than english

    • +
    • I heard that one of my spanish colleague try it with another software. I don’t remember the tool. But with AI bloom there are many licensed tools that can do it with fifferent language

    • +
    +
  • +
  • What do you use to crop the videos?

    +
      +
    • I see now, ffmpeg

    • +
    +
  • +
  • how to merge multiple parts in one? I asked because you edited only the icebreaker part?

    +
      +
    • you can manage it in input part, see ffmpeg-editlist readme.

    • +
    +
  • +
  • Do you generate custom thumbnails for the video?

    +
      +
    • no, because of the time, but its good to have. If we had a volunteer to manage that, then we should!

    • +
    +
  • +
  • Does anyone recommend any other (GUI) tools that work well? ffmpeg is very new to me!

    +
      +
    • if you want a basic trimming and editing , you can use Quicktime player/imovies on mac

    • +
    • Clipchamp as the Microsoft video editor

    • +
    • Thanks :smile:

    • +
    +
  • +
  • How do subtitles get uploaded to YouTube?

    +
      +
    • You upload the video and subtitles as part of upload.

    • +
    • :+1:

    • +
    +
  • +
  • How does codewhisperer compare against youtube’s automatically generated subtitles?

    +
      +
    • by experience, whisper was better couple of years ago. We haven’t compared it recently

    • +
    • I guess and advantage is that you can edit whisper subtitles in case something is odd or whatever, probs cannot do that in YouTube

    • +
    +
  • +
+
+
+
+

Open Broadcaster Software (OBS) introduction & setup

+
    +
  • Are the profiles public?

    +
      +
    • Yes, you can see it here

    • +
    +
  • +
  • Does it work in Linux+Wayland?

    +
      +
    • I think everything we do with OBS would.

    • +
    +
  • +
+
+
+
+

Wrapup

+ +
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • ffmpeg seems great, will give a try for fun!

  • +
  • great to see everything in practice!

  • +
  • Very insightful to see what happens behind the scenes.

  • +
+

What one thing would you improve about this session?

+
    +
  • Some more interactivity would’ve been nice but since most the group preferred demo instead of exercise perhaps it’s only a personal opinion

  • +
  • It would have been good to share the OBS profiles repo beforehand in the setup email - so I could have had it to hand. (https://github.com/coderefinery/obs-config)

    +
      +
    • +1 good idea, we should do this next time

    • +
    +
  • +
  • Perhaps a simpler starter OBS setup?

    +
      +
    • Good idea… I should have, but basically ran out of time to prepare.

    • +
    +
  • +
+

Any other comments?

+
    +
  • Cool to see the switch from RSE to trainer to AV guy, impressive!

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/objects.inv b/branch/comms/objects.inv new file mode 100644 index 0000000..74f204d Binary files /dev/null and b/branch/comms/objects.inv differ diff --git a/branch/comms/obs-config/index.html b/branch/comms/obs-config/index.html new file mode 100644 index 0000000..f8717f9 --- /dev/null +++ b/branch/comms/obs-config/index.html @@ -0,0 +1,276 @@ + + + + + + + Open Broadcaster Software (OBS) setup — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Open Broadcaster Software (OBS) setup

+
+

Objectives

+
    +
  • See how to configure OBS using the pre-made CodeRefinery scene +collections

  • +
  • Modify the collections to suit your needs.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: ?? min

  • +
  • Hands-on: ?? min

  • +
  • Q&A: ?? min

  • +
+
+ +

In this lesson, we’ll see how to configure OBS from scratch for your +purposes. We’ll do this by deleting the instructor’s configuration +and trying to recreate it

+

This section is short, since it has never been done before: we’ll just +give it a short and update the lesson later.

+
+

CodeRefinery OBS configs

+
    +
  • CodeRefinery configs are shared in a repository: +https://github.com/coderefinery/obs-config

  • +
  • These can be imported to pre-configure some things

  • +
  • There are two types of configs:

    +
      +
    • Profiles

      +
        +
      • Servers, resolutions, audio, video, etc.

      • +
      +
    • +
    • Scene collections

      +
        +
      • The graphical layouts.

      • +
      +
    • +
    +
  • +
+
+
+

Installing the OBS config

+
    +
  • Clone the git repository.

  • +
  • Import the profile and scene collections under their respective +menus.

  • +
+
+
+

Initial setup

+
    +
  • Click through each menu and change anything that is needed

  • +
  • Set the streaming server

  • +
+
+

The instructor will go through the setup.

+
    +
  • Reset configuration: mv .config/obs-studio/ .config/obs-studio-old/

  • +
  • Import profiles/TeachingStreamingv3/

  • +
  • Import scenes/TeachingStreamingZoomv3.json

  • +
+
+
+
+

Set up the remote control

+
    +
  • Create a Python environment and install it: pip install https://github.com/coderefinery/obs-cr/archive/refs/heads/master.zip

  • +
  • Run it: python obs_cr/control.py localhost:4445 TOKEN --broadcaster

  • +
  • There are more options but let’s not cover them yet… and leave +this for a hands-on session.

  • +
+
+
+

Setup before each course

+
    +
  • Re-confirm audio

  • +
  • Re-confirm each scene

  • +
  • Test everything

  • +
  • rkdarst has a rather long +checklist, +but each individual step is short.

  • +
+
+
+

Q&A

+

We’ll answer audience questions.

+
+

Keypoints

+
    +
  • Most of our configuration has been OBS may seem complicated, but it’s a graphical application and most +pieces make sense once you know how it works.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/obs/index.html b/branch/comms/obs/index.html new file mode 100644 index 0000000..205a80a --- /dev/null +++ b/branch/comms/obs/index.html @@ -0,0 +1,259 @@ + + + + + + + Open Broadcaster Software (OBS) introduction — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Open Broadcaster Software (OBS) introduction

+
+

Objectives

+
    +
  • Understand that OBS is a video mixer.

  • +
  • Understand the basic controls and features of OBS.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 15 min

  • +
  • Q&A 5 min

  • +
+
+ +

In this episode, you’ll get more familiar with the OBS portion of the +streaming setup. You’ll see how it’s used, but not yet how to +configure it from scratch. You’ll learn how to be a “director”.

+
+

What is OBS?

+
    +
  • Formally “OBS Studio”

  • +
  • Most commonly known as a livestreaming application.

  • +
  • Open source, free.

  • +
  • Cross-platform, easy to use screencasting and streaming application.

  • +
  • Real-time video mixer.

  • +
+
+
+

OBS user interface

+
    +
  • We’ll click through each view.

  • +
  • What does each view do?

  • +
  • Let’s click through the buttons.

  • +
  • Let’s see the important config options.

  • +
+
+
+

OBS during a course

+
    +
  • What management is needed.

  • +
  • The control panel.

  • +
  • Audio.

  • +
  • Adjusting windows and so on.

  • +
+
+
+

Hardware requirements

+
    +
  • Reasonably powerful broadcast computer

    +
      +
    • CodeRefinerys streaming computer is 8 CPU AMD, 64GB memory

    • +
    • That is way overkill: a powerful laptop can probably do this.

    • +
    +
  • +
  • Large second monitor for laying out the windows you capture

  • +
  • Stable internet connection (wired preferable)

    +
      +
    • CodeRefinery’s broadcast is the slowest purchasable: 100 Mbit down / +25Mbit up

    • +
    +
  • +
+
+
+

Q&A

+

We’ll answer audience questions.

+
+
+

See also

+ +
+

Keypoints

+
    +
  • OBS may seem complicated, but it’s a graphical application and most +pieces make sense once you know how it works.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/overview/index.html b/branch/comms/overview/index.html new file mode 100644 index 0000000..c63b95c --- /dev/null +++ b/branch/comms/overview/index.html @@ -0,0 +1,418 @@ + + + + + + + A workshop seen from different perspectives — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

A workshop seen from different perspectives

+
+

Objectives

+
    +
  • Understand the general structure of CodeRefinery workshops and why it is the way it is

  • +
  • Get to know the different roles of a workshop and which ones are the most essential ones

  • +
  • Understand the importance of installation instructions and how they contribute to learners success

  • +
  • Understand the importance of onboarding and a welcoming community for volunteers in a workshop

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 15 min

  • +
  • Roles journeys can be shortened to looking only at instructor role.

  • +
+
+
+

Note

+

This episode focuses on the large scale streamed workshop setup. Some of the features can also be applied to smaller scale workshops though.

+
+
+

Discussion

+
+

Discussion

+

In breakoutrooms: choose one or two questions to talk about your own experiences; summary in collaborative notes:

+
    +
  • What kind of roles have you been in yourself regarding workshops?

  • +
  • How were you prepared for your role?

  • +
  • What are the things you would like to know before a workshop?

  • +
  • How are you preparing your participants for your trainings?

  • +
  • What was the best workshop experience for you as learner, helper or instructor? What made it great?

  • +
+
+
+
+

One workshop - many parts

+
+../_images/CR_workshop_setup.png +
+

Image showing the different phases of a CodeRefinery workshop described below. Also showing that while there is only two people teaching, many people work behind the scenes.

+
+
+
+

Before the workshop

+
    +
  • During winter/summer: “Someone” takes the coordinator role for the next workshop

  • +
  • Coordinator fills other roles:

    +
      +
    • Coordinator: collects necessary lesson updates, supports other coordinators

    • +
    • Registration coordinator: Sets up web page, starts and manages registration

    • +
    • Instructor coordinator: Finds instructors and onboards them

    • +
    • Advertising coordinator: Prepares advertizement texts and finds people to distribute them

    • +
    • Team coordinator: Gathers local organizers/teams

    • +
    • Bring your own code session coordinator: If available, offer BYOC session after main workshop

    • +
    +
  • +
  • Instructor: Onboarding with (instructor-) coordinator and previous instructor of lesson; update of lesson materials (urgent issues and personal touches)

  • +
  • Local organizer/Team lead: Group onboarding ~ week/or two before workshop

  • +
  • Learner: Gets installation instructions, invited to installation help session, workshop info from event page and summary via e-mail

  • +
  • Collaborative notes manager sets up the notes document

  • +
+
+

Note

+

Onboarding manuals

+
    +
  • Outline of what will happen during the workshop

  • +
  • Discussion of different strategies to handle the exercise sessions

  • +
  • Lowering the barrier to ask for support by meeting some organizers

  • +
  • Q&A

  • +
+
+
+

Note

+

Installation instructions

+
    +
  • Instructions for all operating systems

  • +
  • Goal: Learners leave the workshop and are ready to apply the learned tools and techniques to their own work

  • +
  • Support session for installation challenges

  • +
+
+
+
+

During the workshop

+
+../_images/BYOC.png +
+

Image showing the different ways learners can do the exercises. No matter which way they choose, they always watch the stream and interact with instructors and organizers via collaborative notes. Individual learners do the exercises alone, people in online or local classrooms in addition get to discuss with their peers.

+
+
+
    +
  • Everyone watches stream

  • +
  • Co-instructors +- Present content +- Answer questions in collaborative notes

  • +
  • Collaborative notes manager

    +
      +
    • Keeps the collaborative notes clean

    • +
    • Helps answering questions

    • +
    • Adds sections

    • +
    • Archives the document after each day

    • +
    +
  • +
  • Learners do exercises individually or in team

  • +
  • Local organizer / Team lead

    +
      +
    • Guides learners through exercises

    • +
    • Facilitates discussion

    • +
    +
  • +
  • (Registration-) coordinator sends out e-mails to participants after each day (summary + preparation)

  • +
  • Director/Broadcaster manages the streaming (see session 4)

  • +
+
+
+

After the workshop

+
    +
  • Coordinator collects lessons learned based on experience and feedback and turns them into issues

  • +
  • Coordinator organizes debriefing week after the workshop, where anyone can join to give feedback

  • +
  • “Someone” sends out post-workshop survey half a year after workshop

  • +
  • Coordinator organizes “Bring your own code” sessions

  • +
  • Broadcaster prepares and shares recording (see session 4)

  • +
+
+

Note

+

Bring your own code sessions

+

We want to support learners to apply what they have learned in the workshop to their own work by offering one/two sessions where they can drop in, and discuss challenges with CodeRefinery instructors and helpers.

+
+../_images/welcome.png +
+

Image showing a classroom learning about git leading to a discussion between student and teacher to start a welcoming environment for asking for help.

+
+
+
+
+
+
+

This sounds like a lot of people and time investment!

+
    +
  • Many roles can be combined or adjusted as needed

  • +
  • Some roles can be taken on by multiple people

  • +
+

So how many people are needed for this kind of workshop?

+
    +
  • Recommended minimum: 2-3 people

  • +
  • Optimum: ~ 4-5 people +The more people you involve, the more time goes into coordination work.

  • +
+
+
+

How did we get to this setup?

+
    +
  • Collaborative in-person workshops since 2016 around the Nordics

  • +
  • Moved online in 2020

  • +
  • Started with “traditional zoom” workshops, breakoutrooms, volunteer helpers

  • +
  • Thought about scaling and ease of joining -> current setup (More about this in session 4)

  • +
  • Continuous development

  • +
+

We also still do smaller scale local workshops, if instructors are available. +You can offer your own CodeRefinery workshop by inviting other CodeRefinery instructors. +You can also reuse single lessons and integrate them into your own teaching.

+
+
+

Workshop roles and their journeys

+
+

Individual learner journey

+
    +
  • Registration

  • +
  • Installation

  • +
  • (if appicable: Invited to local meetup)

  • +
  • Workshop

    +
      +
    • Watch stream

    • +
    • Q&A in notes

    • +
    • Exercises alone or in team

    • +
    • Daily feedback

    • +
    +
  • +
  • Debrief/ Feedback session

  • +
  • Post workshop survey

  • +
+
+
+

Instructor journey

+
    +
  • Indicate interest in CodeRefinery chat

  • +
  • Onboarding

  • +
  • Lesson material updates

  • +
  • Teaching

  • +
  • (if wished: supports answering questions in notes)

  • +
  • Debrief

  • +
+
+
+

Team lead / Local host journey

+
    +
  • Registration

  • +
  • (if applicable: run own registration)

  • +
  • Onboarding

  • +
  • Workshop

    +
      +
    • Watch stream

    • +
    • Facilitate exercises/discussions

    • +
    • Daily feedback

    • +
    +
  • +
  • Debrief / feedback / survey

  • +
+
+
+

Other roles

+

Director and broadcaster roles will be discussed in Session 4. +For more in-depth descriptions and other roles (host, instructor, registration coordinator, etc), see also our CodeRefinery manuals.

+
+
+
+

Different roles as stepping stones for community involvement

+
+../_images/steps.png +
+

Image showing a person jumping from step to step following learner, helper, expert helper, co-instructor, co-organizer.

+
+
+

There is no “one way” to get involved. Do what feels right. +Interested in teaching with us? Let us know and we can discuss what is a suitable path for you!

+
+

Keypoints

+
    +
  • CodeRefinery workshops are a collaborative effort with many different roles

  • +
  • Onboarding the different roles is one key aspect of our workshops

  • +
  • Everyone has their own path

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/screenshare/index.html b/branch/comms/screenshare/index.html new file mode 100644 index 0000000..a16afec --- /dev/null +++ b/branch/comms/screenshare/index.html @@ -0,0 +1,565 @@ + + + + + + + How to prepare a quality screen-share — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

How to prepare a quality screen-share

+
+

Objectives

+
    +
  • Discuss the importance of a well planned screen-share.

  • +
  • Learn how to prepare and how to test your screen-share setup.

  • +
  • Know about typical pitfalls and habits to avoid.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 15 min

  • +
  • Exercises: 15 min

  • +
+
+
+

Share portrait layout instead of sharing entire screen when teaching online

+
    +
  • Many learners will have a smaller screen than you.

  • +
  • You should plan for learners with only one small screen.

  • +
  • A learner will need to focus on both your screen share and their +work.

  • +
  • Share a portrait/vertical half of your screen (840 × 1080 is our standard and your +maximum).

  • +
  • Zoom provides a “Share a part of screen” that is good for this.

    +
      +
    • Our latest streaming setup (day 4) can take the portrait part for +you so you can share landscape.

    • +
    • Zoom + Linux + Wayland display manager doesn’t have “Share a +portion of the screen”

      +
        +
      • You can share a single window portrait.

      • +
      • Or you can start your desktop session in “X11” or “Xorg” legacy +mode.

      • +
      • Or possibly other workarounds (does anyone know other solutions?)

      • +
      +
    • +
    +
  • +
+
+../_images/landscape.png +
+

A FullHD 1920x1080 screen shared. Learners have to make this really small if +they want to have something else open.

+
+
+
+../_images/portrait.png +
+

Portrait layout. Allows learners to have something else open in the other half.

+
+
+

Motivation for portrait layout:

+
    +
  • This makes it easier for you to look at some other notes or to coordinate +with other instructors at the same time +without distracting with too much information.

  • +
  • This makes it possible for participants to have something else open in the +other screen half: terminal or browser or notebook.

  • +
+
+

Instructor perspective

+
+../_images/instructor.png +
+

I1: +This is how it can look for the instructor. Zoom is sharing a portion of the left +side, the right side is free for following notes, chat, etc.

+
+
+
+
+

Learner perspective

+

Here are three examples of how it can look for the learner.

+
+../_images/learner-large.png +
+

L1: +Learner with a large screen, Zoom in dual-monitor mode so that the instructor +pictures are not shown. Screen-share is on the left side, collaborative notes +at bottom left, terminal and web browser on the right.

+
+
+
+../_images/learner-normal.png +
+

L2: +A learner with a single large screen (Zoom in “single monitor mode”). +Instructor screen share at right, learner stuff at left.

+
+
+
+../_images/learner-small.png +
+

L3: +A learner with a particularly small screen. Instructor screen-share at left, +your windows at right.

+
+
+
+
+
+

Share the history of your commands

+

Even if you type slowly it is almost impossible to follow every command. We +all get distracted or want to read up on something or while following a command +fails on the learner laptop while instructor gets no error.

+

Add pauses and share the commands that you have typed so that one can catch up.

+

Below are some examples (some more successful than others) of sharing history +of commands.

+
+../_images/history-portrait.png +
+

H1: +A vertical screen layout shared. Note the extra shell history at the top. The +web browser is at the bottom, because the Zoom toolbar can cover the bottom +bit.

+
+
+
+../_images/history-rsh.png +
+

H2: +This isn’t a screen-share from CodeRefinery, but may be instructive. Note the +horizontal layout and shell history at the bottom right.

+
+
+
+../_images/history-landscape-dark.png +
+

H3: +Similar to above, but dark. Includes contents on the right.

+
+
+
+../_images/history-portrait-light.png +
+

H4: +Jupyter + terminal, including the fish shell and the terminal history.

+
+
+
+../_images/history-portrait-dark.png +
+

H5: +Lesson + terminal, tmux plus terminal history and dark background.

+
+
+
+../_images/portrait.png +
+

H6: +HPC Kickstart course. Note the colors contrast of the windows and colors of +the prompt and text. The history is smaller and doesn’t take up primary +working space. The working directory is in the window title bar.

+
+
+
+https://raw.githubusercontent.com/bast/history-window/main/demo.gif +
+

H7: +Show command history “picture-in-picture”, in the same terminal window.

+
+
+
+
+

How to configure history sharing

+

You need to find a way to show the recent commands you have entered, so that +learners can see the recent commands. Below are many solutions. Try them out +and see what works for you.

+
    +
  • prompt-log: +It adds a interesting idea that the command you enter is in color and also +provides terminal history before the command returns.

  • +
  • Simple: The simple way is PROMPT_COMMAND="history -a" and then +tail -f -n0 ~/.bash_history, but this doesn’t capture ssh, +sub-shells, and only shows the command after it is completed.

  • +
  • Better yet still simple: Many Software Carpentry instructors use +this script, +which sets the prompt, splits the terminal window using tmux and displays command history +in the upper panel. Requirement: tmux

  • +
  • Better (bash): This prints the output before the command is run, +instead of after. Tail with tail -f ~/demos.out.

    +
    BASH_LOG=~/demos.out
    +bash_log_commands () {
    +    # https://superuser.com/questions/175799
    +    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    +    [[ "$PROMPT_COMMAND" =~ "$BASH_COMMAND" ]] && return # don't cause a preexec for $PROMPT_COMMAND
    +    local this_command=`HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"`;
    +    echo "$this_command" >> "$BASH_LOG"
    +}
    +trap 'bash_log_commands' DEBUG
    +
    +
    +
  • +
  • Better (zsh): This works like above, with zsh. Tail with tail -f ~/demos.out.

    +
    preexec() { echo $1 >> ~/demos.out }
    +
    +
    +
  • +
  • Better (fish): This works like above, but for fish. Tail with +tail -f ~/demos.out.

    +
    function cmd_log --on-event fish_preexec ; echo "$argv" >> ~/demos.out  ; end
    +
    +
    +
  • +
  • Better (tmuxp): This will save some typing. +TmuxP is a Python program (pip install tmuxp) that gives you programmable tmux sessions. One configuration that +works (in this case for fish shell):

    +
    session_name: demo
    +windows:
    +  - window_name: demo
    +    layout: main-horizontal
    +    options:
    +      main-pane-height: 7
    +    panes:
    +      - shell_command:
    +          - touch /tmp/demo.history
    +          - tail -f /tmp/demo.history
    +      - shell_command:
    +          - function cmd_log --on-event fish_preexec ; echo "$argv" >> /tmp/demo.history  ; end
    +
    +
    +
  • +
  • Windows PowerShell: In Windows Terminal, +a split can be made by pressing CTRL+SHIFT+=. Then, in one of the splits, the following +PowerShell command will start tracking the shell history:

    +
    Get-Content (Get-PSReadlineOption).HistorySavePath -Wait
    +
    +
    +

    Unfortunately, this only shows commands after they have been executed.

    +
  • +
  • Tavatar: shell history mirroring teaching tool can copy recent history to a remote server.

  • +
  • history-window: Show command +history “picture-in-picture” when teaching command line. Requires Bash.

  • +
+
+
+

Font, colors, and prompt

+
+

Terminal color schemes

+
    +
  • Dark text on light background, not dark theme. Research and our +experience says that dark-text-on-light is better in some cases and +similar in others.

  • +
  • You might want to make the background light grey, to avoid +over-saturating people’s eyes and provide some contrast to the pure +white web browser. (this was an accessibility recommendation when +looking for ideal color schemes)

  • +
  • Do you have any yellows or reds in your prompt or program outputs? +Adjust colors if possible.

  • +
+
+
+

Font size

+
    +
  • Font should be large (a separate history terminal can have a smaller +font).

  • +
  • Be prepared to resize the terminal and font as needed. Find out +the keyboard shortcuts to do this since you will need it.

  • +
+
+
+

Prompt

+

At the beginning of the workshop your goal is to have a shell +as easy to follow as possible and as close to what learners will +see on their screens:

+
    +
  • Your prompt should be minimal: few distractions, and not take up many +columns of text.

  • +
  • prompt-log does +this for you.

  • +
  • The minimum to do is is export PS1='\$ '.

  • +
  • Blank line between entries: export PS1='\n\$ '.

  • +
  • Have a space after the $ or % or whatever prompt character you +use.

  • +
  • Strongly consider the Bash shell. This is what most new people will +use, and Bash will be less confusing to them.

  • +
  • Eliminate menu bars and any other decoration that uses valuable +screen space.

  • +
  • Add colors only if it simplifies the reading of the prompt.

  • +
+

Later in the workshop or in more advanced lessons:

+
    +
  • Using other shells and being more adventurous is OK - learners will +know what is essential to the terminal and what is extra for your +environment.

  • +
+

Try to find a good balance between:

+
    +
  • Showing a simple setup and showing a more realistic setup.

  • +
  • Showing a consistent setup among all instructors and showing a +variety of setups.

  • +
+
+
+
+

Habits we need to un-learn

+
    +
  • Do not clear the terminal. Un-learn CTRL-L or clear if possible. +More people will wonder what +just got lost than are helped by seeing a blank screen. Push +ENTER a few times instead to add some white space.

  • +
  • Do not rapidly switch between windows or navigate quickly between multiple +terminals, browser tabs, etc. This is useful during your own work when nobody +is watching, but it is very hard to follow for learners.

  • +
  • Avoid using aliases or shortcuts that are not part of the +standard setup. Learners probably don’t have them, and they will fail +if they try to follow your typing. Consider even to rename corresponding +files (.bashrc, .gitconfig, .ssh/config, .ssh/authorized_keys, .conda/*).

  • +
  • Be careful about using tab completion or reverse history search if these +haven’t been introduced yet.

  • +
+
+
+

Desktop environment and browser

+
    +
  • Try to remove window title bars if they take up lots of space +without adding value to the learner.

  • +
  • Can you easily resize your windows for adjusting during teaching?

  • +
  • Does your web browser have a way to reduce its menu bars and other +decoration size?

    +
      +
    • Firefox-based browsers: go to about:config and set +layout.css.devPixelsPerPx to a value slightly smaller than one, +like 0.75. Be careful you don’t set it too small or large since +it might be hard to recover! When you set it to something smaller +than 1, all window decorations become smaller, and you compensate +by zooming in on the website more (you can set the default zoom to +be greater than 100% to compensate). Overall, you get more +information and less distraction.

    • +
    +
  • +
+
+
+

How to switch between teaching setup and work setup?

+
    +
  • Make a dedicated “demos” profile in your terminal emulator, if +relevant. Or use a different terminal emulator just for demos.

  • +
  • Same idea for the browser: Consider using a different browser profile for +teaching/demos.

  • +
  • Another idea is to containerize the setup for teaching. +We might demonstrate this during the Sharing teaching gems session later.

  • +
+
+
+

Keypoints

+
    +
  • Share portrait layout instead of sharing entire screen

  • +
  • Adjust your prompt to make commands easy to read

  • +
  • Readability and beauty is important: adjust your setup for your audience

  • +
  • Share the history of your commands

  • +
  • Get set up a few days in advance and get feedback from someone else. +Feedback and time to improve is very important to make things clear and accessible. +10 minutes before the session starts is typically too late.

  • +
+
+
+
+

Exercises

+
+

Evaluate screen captures (20 min)

+

Evaluate screenshots on this page. Discuss the trade-offs of each one. Which +one do you prefer? Which are useful in each situation?

+

Please take notes in the collaborative document.

+
+
+

Set up your own environment (20 min)

+

Set up your screen to teach something. Get some feedback from another learner +or your exercise group.

+
+
+
+

Other resources

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/search/index.html b/branch/comms/search/index.html new file mode 100644 index 0000000..b33850f --- /dev/null +++ b/branch/comms/search/index.html @@ -0,0 +1,184 @@ + + + + + + Search — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/branch/comms/searchindex.js b/branch/comms/searchindex.js new file mode 100644 index 0000000..ace926b --- /dev/null +++ b/branch/comms/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {":calendar: Schedule": [[11, "calendar-schedule"], [11, "id1"], [11, "id9"], [11, "id17"]], ":icecream: Icebreaker": [[11, "icecream-icebreaker"], [11, "id2"], [11, "id10"], [11, "id18"]], ":question: Questions": [[11, "question-questions"], [11, "id5"], [11, "id13"], [11, "id21"]], "A workshop seen from different perspectives": [[14, null]], "About teaching": [[11, "about-teaching"]], "About the CodeRefinery project and CodeRefinery workshops in general": [[1, null]], "Accepting the smallest contribution": [[10, "discussion-0"]], "After the workshop": [[14, "after-the-workshop"]], "All CodeRefinery lessons are on GitHub": [[9, "discussion-0"]], "Alternatives": [[18, "alternatives"]], "Are there any downsides?": [[0, "are-there-any-downsides"]], "Asking questions": [[2, "asking-questions"]], "Asking questions before the workshop": [[6, "asking-questions-before-the-workshop"]], "August/September 2024": [[11, "august-september-2024"]], "August/September 2024 CodeRefinery train the trainer workshop": [[8, null]], "Balancing and dynamic adjustment": [[17, "balancing-and-dynamic-adjustment"]], "Basic controls": [[2, "basic-controls"]], "Before the workshop": [[2, "before-the-workshop"], [14, "before-the-workshop"]], "Behind the stream": [[11, "behind-the-stream"], [18, null]], "Benefits and disadvantages": [[22, "benefits-and-disadvantages"]], "Best classroom experiences": [[11, "best-classroom-experiences"]], "Better approach": [[9, "better-approach"]], "Bj\u00f8rn Lindi": [[20, "exercise-1"]], "Breakout Room exercise": [[11, "breakout-room-exercise"]], "Carpentries audience": [[1, "carpentries-audience"]], "Challenges related to defining our target audience": [[1, "discussion-1"]], "Check-in": [[11, "check-in"], [11, "id3"], [11, "id11"], [11, "id19"]], "Co-teaching": [[0, null], [0, null]], "Co-teaching and team teaching benefits": [[0, "co-teaching-and-team-teaching-benefits"]], "CodeRefinery OBS configs": [[13, "coderefinery-obs-configs"]], "CodeRefinery audience": [[1, "coderefinery-audience"]], "CodeRefinery control panel": [[18, "coderefinery-control-panel"]], "CodeRefinery lesson template": [[10, "coderefinery-lesson-template"]], "CodeRefinery teaching philosophies": [[20, null]], "Collaborative Document Manager": [[2, "collaborative-document-manager"]], "Collaborative document format example": [[2, "collaborative-document-format-example"]], "Collaborative document mechanics and controls": [[2, "collaborative-document-mechanics-and-controls"]], "Collaborative notes": [[2, null]], "Collaborative notes archives from workshops": [[11, null]], "Collecting feedback as we teach": [[6, "collecting-feedback-as-we-teach"]], "Communications with participants": [[3, null]], "Community": [[1, "community"]], "Competent practitioners": [[1, null]], "Computational thinking": [[4, null]], "Creating new teaching material": [[9, "creating-new-teaching-material"]], "Day 2 : Session 2 (20.08.24)- Tools and techniques adopted in CodeRefinery workshops": [[11, "day-2-session-2-20-08-24-tools-and-techniques-adopted-in-coderefinery-workshops"]], "Day 3 : sessiion 3 (27.08.24) - \u201cAbout teaching and cool things we all would like to share\u201d": [[11, "day-3-sessiion-3-27-08-24-about-teaching-and-cool-things-we-all-would-like-to-share"]], "Day1: Session 1 (13.08.24) - About lesson design, deployment and iterative improvement": [[11, "day1-session-1-13-08-24-about-lesson-design-deployment-and-iterative-improvement"]], "Day4: Session 4 (3.09.24) - Streaming and video editing": [[11, "day4-session-4-3-09-24-streaming-and-video-editing"]], "Desktop environment and browser": [[15, "desktop-environment-and-browser"]], "Different roles as stepping stones for community involvement": [[14, "different-roles-as-stepping-stones-for-community-involvement"]], "Discuss how to collaborate and handle questions (15 min)": [[2, "exercise-0"]], "Discuss the models of team teaching (10 min)": [[0, "exercise-0"]], "Discussion": [[14, "discussion"], [14, "discussion-0"]], "Discussion: how to distribute this?": [[21, null]], "Discussion: what makes a video easy to edit?": [[21, null]], "Don\u2019t get overwhelmed": [[2, "don-t-get-overwhelmed"]], "During the workshop": [[14, "during-the-workshop"]], "Editing-1: Get your sample video": [[21, "exercise-1"]], "Editing-2: Run Whisper to generate raw subtitles and test video.": [[21, "exercise-0"]], "Editing-3: Create the basic editlist.yaml file": [[21, "exercise-2"]], "Editing-4: Run ffmpeg-editlist": [[21, "exercise-3"]], "Editing-5: Add more features": [[21, "exercise-4"]], "Editing-6: Subtitles": [[21, "exercise-5"], [21, "exercise-6"]], "Editing-7: Generate the final output file.": [[21, "exercise-7"]], "Episode 1 : Computational thinking": [[11, "episode-1-computational-thinking"]], "Episode 1: CodeRefinery": [[11, "episode-1-coderefinery"]], "Episode 1: Lesson design and development": [[11, "episode-1-lesson-design-and-development"]], "Episode 2 : Teaching philosophies": [[11, "episode-2-teaching-philosophies"]], "Episode 2: Collaborative Notes": [[11, "episode-2-collaborative-notes"]], "Episode 2: Lessons with version control": [[11, "episode-2-lessons-with-version-control"]], "Episode 3: Co-teaching": [[11, "episode-3-co-teaching"]], "Episode 3: How we collect feedback and measure impact": [[11, "episode-3-how-we-collect-feedback-and-measure-impact"]], "Episode 3: One workshop, many perspectives": [[11, "episode-3-one-workshop-many-perspectives"]], "Episode 4: Sound": [[11, "episode-4-sound"]], "Episode 5: How to prepare a quality screen-share": [[11, "episode-5-how-to-prepare-a-quality-screen-share"]], "Evaluate screen captures (20 min)": [[15, "exercise-0"]], "Example 1": [[6, "example-1"]], "Example 2": [[6, "example-2"]], "Example 3": [[6, "example-3"]], "Example 4": [[6, "example-4"]], "Exercise": [[0, "exercise"], [2, "exercise"]], "Exercise A": [[21, "exercise-a"]], "Exercise B": [[21, "exercise-b"]], "Exercise questions to discuss": [[11, "exercise-questions-to-discuss"]], "Exercise: Discussion about learning objectives and exercise design": [[9, "exercise-discussion-about-learning-objectives-and-exercise-design"]], "Exercise: Group discussion (10 min)": [[6, "exercise-group-discussion-10-min"]], "Exercise: How do you design your teaching material?": [[9, "exercise-how-do-you-design-your-teaching-material"]], "Exercises": [[10, "exercises"], [15, "exercises"], [17, "exercises"], [21, "exercises"]], "Feedback about todays session": [[11, "feedback-about-todays-session"], [11, "id8"], [11, "id16"], [11, "id23"]], "Feedback template": [[2, "feedback-template"]], "Font size": [[15, "font-size"]], "Font, colors, and prompt": [[15, "font-colors-and-prompt"]], "Future prospects (briefly)": [[22, "future-prospects-briefly"]], "General / Practicalities": [[11, "general-practicalities"], [11, "id6"], [11, "id14"]], "General Collaborative Document practices": [[2, "general-collaborative-document-practices"]], "Getting it set up": [[18, "getting-it-set-up"]], "Goals": [[1, "goals"]], "Great resources": [[9, "great-resources"]], "Group discussion using the collaborative notes": [[6, "exercise-0"]], "Guide and demo-giver": [[0, "guide-and-demo-giver"]], "Habits we need to un-learn": [[15, "habits-we-need-to-un-learn"]], "Hardware requirements": [[12, "hardware-requirements"]], "History": [[1, "discussion-0"], [22, "history"]], "How did we get to this setup?": [[14, "how-did-we-get-to-this-setup"]], "How scenes are controlled": [[18, "how-scenes-are-controlled"]], "How this relates to streaming": [[21, "how-this-relates-to-streaming"]], "How to configure history sharing": [[15, "how-to-configure-history-sharing"]], "How to prepare a quality screen-share": [[15, null]], "How to switch between teaching setup and work setup?": [[15, "how-to-switch-between-teaching-setup-and-work-setup"]], "How we collect feedback and measure impact": [[6, null]], "How we do it": [[21, "how-we-do-it"]], "Ice-breaker in groups (20 minutes)": [[20, "exercise-0"]], "Icebreaker questions": [[22, "icebreaker-questions"]], "Improving existing lessons": [[9, "improving-existing-lessons"]], "Individual learner journey": [[14, "individual-learner-journey"]], "Initial setup": [[13, "initial-setup"]], "Installing the OBS config": [[13, "installing-the-obs-config"]], "Instructor guide": [[7, null]], "Instructor journey": [[14, "instructor-journey"]], "Instructor note": [[0, "instructor-note-0"], [2, "instructor-note-0"], [4, "instructor-note-0"], [5, "instructor-note-0"], [6, "instructor-note-0"], [9, "instructor-note-0"], [10, "instructor-note-0"], [12, "instructor-note-0"], [13, "instructor-note-0"], [14, "instructor-note-0"], [15, "instructor-note-0"], [17, "instructor-note-0"], [18, "instructor-note-0"], [19, "instructor-note-0"], [20, "instructor-note-0"], [21, "instructor-note-0"], [22, "instructor-note-0"]], "Instructor perspective": [[15, "instructor-perspective"]], "Instructor views": [[20, "instructor-views"]], "Instructors go through the building and contributing process": [[10, "demo-0"]], "Introduction": [[2, "introduction"], [20, "introduction"]], "Introduction in breakoutrooms": [[11, "id4"], [11, "id12"], [11, "id20"]], "Introduction in breakoutrooms.": [[11, "introduction-in-breakoutrooms"]], "Keypoints": [[0, "keypoints-0"], [2, "keypoints-0"], [4, "keypoints-0"], [10, "keypoints-0"], [12, "keypoints-0"], [13, "keypoints-0"], [14, "keypoints-0"], [15, "keypoints-0"], [17, "keypoints-0"], [18, "keypoints-0"], [19, "keypoints-0"], [20, "keypoints-0"], [21, "keypoints-0"], [22, "keypoints-0"]], "Keypoints: CodeRefinery": [[1, "keypoints-0"]], "Learner perspective": [[15, "learner-perspective"]], "Lesson design and development": [[9, null]], "Lesson-VCS-1: Present and discuss your own lesson formats": [[10, "exercise-0"]], "Lesson-VCS-2: Tour a CodeRefinery or Carpentries lesson on Github": [[10, "exercise-1"]], "Lesson-VCS-3: Modify a CodeRefinery example lesson on Github": [[10, "exercise-2"]], "Lesson-VCS-4: Clone and build a CodeRefinery lesson locally": [[10, "exercise-3"]], "Lesson-VCS-5: (advanced) Create your own lesson using the CodeRefinery format": [[10, "exercise-4"]], "Lessons learned": [[6, "lessons-learned"]], "Lessons with version control": [[10, null]], "Most things to edit (everyone)": [[2, "most-things-to-edit-everyone"]], "Novices": [[1, null]], "OBS during a course": [[12, "obs-during-a-course"]], "OBS user interface": [[12, "obs-user-interface"]], "Objectives": [[0, "objectives-0"], [1, "objectives-0"], [2, "objectives-0"], [4, "objectives-0"], [5, "objectives-0"], [6, "objectives-0"], [9, "objectives-0"], [10, "objectives-0"], [12, "objectives-0"], [13, "objectives-0"], [14, "objectives-0"], [15, "objectives-0"], [17, "objectives-0"], [18, "objectives-0"], [19, "objectives-0"], [20, "objectives-0"], [21, "objectives-0"], [22, "objectives-0"]], "One workshop - many parts": [[14, "one-workshop-many-parts"]], "Open Broadcaster Software (OBS) introduction": [[12, null]], "Open Broadcaster Software (OBS) introduction & setup": [[11, "open-broadcaster-software-obs-introduction-setup"]], "Open Broadcaster Software (OBS) setup": [[13, null]], "Other resources": [[15, "other-resources"]], "Other roles": [[14, "other-roles"]], "Overview": [[0, "overview"]], "Participant preparations for each session": [[7, "participant-preparations-for-each-session"]], "Poll": [[11, "poll"]], "Posting the collaborative document to the website": [[2, "posting-the-collaborative-document-to-the-website"]], "Presenter and interviewer": [[0, "presenter-and-interviewer"]], "Primary articles": [[21, "primary-articles"]], "Privacy": [[2, "privacy"]], "Prompt": [[15, "prompt"]], "Q&A": [[12, "q-a"], [13, "q-a"], [18, "q-a"], [22, "q-a"]], "Questions": [[11, "questions"]], "Questions from the audience": [[11, "questions-from-the-audience"]], "Questions to audience": [[11, "questions-to-audience"]], "Radovan Bast": [[20, "exercise-2"]], "Recommendations": [[17, "recommendations"]], "Resources": [[8, null]], "Richard Darst": [[20, "exercise-4"]], "Sabry Razick": [[20, "exercise-3"]], "See also": [[12, "see-also"], [19, "see-also"], [21, "see-also"]], "Session 1": [[8, null]], "Session 2": [[8, null]], "Session 3": [[8, null]], "Session 4": [[8, null]], "Session 4 intro": [[16, null]], "Set up the remote control": [[13, "set-up-the-remote-control"]], "Set up your own environment (20 min)": [[15, "exercise-1"]], "Setup before each course": [[13, "setup-before-each-course"]], "Share portrait layout instead of sharing entire screen when teaching online": [[15, "share-portrait-layout-instead-of-sharing-entire-screen-when-teaching-online"]], "Share the history of your commands": [[15, "share-the-history-of-your-commands"]], "Sharing teaching gems": [[5, null]], "Solution": [[21, "solution-0"], [21, "solution-1"], [21, "solution-2"], [21, "solution-3"], [21, "solution-4"], [21, "solution-5"]], "Sound": [[17, null]], "Sound-1: Evaluate sound quality": [[17, "exercise-0"]], "Sound-2: Adjust volume up and down": [[17, "exercise-1"]], "Sound-3: Do a balance check": [[17, "exercise-2"]], "Speak up when there are problems": [[17, "speak-up-when-there-are-problems"]], "Sphinx": [[10, "sphinx"]], "Stepas Toliautas": [[20, "exercise-5"]], "Summary": [[0, "summary"], [10, "summary"], [17, "summary"], [20, "summary"], [21, "summary"]], "Take time designing your survey": [[6, "take-time-designing-your-survey"]], "Talking points for each sessions intro": [[7, "talking-points-for-each-sessions-intro"]], "Target audience": [[1, "target-audience"], [7, "target-audience"]], "Teaching": [[11, "teaching"]], "Teaching gems": [[11, "teaching-gems"]], "Team lead / Local host journey": [[14, "team-lead-local-host-journey"]], "Team teaching models": [[0, "team-teaching-models"]], "Team teaching specifics": [[0, "team-teaching-specifics"]], "Terminal color schemes": [[15, "terminal-color-schemes"]], "The importance of audio": [[17, "the-importance-of-audio"]], "The instructor will go through the setup.": [[13, "demo-0"]], "The process of designing a lesson \u201cbackwards\u201d": [[9, "the-process-of-designing-a-lesson-backwards"]], "This sounds like a lot of people and time investment!": [[14, "this-sounds-like-a-lot-of-people-and-time-investment"]], "Timing": [[7, "timing"]], "Tips for good sound quality": [[17, "tips-for-good-sound-quality"]], "Tour of lesson templates options": [[10, "tour-of-lesson-templates-options"]], "Train the trainer workshop": [[8, null]], "Trying to measure impact with longer-term surveys": [[6, "trying-to-measure-impact-with-longer-term-surveys"]], "Typical problems": [[9, "typical-problems"]], "Use case: our lessons": [[9, "use-case-our-lessons"]], "Use ffmpeg-editlist to edit this sample video": [[21, "exercise-8"]], "Video editing": [[11, "video-editing"], [21, null]], "Video recordings": [[20, "prerequisites-0"]], "We collect notes using a shared document (5 min)": [[9, "exercise-0"]], "We work in groups but use the shared document as result (20 min)": [[9, "exercise-1"]], "What can go wrong": [[18, "what-can-go-wrong"]], "What is OBS?": [[12, "what-is-obs"]], "What is streaming and recording?": [[22, "what-is-streaming-and-recording"]], "What\u2019s next?": [[19, null]], "Who does what": [[18, "who-does-what"]], "Why version control?": [[10, "why-version-control"]], "Why we stream": [[11, "why-we-stream"], [22, null]], "Window layouts": [[18, "window-layouts"]], "Workshop roles and their journeys": [[14, "workshop-roles-and-their-journeys"]], "Wrapup": [[11, "wrapup"], [11, "id7"], [11, "id15"], [11, "id22"]]}, "docnames": ["co-teaching", "coderefinery-intro", "collaborative-notes", "comms", "computational-thinking", "cool-gems", "feedback-and-impact", "guide", "index", "lesson-development", "lessons-with-git", "notes-archive", "obs", "obs-config", "overview", "screenshare", "session-4-intro", "sound", "streaming", "streaming-whats-next", "teaching-philosophies", "video-editing", "why-we-stream"], "envversion": {"sphinx": 62, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["co-teaching.md", "coderefinery-intro.md", "collaborative-notes.md", "comms.md", "computational-thinking.md", "cool-gems.md", "feedback-and-impact.md", "guide.md", "index.md", "lesson-development.md", "lessons-with-git.md", "notes-archive.md", "obs.md", "obs-config.md", "overview.md", "screenshare.md", "session-4-intro.md", "sound.md", "streaming.md", "streaming-whats-next.md", "teaching-philosophies.md", "video-editing.md", "why-we-stream.md"], "indexentries": {}, "objects": {}, "objnames": {}, "objtypes": {}, "terms": {"": [0, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 20, 21], "0": [3, 11, 15, 22], "00": [11, 21], "01": 2, "02": 11, "02_at_09": 11, "03": [6, 21], "03308595436e636b3bb37ed9d1f0dee39eeccd0f": 11, "04": 21, "05": [11, 21], "07": 21, "08": 6, "1": [2, 3, 7, 15, 22], "10": [2, 3, 4, 7, 11, 15, 17, 18, 20, 21, 22], "100": [11, 12, 15, 17, 22], "1080": 15, "11": [11, 21], "12": [3, 6, 11, 21], "128": 11, "13": [3, 8], "13292363": 6, "13th": 8, "14": [3, 11], "148421550": 11, "15": [0, 7, 11, 12, 14, 15, 21], "16": [3, 21], "17": 11, "175799": 15, "18": 3, "180": 20, "18640868": 11, "19": 11, "1920x1080": 15, "1d": 11, "2": [2, 3, 7, 9, 14], "20": [2, 3, 4, 6, 7, 8, 10, 14, 18, 21], "200": 11, "2014": [1, 9], "2015": [1, 9], "2016": [1, 9, 14], "2017": 9, "2019": 9, "2020": 14, "202024": 11, "2021": 6, "2022": [1, 9], "2023": 21, "2024": [6, 9, 16], "2025": 1, "20coderefineri": 11, "20th": 3, "20workshop": 11, "21": 11, "23": 11, "24": 21, "25": [7, 10, 11, 21], "25mbit": 12, "26": 11, "2671576": 6, "2671578": 6, "27": [3, 8], "27th": 3, "29": 3, "2k45bftw4sbmlbfjr1oz90": 11, "3": [1, 2, 3, 5, 7, 9, 14, 22], "30": [7, 11], "300": [11, 17], "31": 21, "316508": 11, "35": [3, 5, 7, 9, 11, 21], "37": 21, "39": 11, "3rd": [3, 8, 11], "4": [2, 3, 4, 7, 14, 15], "40": 11, "404": 11, "43": 21, "4445": 13, "45": [2, 7, 11, 20, 21], "5": [0, 2, 3, 6, 7, 12, 14, 17, 19, 22], "50": [11, 21], "500m": 17, "5281": 6, "55": 11, "5c6ecd3628a43b0cdc79815f665e224a": 11, "6": 11, "612x612": 11, "64gb": 12, "7": [3, 11, 15], "75": [3, 15], "7b": 11, "7b7ec4b91d2cf9d8e1b064678d205467": 11, "7e": 11, "7nhx": 20, "8": [3, 11, 12], "80": 11, "840": 15, "9": [3, 11, 15], "90": [3, 7, 9], "9781119861690": 11, "A": [1, 2, 8, 9, 11, 15, 19, 20], "And": [2, 3, 11, 17, 20, 21], "As": [2, 3, 9, 11, 16, 17, 21], "At": [2, 15], "BY": 9, "Be": [2, 11, 15, 17, 21], "Being": 11, "But": [2, 3, 7, 9, 11, 17, 20], "By": [1, 11, 21], "For": [0, 1, 2, 3, 7, 9, 10, 11, 14, 20, 21, 22], "If": [2, 3, 7, 8, 9, 10, 11, 14, 16, 17, 20, 21], "In": [0, 1, 3, 7, 10, 11, 12, 13, 14, 15, 17, 18, 20, 22], "It": [0, 1, 2, 3, 7, 9, 10, 11, 15, 16, 17, 18, 20, 21], "NO": 11, "NOT": 11, "No": [6, 11, 14, 21, 22], "Not": [0, 6, 9, 11, 18], "One": [0, 1, 2, 3, 6, 15, 17, 18], "Or": [2, 10, 11, 15], "That": [11, 12, 20], "The": [0, 1, 2, 3, 6, 8, 10, 11, 12, 14, 15, 16, 18, 20, 21, 22], "Then": [3, 7, 11, 15], "There": [1, 2, 3, 7, 10, 11, 13, 14, 16, 18, 21, 22], "These": [3, 7, 11, 13, 16, 17, 19, 21, 22], "To": [3, 7, 11, 21], "Will": 11, "With": [11, 17, 20], "_build": 10, "_cobn": 21, "aaa": 17, "aalto": [11, 21], "aaltoscicomp": 21, "aau": 11, "abl": [2, 3, 7, 9, 11, 17, 20, 21], "about": [0, 2, 3, 6, 7, 8, 10, 12, 14, 15, 16, 18, 19, 20, 21, 22], "abov": [2, 6, 11, 15, 21], "abraham": 11, "absenc": 11, "absolut": 11, "abstract": [4, 11], "academ": [1, 11, 20], "academi": 11, "accept": [1, 11], "access": [9, 11, 15, 21], "accid": 21, "accident": 0, "accomd": 11, "accompani": 9, "accomplish": [2, 11], "account": [2, 3, 7, 10, 11], "accur": 21, "achiev": [6, 11, 17, 20], "achiv": 11, "acoust": [11, 17], "acquiesc": [6, 11], "across": 11, "act": 11, "action": [6, 11], "activ": [0, 1, 9, 11, 16], "actual": [0, 1, 6, 9, 11, 20, 21, 22], "ad": [2, 11, 15], "adapt": [0, 3, 11], "add": [0, 2, 3, 6, 7, 10, 11, 14, 15], "addit": [0, 11, 14, 17, 20], "address": [1, 11], "adjust": [0, 2, 3, 7, 11, 12, 14, 15, 18, 21], "adopt": [3, 8], "advanc": [0, 2, 3, 7, 11, 15], "advantag": [3, 7, 9, 11], "advent": 11, "adventur": 15, "advertis": 14, "advertiz": 14, "advic": 11, "advoc": [9, 11, 21], "affili": 11, "africa": 11, "after": [2, 3, 6, 7, 10, 11, 15, 17, 20, 21], "afternoon": 9, "afterward": [2, 11, 20], "aftwerward": 11, "again": 3, "against": 11, "agil": [11, 20], "ago": [11, 20], "agre": [0, 2, 11], "ah": 11, "aha": 20, "ahead": 11, "ai": 11, "aim": [1, 8, 11, 20], "airwav": 11, "al": 11, "albert": 11, "algorithm": [4, 11], "alias": 15, "align": 21, "all": [0, 1, 2, 3, 6, 7, 8, 10, 14, 15, 17, 18, 20, 21, 22], "alloc": 11, "allow": [0, 2, 9, 10, 11, 15, 20, 21, 22], "almost": [11, 15, 20], "alon": [2, 11, 14], "along": [2, 11, 20, 21], "alreadi": [0, 1, 6, 9, 11, 20], "alredi": 11, "also": [0, 1, 2, 3, 7, 8, 9, 10, 11, 14, 15, 16, 17, 18, 20], "altern": [0, 2, 10, 11], "alternativeto": 11, "although": 11, "alwai": [1, 2, 9, 11, 14, 20], "am": [3, 9, 11, 17, 20], "amazingli": 9, "ambassador": 1, "ambros": 11, "amd": [11, 12], "among": [11, 15, 17], "amount": [2, 11], "amus": 11, "an": [0, 1, 2, 3, 6, 7, 8, 9, 11, 15, 16, 17, 18, 20, 21], "analogi": 11, "analysi": 11, "analyz": 9, "anecdot": 3, "ani": [1, 2, 3, 6, 8, 11, 15, 17, 20, 21], "annoi": 11, "annot": 11, "anomali": 16, "anonym": [6, 11], "anonymis": 11, "anoth": [0, 9, 11, 15], "answer": [2, 3, 6, 9, 11, 12, 13, 14, 20], "anticip": [0, 11], "anwser": 2, "anxieti": 11, "anybodi": [6, 11], "anymor": 20, "anyon": [2, 11, 14, 15, 21], "anyth": [2, 6, 10, 11, 13, 18, 21, 22], "anywai": 11, "anywher": 10, "apart": 11, "apetit": 11, "api": 10, "aposteriori": 11, "app": 11, "appear": [3, 11, 20, 21], "apper": 11, "appic": 14, "appli": [0, 1, 9, 11, 14, 21], "applic": [0, 11, 12, 13, 14, 18, 20], "apprecentiship": 11, "appreci": [11, 20], "apprici": 11, "approach": [0, 1, 11, 20], "appropri": 11, "approxim": 11, "apriori": 11, "ar": [1, 2, 3, 6, 7, 8, 10, 11, 13, 14, 15, 16, 20, 21, 22], "archiv": [2, 8, 13, 14], "area": [0, 1, 11, 21], "aren": [2, 11, 17, 21], "argument": 11, "argv": 15, "aronud": 11, "around": [3, 11, 14], "arrang": 2, "art": 11, "arthur": 11, "articl": 11, "artifact": 17, "asc": 21, "asid": 11, "ask": [0, 3, 9, 10, 11, 14, 16, 17, 20], "asleep": 11, "aspect": [3, 7, 11, 14], "assess": [0, 9], "assign": [7, 11], "assist": 11, "assum": [1, 2, 6, 10, 11], "assur": 11, "asymptot": 11, "async": 22, "attempt": 10, "attend": [6, 9, 11, 21], "attent": [0, 11], "audibl": 11, "audienc": [0, 6, 8, 9, 12, 13, 15, 17, 18, 20, 21, 22], "audio": [3, 7, 8, 11, 12, 13, 16, 21], "aug": [3, 8], "august": 3, "authorized_kei": 15, "auto": 11, "autom": 9, "automat": [2, 11], "av": 11, "avail": [0, 3, 4, 6, 10, 11, 14, 17, 20, 21], "avm": 11, "avoid": [1, 2, 6, 11, 15, 20], "awai": [2, 11, 17, 18], "awar": [1, 11, 20], "awkward": 0, "b": 11, "bachelor": 11, "back": [2, 9, 11, 20, 21], "background": [9, 11, 15, 17, 20], "backup": [2, 19], "backward": 11, "bad": [11, 17], "bake": 11, "balanc": [2, 6, 15], "band": 11, "bandwidth": 17, "bar": [11, 15], "barrier": [3, 7, 11, 14], "bascic": 11, "base": [1, 9, 10, 11, 14, 15, 18, 21], "baselin": 11, "bash": 15, "bash_command": 15, "bash_histori": 15, "bash_log": 15, "bash_log_command": 15, "bashrc": 15, "basic": [0, 3, 7, 9, 10, 11, 12, 16, 17, 20], "basisc": 11, "bast": 8, "bbb": 17, "beamer": 11, "bear": 11, "beast": 11, "beat": 17, "beauti": 15, "becam": 11, "becaus": [1, 6, 11, 15, 17, 20, 21], "becom": [0, 6, 8, 9, 11, 15, 20, 21], "been": [3, 6, 7, 9, 10, 11, 13, 14, 15, 17, 19, 20, 21], "befor": [1, 3, 7, 9, 11, 15, 20, 21], "beforehand": 11, "beggin": 11, "begin": [6, 11, 15, 20, 21], "beginn": 8, "behalf": 3, "behind": [2, 6, 7, 8, 14], "being": [0, 11, 15, 20], "belief": 11, "believ": 11, "bell": 11, "below": [0, 2, 6, 8, 10, 11, 14, 15, 17, 20, 21], "benefici": [1, 11, 20], "benefit": [10, 11, 21], "benjamin": 11, "berlin": 3, "besid": 11, "best": [0, 1, 3, 7, 14, 20], "better": [6, 11, 15, 20], "between": [0, 2, 3, 7, 8, 10, 11, 14, 20], "beyond": [1, 2, 3, 7, 17], "bia": [6, 11], "bias": 11, "biasi": 11, "big": [0, 9, 11, 22], "bigger": 6, "biggest": 11, "bill": 11, "bin": 11, "binari": 20, "binder": 11, "bioinformat": 11, "biolog": 11, "biologi": 11, "birdsey": 11, "bit": [3, 11, 15, 17, 18, 20], "bj\u00f8rn": 8, "bl": 11, "black": [11, 21], "blackbox": 11, "blank": [2, 9, 15], "bleed": 11, "blob": [3, 7, 11, 20], "bloc": 11, "block": [9, 11, 20], "blog": [6, 9, 11], "bloom": [9, 11], "blow": 11, "blue": 11, "bluetooth": [11, 17], "blurb": 11, "board": 11, "bob": 11, "bomb": 11, "bombard": 11, "book": [9, 10, 11], "bookshop": 11, "bore": [11, 16], "bot": 11, "both": [11, 15, 20], "bother": 11, "bottom": [2, 6, 11, 15], "bound": 11, "box": [10, 11], "br": 11, "brain": [3, 7, 11], "brainstorm": [9, 11], "branch": [9, 11], "brand": 11, "bravo": 11, "bread": 11, "break": [2, 7, 11, 17, 18, 20, 21], "breaker": 11, "breakfast": 11, "breakout": [0, 2, 21], "breakoutroom": [7, 8, 14, 20], "breakthrough": 11, "breath": 11, "bridl": 11, "brief": [3, 7], "bring": [2, 9, 11, 14, 17], "british": 3, "broad": [3, 7, 11], "broadcast": [8, 14, 18], "broaden": 20, "broken": 11, "browser": [11, 20], "bst": [3, 11], "budget": 21, "buffer": 11, "build": [1, 3, 7, 11], "built": [10, 11], "bullet": [2, 11, 20], "busi": [11, 20], "button": [11, 12], "byoc": 14, "c": 11, "c4": 11, "cake": 11, "calcul": 11, "call": [11, 17, 18], "came": [11, 17], "camera": [8, 11, 20], "can": [0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 19, 20, 21, 22], "cancel": [11, 17], "cannot": [3, 7, 11], "canon": 11, "capac": 11, "capic": 11, "captur": [6, 11, 12, 16], "care": [1, 15], "carpentri": [9, 11, 15, 20], "cartooni": 11, "case": [0, 1, 2, 3, 11, 15, 20], "cat": 11, "catch": [0, 11, 15, 21], "cater": 11, "caus": 15, "caveat": 11, "cc": 9, "cell": 11, "center": 11, "central": 3, "centric": 20, "certain": [11, 18, 20, 22], "certainti": 11, "certif": 11, "cest": [3, 11], "challeng": [3, 11, 14], "chanc": [8, 11], "chang": [0, 2, 3, 6, 7, 9, 10, 11, 13, 18, 20], "channel": [1, 11], "chao": 0, "chaotic": [0, 11], "chapter": 21, "characht": 11, "charact": 15, "characterist": 11, "charg": 8, "charm": 11, "chat": [1, 2, 3, 7, 11, 14, 15, 17], "chatgpt": 11, "cheat": 11, "check": [2, 3, 6, 7, 20, 21], "checklist": [11, 13], "cheek": 11, "chemic": 11, "cherish": 11, "cherki": 11, "choic": [9, 11, 21], "choos": [9, 11, 14], "chose": 11, "chromium": 11, "chronolog": 11, "chubbi": 11, "chunk": 21, "cicero": [10, 11], "circl": 11, "circul": 11, "citabl": [6, 9], "clarifi": 11, "clariti": 17, "class": 20, "classic": [0, 11], "classroom": [0, 9, 14], "clean": [11, 14], "cleanli": 21, "clear": [0, 11, 15, 20, 21], "clearer": 11, "clearli": [11, 21], "cli": 11, "click": [10, 12, 13], "client": 11, "clipchamp": 11, "clock": 11, "clone": 13, "close": [2, 6, 8, 9, 15, 17], "closer": [0, 9], "cloud": 11, "clue": 11, "clutter": 11, "cm": 11, "cmd_log": 15, "co": [1, 3, 7, 8, 14, 20], "coach": 11, "coc": 11, "cocktail": 11, "code": [1, 6, 7, 9, 10, 11, 14, 21], "codeberg": 11, "coder": 11, "coderefineri": [0, 2, 3, 6, 7, 12, 14, 15, 21, 22], "codewhisper": 11, "coffe": 11, "cognit": 11, "cohort": 11, "colab": 11, "collab": 11, "collabor": [0, 1, 3, 7, 8, 9, 14, 15, 20], "collat": 11, "colleagu": [6, 9, 11], "collect": [3, 7, 8, 13, 14, 20, 21], "color": [10, 11], "colour": 11, "column": 15, "com": [3, 6, 7, 9, 10, 11, 13, 15, 20, 21], "combin": [11, 14, 20, 21], "come": [2, 3, 7, 9, 11, 19, 20, 21], "comfort": 11, "command": [3, 7, 9, 10, 11, 21], "comment": [0, 1, 2, 3, 6, 7, 11], "commit": [10, 11], "common": [0, 1, 11, 20], "commonli": [11, 12], "commun": [2, 7, 11, 22], "comp_lin": 15, "compani": 11, "compar": 11, "compel": 11, "compens": [15, 22], "compet": 11, "competit": 11, "compil": 11, "complement": [0, 20], "complet": [2, 9, 11, 15], "complex": 11, "complic": [11, 12, 13, 20], "compon": 11, "comprehens": 16, "compressor": 11, "compromis": 20, "comput": [1, 3, 7, 8, 9, 10, 12, 20, 21], "con": 11, "concept": [0, 11, 20], "conceptu": [1, 11], "concern": 11, "conclus": [2, 11], "concucurr": 11, "conda": [9, 15], "condens": 11, "condition_on_previous_text": 21, "conduct": [7, 11], "conf": 11, "confer": 22, "confid": [1, 20], "confident": 11, "config": [11, 12, 15], "configur": [12, 13], "confirm": [3, 7, 11, 13], "conflict": 11, "conform": 11, "confus": [11, 15, 20], "connect": [3, 11, 12, 18], "conquer": 11, "consciou": 20, "consid": [2, 6, 11, 15, 17, 20], "consider": 11, "consist": [2, 4, 8, 10, 11, 15], "constant": [0, 11], "constantli": 11, "constel": 11, "construct": [9, 11, 17], "consum": 22, "contact": [3, 11, 16], "contain": [3, 8, 9, 10, 21], "container": [11, 15], "content": [0, 8, 10, 11, 14, 15, 20, 21], "context": [0, 2, 11, 20], "continu": [1, 11, 14], "continuum": 0, "contrast": 15, "contribut": [11, 14], "contributor": 1, "control": [0, 1, 8, 9, 12, 17], "convei": 20, "conveni": 11, "convent": 11, "convers": [0, 2], "convert": [6, 9, 11], "cook": 11, "cool": [3, 7, 8, 9], "coordin": [0, 11, 14, 15, 18, 22], "copi": [7, 10, 15, 21], "core": 11, "correct": [11, 20], "correspond": [11, 15], "coteach": 11, "could": [0, 2, 9, 11, 18, 20, 21], "couldn": 11, "count": [11, 17], "countri": 1, "coupl": 11, "courag": 11, "cours": [0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 15, 17, 18, 19, 21, 22], "cover": [3, 7, 9, 11, 13, 15, 16], "covid": [11, 22], "cph": 11, "cpu": [9, 11, 12], "cr": [2, 3, 10, 11, 13], "creat": [0, 2, 8, 11, 13, 20], "creator": 1, "criteria": 11, "critic": 11, "crop": 11, "cross": [10, 12], "crowd": 11, "crowdsourc": 21, "crown": 11, "crucial": 11, "cry": 11, "csc": 11, "css": [11, 15], "ctfasset": 11, "ctrl": 15, "cube": 11, "cuda": 21, "cultur": [11, 17], "curios": 20, "curiou": [8, 11], "current": [1, 3, 9, 11, 14, 21], "curriculum": 9, "curriculumn": 11, "cursor": 21, "curv": 11, "custom": [10, 11, 18, 20], "customis": 11, "cut": [11, 21], "cycl": 11, "d": [11, 20], "dai": [2, 3, 6, 7, 9, 14, 15, 21, 22], "daili": [7, 9, 11, 14], "danger": 2, "dark": 15, "darst": 8, "darstr1": 21, "data": [2, 6, 9, 11, 21], "dataset": 11, "date": 11, "daunt": 11, "day1": 21, "deactiv": 11, "dead": 21, "deal": [2, 11], "debrief": 14, "debug": [9, 15], "decaf": 11, "decemb": 11, "decid": [10, 11, 17], "decis": 11, "declar": 2, "decomposit": 4, "decor": 15, "dedic": [0, 2, 10, 15], "deep": [2, 11], "deeper": [3, 7, 11], "deepli": 2, "default": [11, 15], "defin": [0, 9, 11, 21], "definit": [11, 18, 21], "degre": [11, 20], "delai": [2, 11], "delet": 13, "deliev": 11, "deliv": 11, "deliveri": 0, "demand": [2, 11], "demo": [2, 3, 10, 11, 15, 16, 20, 21], "demonstr": [5, 9, 11, 15, 17, 19, 21], "demystifi": 20, "denni": 11, "depend": [2, 3, 7, 9, 10, 11, 21], "deploy": [3, 8], "depth": [11, 14], "deriv": 10, "derse24": 11, "describ": [1, 9, 11, 14, 18], "descript": [11, 14, 21], "design": [1, 3, 4, 7, 8, 10], "desir": [11, 21], "desk": 11, "desktop": 11, "destroi": 11, "detail": [0, 2, 3, 7, 8, 11, 18], "detect": 20, "determin": 11, "dev": 11, "devast": 11, "develop": [1, 3, 6, 7, 8, 14, 20], "deviat": [0, 20], "devic": [2, 11, 17, 21], "devil": 11, "devpixelsperpx": 15, "dhanya": 8, "diagram": 20, "dictionari": 11, "did": [6, 11, 17, 20], "didn": [11, 21], "diff": 11, "differ": [0, 1, 2, 3, 7, 8, 10, 11, 15, 16, 17, 19, 20, 22], "difficult": [1, 6, 11, 20], "difficulti": [1, 22], "dig": 11, "digest": 11, "digit": 11, "dipietro": 11, "dir": 11, "direct": [1, 2, 9, 10, 11, 17, 18], "directli": [10, 18, 21], "director": [0, 11, 12, 14, 18], "directori": [10, 11, 15, 21], "disadvantag": [3, 7, 10], "disagre": 11, "disciplin": [1, 11], "disclaim": 21, "discov": [3, 11], "discret": 1, "discuss": [1, 3, 5, 7, 15, 17, 20, 22], "disorganis": 11, "disori": 0, "displai": [2, 3, 7, 10, 11, 15], "dissoci": 6, "distanc": 11, "distil": [11, 20], "distinct": [11, 22], "distract": [2, 11, 15], "distribut": [11, 14], "divers": [9, 11], "divid": 11, "divis": [0, 11], "dli": 11, "dmp": 11, "dna": 11, "do": [0, 1, 2, 3, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 22], "doc": [2, 10, 11], "document": [0, 1, 3, 6, 10, 11, 14, 15, 20], "doe": [0, 1, 3, 6, 7, 11, 12, 15, 17, 21], "doesn": [2, 10, 11, 15, 17], "doi": 6, "domain": 11, "don": [0, 3, 6, 7, 9, 10, 11, 15, 17, 18, 20, 21, 22], "done": [2, 8, 11, 13, 18, 20, 21, 22], "doubli": 20, "dough": 11, "down": [2, 9, 11, 12], "download": [2, 11, 21], "downsid": [11, 22], "dra": 11, "draft": [9, 11], "drag": 11, "draw": 11, "drawn": 11, "driven": 1, "drop": [0, 11, 14], "drown": 11, "drug": 11, "dry": 11, "dual": 15, "duck": 17, "due": [0, 11, 17], "durat": 2, "dure": [0, 2, 3, 6, 7, 9, 11, 15, 17, 18, 20], "dynam": 11, "e": [0, 1, 3, 7, 11, 14, 15, 18, 21], "each": [0, 2, 3, 6, 8, 9, 11, 12, 14, 15, 17, 18, 20, 21], "ean": 11, "earli": [3, 6, 9, 11], "earlier": [1, 6, 9, 11], "eas": 14, "easi": [2, 9, 10, 11, 12, 15, 20], "easier": [2, 6, 9, 10, 11, 15], "easiest": 11, "easili": [1, 2, 10, 11, 15, 20], "eat": 11, "echo": [11, 15], "edit": [3, 7, 8, 10, 22], "editlist": 11, "editor": [2, 11, 21], "educ": [0, 9, 11], "edward": 11, "eest": [3, 11], "effect": [6, 9, 11], "effici": 11, "effort": [11, 14, 20], "eg": [1, 11], "egg": 11, "eight": 11, "einstein": 11, "either": [0, 5, 10, 11, 17], "elabor": 11, "element": 11, "elimin": 15, "els": [2, 6, 9, 10, 11, 15, 17, 18, 21], "email": [3, 11], "embrac": 20, "emoji": 11, "emot": 11, "emoticon": 11, "emphas": [10, 20], "emphasi": [9, 22], "emploi": 11, "empow": 11, "empti": [9, 11], "emul": 15, "en": [11, 21], "enabl": [2, 11], "encod": 21, "encompass": 11, "encount": 3, "encourag": [5, 9, 11, 20], "end": [0, 2, 9, 11, 15, 17, 18, 20, 21], "energi": 2, "engag": [0, 8, 9, 11, 20, 22], "engin": 11, "english": 11, "enhanc": [8, 11], "enjoi": [3, 11], "enjoy": [11, 17], "enough": [1, 9, 11, 21], "ensur": [0, 2, 11, 17], "enter": 15, "enthusiast": 11, "entiti": 11, "entri": [11, 15], "enviro": 11, "environ": [2, 3, 7, 9, 10, 11, 13, 14, 20, 21], "environemnt": 11, "epcc": 11, "episod": [2, 3, 7, 9, 12, 13, 14, 18, 20, 21], "epsisod": 11, "epub": 10, "equal": [2, 11, 21], "equip": [11, 17], "equival": 11, "erambl": 11, "error": [6, 11, 15, 20], "especi": [0, 11, 20, 21], "essenc": 20, "essenti": [9, 11, 14, 15], "est": 11, "estim": 11, "et": 11, "etc": [1, 2, 3, 7, 8, 10, 11, 13, 14, 15, 17, 18, 21, 22], "etern": 6, "etherpad": 11, "europ": 11, "european": 3, "evalu": [9, 11], "even": [0, 2, 3, 7, 10, 11, 15, 17, 20, 21, 22], "event": [3, 7, 11, 14, 15, 17, 22], "eventu": 11, "ever": [3, 11, 17], "everett": 11, "everi": [0, 2, 8, 10, 11, 15], "everybodi": 11, "everyon": [3, 7, 8, 10, 11, 14, 17, 21], "everyth": [0, 10, 11, 13, 20, 21], "everytim": 11, "everywher": 11, "evolv": 1, "ex": 11, "exam": 11, "exampl": [0, 1, 9, 11, 15, 17, 20, 21], "exc": 11, "excalideck": 11, "excalidraw": 11, "excel": 11, "except": 11, "excercis": 11, "excerpt": 21, "exchang": [8, 11], "excit": [3, 11, 17], "execut": [10, 11, 15], "exemplifi": 11, "exercic": 11, "exercis": [1, 3, 4, 7, 14, 20, 22], "exhaust": 11, "exist": [1, 10, 11], "expand": 11, "expect": [6, 9, 11, 21], "expens": [11, 17], "experi": [1, 2, 6, 8, 14, 15, 20], "experienc": [0, 9, 20], "expert": [1, 6, 11, 14, 20], "explain": [0, 1, 4, 11, 20], "explan": [11, 18, 21], "explicit": 20, "explicitli": 11, "explor": [3, 7, 11], "explos": 11, "export": 15, "expos": 9, "express": [9, 11], "extant": 11, "extend": [10, 11], "extens": [9, 10, 11], "extern": [17, 21], "extra": [10, 11, 15], "extrapol": 11, "extrem": 17, "ey": [2, 15], "f": [11, 15], "face": 11, "facilit": [8, 14], "fact": [11, 20], "factor": [11, 21], "fail": [11, 15], "failur": 11, "fair": 11, "fairli": 11, "faith": 11, "fake": 11, "fall": 11, "fals": 21, "familar": [3, 7], "familiar": [11, 12], "fan": 11, "fanci": 11, "far": [3, 6, 7, 11], "fashion": 20, "fast": [2, 6, 11, 20, 21, 22], "faster": 11, "favor": 1, "favorit": [9, 11], "feasibl": 11, "featur": [10, 11, 12, 14], "featureless": 11, "februari": 1, "feedback": [0, 1, 7, 8, 9, 14, 15, 16, 20], "feel": [0, 1, 11, 14, 20, 22], "fell": 11, "fellow": [8, 11], "felt": [11, 20], "few": [2, 6, 11, 15, 20, 21], "ffmpeg": [3, 7, 11], "fi": [11, 21], "fidgit": 11, "field": [6, 11], "fiffer": 11, "figma": 11, "figur": [2, 6, 9, 11, 16, 17, 18], "fil": 11, "file": [10, 11, 15], "filesystem": 11, "fill": [0, 9, 11, 14], "final": [3, 7, 11], "find": [1, 2, 10, 11, 14, 15, 20, 21], "findabl": [9, 11], "fine": [10, 11], "fire": 11, "firefox": 15, "first": [0, 1, 2, 3, 6, 7, 9, 11, 16, 17, 18, 21], "fish": 15, "fish_preexec": 15, "fit": [0, 10, 11], "fix": [2, 6, 10, 11, 17, 21], "fl": 11, "flat": 11, "flexibl": 11, "flinga": 11, "flood": 2, "flow": [0, 2, 10, 11], "flowchat": 21, "fly": 11, "focu": [0, 2, 3, 11, 15, 18, 22], "focus": [0, 11, 14, 22], "folder": 11, "folk": 11, "follow": [1, 2, 3, 6, 9, 10, 11, 14, 15, 21], "font": [10, 11], "fool": 11, "forbidden": 11, "forc": 0, "forev": 11, "forget": [11, 21], "forgiv": 11, "fork": [10, 11], "form": [0, 1, 2, 6, 9, 11, 21, 22], "formal": [11, 12], "format": [1, 9, 11], "former": 11, "formul": 6, "fortun": 11, "forward": [0, 3, 11], "foster": 11, "found": [3, 5, 7, 11], "four": [3, 8, 11, 20, 21], "fourth": 3, "fragment": 10, "frame": [11, 21], "framework": [4, 11], "franklin": 11, "free": [1, 6, 8, 10, 11, 12, 15, 22], "freelanc": 11, "freir": 11, "frequenc": 11, "frequent": 11, "friend": 20, "friendli": [8, 11], "from": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 12, 13, 15, 18, 20, 21, 22], "fruit": [8, 11], "frustrat": 11, "full": [11, 17, 21, 22], "fullhd": 15, "fulli": [1, 11, 20], "fun": [11, 20], "function": [10, 11, 15], "fund": 1, "funder": 6, "further": [3, 7], "fuse": 0, "futur": [1, 6, 7, 8, 11, 20, 21], "g": [0, 11, 18, 21], "gain": 11, "game": 17, "gap": 0, "garbag": 11, "garbl": 21, "gatekeep": 11, "gather": 14, "gave": 19, "gcjexwc8cf": 20, "gdpr": 11, "ge": 11, "gear": 11, "gem": [3, 7, 8, 15], "gener": [0, 3, 7, 8, 9, 10, 14, 22], "geniu": 11, "gentl": 11, "get": [0, 1, 3, 4, 6, 7, 8, 9, 10, 11, 12, 15, 17, 20], "getzola": 11, "ghost": 11, "gi": 11, "giant": 11, "gig": 11, "gigo": 11, "git": [1, 9, 10, 11, 13, 14], "gitautopush": 11, "gitconfig": 15, "github": [2, 3, 6, 7, 11, 13, 15, 21], "gitlab": 9, "give": [1, 2, 6, 10, 11, 13, 14, 15, 20, 21, 22], "given": [1, 9, 11], "giver": 11, "global": 11, "gme": 11, "gmt": 3, "go": [0, 2, 3, 7, 9, 11, 15, 17, 20, 21], "goal": [2, 5, 6, 9, 11, 14, 15, 20], "goe": [2, 11, 14], "gone": 11, "good": [0, 1, 2, 3, 6, 8, 9, 10, 11, 15, 20, 21, 22], "googl": [2, 11], "got": [1, 3, 7, 11, 15, 20, 22], "gotten": 11, "gpu": 11, "grade": 22, "gradual": 11, "grain": 11, "graphic": [11, 12, 13], "grasp": 11, "great": [8, 11, 14, 20], "greater": 15, "greatest": 20, "green": 11, "grei": 15, "grew": 1, "gritti": 20, "ground": [11, 20], "group": [0, 3, 7, 8, 11, 14, 15], "grow": 11, "guarante": 21, "guess": 11, "guest": 11, "gui": 11, "guid": [8, 9, 11, 14, 18, 20], "gwdg": 11, "h1": 15, "h2": 15, "h3": 15, "h4": 15, "h5": 15, "h6": 15, "h7": 15, "ha": [1, 6, 9, 10, 11, 13, 14, 17, 18, 20], "habit": 0, "hackathon": 11, "hackmd": [0, 2, 11, 21], "had": [6, 11, 20], "hale": 11, "half": [14, 15], "hand": [0, 1, 3, 7, 11, 13, 19], "handbook": 9, "handl": [11, 14], "happen": [2, 11, 14, 18, 21], "happend": 11, "happi": 11, "hard": [10, 11, 15, 17, 18, 20, 21, 22], "harder": [11, 22], "hardest": 11, "hardwar": [11, 20], "hashnod": 11, "hasn": 11, "have": [0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 14, 15, 16, 17, 18, 19, 20, 21, 22], "haven": [9, 11, 15], "hc": 11, "he": 11, "head": [2, 11, 13, 18, 20], "headphon": [11, 17], "headset": [11, 17], "hear": [11, 17], "heard": [11, 17], "hedgedoc": [0, 2, 11], "hei": 3, "heidi": 11, "height": 15, "heinlein": 11, "held": 0, "help": [0, 1, 2, 3, 6, 7, 9, 10, 11, 14, 15, 16, 17, 20, 21, 22], "helper": [2, 7, 8, 11, 14], "helsinki": 3, "here": [0, 1, 2, 3, 5, 7, 9, 10, 11, 15, 20, 21, 22], "herford": 11, "heterogen": 11, "hide": 11, "high": [1, 9, 17, 21], "higher": 11, "highli": [2, 11], "highlight": [2, 9, 10, 11], "him": 11, "himself": 11, "hint": [2, 21], "histori": [3, 10, 11], "historysavepath": 15, "histtimeformat": 15, "hole": 20, "home": [11, 20], "homepag": 11, "hope": [3, 11], "hopefulli": [2, 9], "horizont": 15, "horribl": 2, "host": [1, 10, 11], "hostabl": 10, "hour": [2, 3, 6, 11, 21, 22], "hous": 11, "hover": 21, "how": [0, 1, 3, 4, 7, 8, 10, 12, 13, 17, 20, 22], "howev": [0, 1, 11], "hpc": [11, 15, 21, 22], "html": [10, 11], "http": [2, 3, 6, 7, 9, 10, 11, 13, 15, 20, 21], "huge": [11, 22], "human": 11, "humour": 20, "hustl": 11, "hybrid": 11, "hypothesi": 21, "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21], "i1": 15, "i3": 11, "ic": 11, "icebreak": [2, 7], "icon": 10, "icp": 11, "id": 11, "idcc": 11, "idcc24": 11, "idea": [1, 3, 6, 9, 11, 15], "ideal": [11, 15], "identifi": [9, 11], "ie": 11, "imag": [1, 11, 14], "imagin": 11, "imbalanc": 17, "imform": 11, "imho": 11, "immedi": [2, 11, 20, 21], "imovi": 11, "impact": [7, 8], "imperfect": 9, "implement": 11, "implicitli": 11, "import": [0, 1, 2, 9, 10, 11, 12, 13, 14, 15, 20, 21], "imposs": [11, 15], "impress": 11, "impro": 11, "improv": [1, 2, 3, 6, 8, 10, 15, 17, 21], "improvis": 11, "incent": 21, "inclin": 20, "includ": [0, 2, 11, 15, 20, 21], "inclus": 11, "inconveni": 11, "incorpor": 6, "increas": 11, "increment": 11, "inde": 11, "independ": [1, 3, 11, 20], "index": 11, "indic": [2, 11, 14, 21], "individu": [0, 11, 13, 17, 18, 20], "industri": 11, "inertia": 11, "influenc": 11, "info": [2, 3, 11, 14, 21], "inform": [1, 2, 3, 7, 8, 11, 15, 20, 21], "infrastructur": [1, 20], "infrequ": 22, "initi": [2, 3, 9, 11, 21], "initial_prompt": 21, "inkscap": 11, "inlcud": 1, "inlin": 10, "inner": 11, "input": [10, 11, 17, 21], "insid": 11, "insight": 11, "inspir": [6, 10, 11], "instal": [0, 3, 7, 10, 11, 14, 15, 21], "instanc": [0, 10, 11], "instant": [2, 22], "instead": [2, 6, 9, 10, 11, 20, 21], "institut": [1, 6], "instruct": [0, 2, 11, 14, 15, 21], "instructor": [1, 3, 8, 11], "int": 11, "intak": 11, "integr": [11, 14], "intend": [11, 20], "intens": 2, "intent": 20, "interact": [0, 2, 3, 7, 8, 10, 11, 14, 17, 20, 21, 22], "interest": [1, 3, 7, 8, 9, 11, 14, 15, 20], "interfac": [10, 11], "intergr": 11, "intermedi": [1, 11], "intern": 16, "internet": [11, 12], "interoper": 11, "interpret": 2, "interrupt": [0, 2], "interview": 11, "intro": [8, 10, 11, 21], "introduc": [11, 15], "introduct": [3, 7, 8, 9, 13, 16, 21], "introductori": [2, 16], "intuit": 11, "invent": 21, "invert": 9, "invest": 11, "invit": 14, "involv": [1, 11], "io": [2, 3, 6, 7, 9, 10, 11, 15, 21], "iron": 11, "isn": [2, 3, 7, 11, 15, 17, 18, 20, 22], "isol": [9, 11], "issu": [1, 3, 6, 7, 9, 10, 11, 14, 17, 20], "istockphoto": 11, "item": [2, 6, 11], "iter": [1, 3, 8], "its": [0, 1, 3, 11, 15, 21], "itself": [0, 1, 6, 10, 11], "j": 11, "jame": 11, "jargon": [11, 20], "jarno": 8, "jekyl": 9, "jitsi": 11, "job": [11, 20], "joi": 11, "join": [0, 1, 2, 3, 7, 8, 11, 14], "jointli": 0, "joke": 11, "jonathan": 11, "journal": 11, "joyc": 11, "jpg": 11, "json": 13, "judg": [6, 11], "jump": [11, 14, 21], "jupyt": [1, 9, 10, 11, 15], "jupyterbook": 10, "jupyterhub": 11, "jupyterlab": 11, "just": [1, 2, 3, 6, 8, 9, 10, 11, 13, 15, 16, 20, 21], "justifi": 11, "k": 11, "kahoot": 11, "kao": 11, "kb0068677": 11, "kdenliv": 11, "keep": [0, 1, 2, 3, 11, 14, 18, 20], "kei": [1, 11, 14, 21], "keller": 11, "kept": 11, "keyboard": [11, 15], "kick": 11, "kickstart": [15, 21, 22], "kid": 11, "kind": [2, 3, 11, 14, 16, 17], "kinda": 3, "kindli": 3, "kitchen": 11, "knead": 11, "knew": [9, 11], "know": [0, 1, 4, 6, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21], "knowledg": [10, 11, 20], "known": [1, 11, 12, 20], "kth": 1, "l": 15, "l1": 15, "l2": 15, "l3": 15, "l8my5kygc": 11, "la": 11, "lab": 11, "label": 11, "labor": [0, 11], "lai": [11, 12], "landscap": 15, "lang": [11, 21], "languag": [1, 9, 11, 20], "laptop": [12, 15], "larg": [2, 8, 11, 12, 14, 15, 20, 21], "larger": [0, 9, 11, 22], "largest": 22, "last": [3, 7, 11], "late": [11, 15, 21], "latenc": [11, 17], "later": [2, 3, 6, 8, 9, 10, 11, 13, 15, 18, 21], "latest": [2, 11, 15, 20], "latex": [9, 10, 11], "latter": [8, 11], "laugh": 11, "layout": 13, "lead": [0, 6, 11, 21], "leader": 17, "lean": 11, "leap": 11, "learn": [0, 1, 3, 7, 8, 11, 12, 14, 18, 20, 21, 22], "learner": [0, 1, 2, 6, 9, 11, 20, 21], "least": 11, "leav": [2, 11, 13, 14, 21], "lectur": [0, 2, 11, 20], "led": 11, "left": [2, 15, 21], "legaci": 15, "length": [3, 7, 11], "less": [0, 11, 15, 17, 20, 22], "lesson": [0, 1, 2, 3, 7, 8, 13, 14, 15, 16, 18, 19, 20, 21], "let": [1, 2, 11, 12, 13, 14, 17, 21], "level": [1, 2, 3, 7, 9, 10, 11], "licens": [9, 11], "life": [11, 16, 20], "lifecycl": 11, "light": [11, 15], "lightn": [3, 7], "like": [0, 1, 2, 3, 5, 7, 8, 9, 10, 15, 17, 20, 21], "likert": 11, "limit": [10, 11, 17, 21, 22], "lincoln": 11, "lindi": 8, "line": [2, 3, 7, 9, 10, 11, 15, 21], "link": [2, 3, 6, 7, 8, 10, 11, 20], "linkedin": 11, "linux": [2, 9, 10, 11, 15, 21], "list": [9, 11, 20, 21], "listen": [11, 17, 20], "liter": [0, 11], "littl": 11, "live": [2, 9, 11, 20], "livestream": [3, 7, 11, 12, 21, 22], "ll": [10, 11, 12, 13, 18], "local": [0, 1, 3, 7, 9, 11, 15], "localhost": 13, "locat": [11, 17], "log": [11, 15], "logic": [2, 11], "login": 2, "logo": 10, "long": [2, 6, 10, 11, 13, 17, 20, 21, 22], "longer": [10, 11], "look": [0, 2, 3, 7, 9, 10, 11, 14, 15, 17, 18, 20, 21], "loop": 11, "loos": 11, "lose": [2, 11], "lost": [9, 11, 15, 21], "lot": [6, 8, 9, 11, 15, 16, 17, 18, 19, 20], "loud": [11, 17], "louder": [11, 17], "loudest": 11, "love": 11, "low": [3, 7, 11, 17], "lower": [11, 14, 17], "luck": 11, "lucki": 11, "luckili": 11, "lyric": 11, "m": [11, 20], "mac": 11, "machin": 11, "made": [10, 11, 13, 14, 15], "magic": 20, "mai": [0, 1, 2, 3, 7, 9, 11, 12, 13, 15, 16, 17, 20, 21], "mail": [3, 7, 11, 14], "main": [0, 1, 2, 3, 4, 7, 9, 11, 14, 15, 18, 20, 21], "mainli": 11, "maintain": [0, 1, 22], "major": [1, 6, 11], "make": [0, 1, 2, 3, 6, 7, 9, 10, 11, 12, 13, 15, 17, 20, 22], "maker": 11, "man": 11, "manag": [9, 10, 11, 12, 14, 15, 18], "mani": [0, 1, 3, 7, 10, 15, 16, 20, 22], "mankind": 11, "manual": [0, 9, 11, 12, 13, 14, 15, 21], "map": [11, 20], "markdown": [2, 9, 10, 11], "mass": [11, 22], "master": [11, 13], "match": [6, 11, 17], "materi": [0, 1, 2, 3, 4, 6, 8, 10, 11, 14, 20], "materti": 11, "matter": [11, 14, 17], "max": 11, "maximum": 15, "mayb": [2, 9, 11], "mbit": 12, "md": 11, "mdbook": 11, "me": [11, 20], "mean": [11, 20, 21], "meant": 11, "measur": [7, 8], "mechan": 6, "media": 11, "mediocr": 11, "medium": [11, 17, 22], "meet": [1, 3, 9, 11, 14, 17], "meetup": 14, "mega": 22, "member": 11, "memor": 20, "memori": [9, 11, 12], "mental": [2, 8], "mention": [3, 11], "mentor": 16, "mentorship": 20, "menu": [11, 13, 15], "mere": 11, "merg": [9, 11], "messag": [9, 10, 11], "messi": 11, "met": 11, "meta": 2, "metaphor": 11, "method": [10, 11], "methodlogi": 11, "mic": [3, 11], "michel": 11, "microphon": [3, 7, 11, 17], "microsoft": 11, "mid": 11, "middl": [6, 11], "midst": 11, "might": [0, 3, 7, 10, 11, 15, 17, 20, 21], "min": [3, 4, 5, 7, 10, 11, 12, 13, 14, 17, 18, 19, 20, 21, 22], "mind": [0, 2, 11, 20], "mindset": 11, "mini": 11, "minim": [2, 10, 11, 15, 20, 21], "minimum": [14, 15], "minor": 11, "minut": [0, 2, 5, 9, 11, 15], "miro": 11, "mirror": 15, "misconcept": 9, "miss": [3, 7, 11, 17, 20, 21], "mistak": [9, 11, 20, 21], "mistyp": 11, "mitig": 11, "mix": [0, 8, 11], "mixer": 12, "mkv": 21, "mobil": 2, "mode": [2, 11, 15, 21], "model": 11, "modesti": 11, "modif": [9, 10], "modifi": [11, 13, 21], "modular": [1, 6, 8, 9, 11], "moment": [11, 20], "mondai": 11, "monei": 11, "monitor": [11, 12, 15], "monologu": 11, "month": 11, "more": [0, 1, 2, 3, 6, 8, 9, 10, 11, 12, 13, 14, 15, 17, 20, 22], "morn": [3, 11], "most": [0, 3, 7, 10, 11, 12, 13, 14, 15, 17, 20, 21, 22], "mostli": [0, 1, 11], "motiv": [1, 6, 11, 15, 20, 21], "motto": 11, "mount": [11, 17], "mous": [11, 21], "move": [0, 9, 11, 14, 21], "movement": 11, "movi": 11, "mpi": 11, "much": [0, 1, 2, 3, 7, 9, 10, 11, 15, 17, 20, 21, 22], "multi": [2, 11], "multipl": [0, 2, 9, 11, 14, 15], "must": [3, 7, 9, 11, 21], "mutual": 11, "mv": 13, "mwakok": 11, "my": [6, 9, 11, 20, 22], "mynam": 2, "myst": [10, 11], "myst_pars": 11, "mysteri": 20, "n": [2, 11, 15], "n0": 15, "n2ak": 21, "name": [2, 3, 6, 11, 17, 21], "narr": 11, "narrat": 11, "narrow": 11, "natur": [0, 3, 11, 20], "navig": [10, 15], "nbinder": 11, "nbviewer": 11, "necessari": [2, 11, 14, 20, 21], "need": [0, 1, 2, 3, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 20, 21], "negoti": 11, "neic": [1, 3, 7], "nerd_fac": 11, "nerded_fac": 11, "nest": 2, "net": 11, "network": [1, 11], "neutral": 6, "never": [2, 3, 7, 11, 13, 20, 21], "new": [0, 2, 8, 10, 11, 15, 16, 18, 20, 21], "next": [2, 3, 6, 7, 8, 9, 10, 11, 12, 14, 17, 20, 21], "nice": [2, 3, 10, 11], "nicer": [11, 22], "nickbearman": 11, "night": 11, "nitti": 20, "nix": 11, "nlastcommand": 11, "nobodi": [11, 15], "nois": [11, 17], "non": [2, 9, 11, 17], "none": [6, 11], "nordic": [1, 14], "norepli": [3, 7], "normal": [3, 7, 10, 11, 17, 22], "notabl": 17, "note": [3, 7, 8, 16], "notebook": [1, 6, 9, 10, 11, 15], "notepad": 11, "notesrecommend": 11, "noth": [11, 15], "notic": [11, 17, 20, 21], "notif": 2, "notifi": 11, "notion": 20, "novemb": 11, "novic": [11, 20], "now": [0, 2, 6, 8, 9, 10, 11, 21, 22], "nuisanc": 11, "number": [0, 3, 7, 9, 11], "numer": 11, "nvidia": 11, "o": [6, 11, 21], "ob": [3, 7, 8, 18, 21], "obei": 11, "object": [7, 8, 11], "obs_cr": 13, "obviou": [2, 11, 21], "occasion": [0, 1, 11, 20], "octob": 1, "odd": 11, "odt": 11, "ofc": 11, "off": [0, 3, 15, 20, 21], "offens": 20, "offer": [3, 7, 8, 9, 11, 14, 20], "offic": 11, "offici": 11, "often": [0, 1, 2, 11, 20], "ok": [11, 15, 21], "old": [11, 13], "older": [2, 21], "oliv": 11, "onboard": [0, 3, 7, 11, 14], "onc": [11, 12, 13, 17, 20], "one": [0, 1, 2, 3, 6, 9, 10, 11, 14, 15, 17, 20, 21, 22], "onedr": 11, "ones": [2, 3, 8, 11, 14, 18], "onli": [0, 2, 3, 7, 8, 9, 10, 11, 14, 15, 16, 20, 21], "onlin": [0, 1, 2, 3, 7, 8, 11, 14, 16, 20], "onsit": 11, "oo": 11, "ooo": [6, 11], "oooo": 11, "ooooo": 11, "oooooo": [6, 11], "ooooooo": 11, "oooooooo": 11, "ooooooooooooooooooo": 6, "op": 11, "open": [0, 1, 2, 3, 7, 8, 9, 10, 15, 20], "openai": 11, "openshot": 11, "oper": [10, 11, 14], "opin": 11, "opinion": [11, 17], "opportun": [1, 2, 11], "oppos": 11, "opposit": [11, 20], "optim": [11, 22], "optimum": 14, "option": [2, 3, 6, 7, 11, 12, 13, 15, 21], "order": [9, 11, 17], "org": [1, 3, 6, 7, 8, 9, 10, 11], "organ": [0, 1, 8, 9, 10, 11, 14], "organis": 11, "orient": 11, "origin": [11, 21], "oss": 11, "other": [0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 17, 20, 21, 22], "otherwis": [11, 16, 21], "our": [0, 3, 5, 6, 10, 11, 13, 14, 15, 16, 17, 18, 21, 22], "out": [1, 2, 3, 6, 7, 10, 11, 12, 14, 15, 16, 17, 18, 21], "outcom": [11, 20], "outlin": [11, 14, 16], "output": [10, 11, 15], "output_format": 21, "outro": [7, 11], "outsid": [3, 8, 11, 21], "outstand": 11, "ov": 11, "over": [0, 6, 8, 9, 11, 15, 17, 20, 21], "overal": [9, 10, 11, 15, 21], "overarch": 9, "overcom": 11, "overhead": 11, "overkil": 12, "overload": [2, 11], "oversight": 11, "overview": [1, 7, 9, 11], "overwhelm": 20, "own": [1, 2, 3, 9, 11, 14, 20, 22], "oxford": 11, "p": 11, "pace": [6, 11], "packag": 11, "pad": 11, "page": [2, 9, 10, 11, 14, 15, 17, 21], "paid": 11, "paint": 9, "pane": 15, "panel": [11, 12, 15], "panick": 17, "paolo": 11, "paper": [9, 11], "paradigm": 11, "parallel": [0, 9, 11, 21], "parser": 10, "parson": 9, "part": [0, 1, 2, 4, 7, 9, 11, 15, 17, 18, 19, 21, 22], "part1": 21, "parti": 11, "partial": 11, "particip": [2, 5, 6, 8, 9, 11, 14, 15, 20, 21], "particu": 11, "particular": [0, 11], "particularli": [6, 11, 15], "partli": 11, "partner": [8, 11], "pass": [3, 7, 11], "past": [9, 11, 21], "path": [11, 14, 21], "pathwai": 11, "pattern": [4, 11], "paus": [11, 15], "pavucontrol": 11, "pdf": [10, 11], "pedagog": 11, "peer": 14, "pen": 11, "pencil": 10, "peng": 11, "peopl": [1, 2, 9, 10, 11, 15, 17, 20, 21, 22], "per": [11, 21], "perceiv": 11, "perfect": [2, 9, 21], "perfectli": 20, "perform": [1, 9], "perhap": [11, 21], "period": [2, 11, 20], "periscop": 11, "perman": 11, "permiss": 2, "persist": 6, "person": [0, 2, 3, 11, 14, 17, 18, 20, 22], "persona": [9, 11, 20], "personalis": 11, "personel": 11, "perspect": [8, 20], "phase": 14, "phd": 11, "philosohi": 7, "philosophi": [3, 8, 10], "phrase": 20, "physic": 11, "pick": [9, 11, 17], "pickl": 11, "pickup": 17, "pictur": [0, 6, 9, 15], "pid": 11, "piec": [11, 12, 13], "pinimg": 11, "pioneer": 11, "pip": [11, 13, 15, 21], "pipe": 11, "pitfal": 15, "place": [2, 3, 6, 10, 11, 20, 21, 22], "plai": 11, "plain": 11, "plan": [0, 1, 2, 3, 6, 9, 11, 15, 19], "planet": 11, "platform": [11, 12, 18], "player": 11, "playlist": [20, 21], "pleas": [2, 3, 6, 7, 8, 9, 11, 15, 16, 17, 20], "pleasant": 11, "plenti": [3, 7, 11], "plplblyhczjaahf89p": 20, "plu": 15, "plug": 17, "plzlvms9rf3nmkr2jmglan4su3ojwtwmvw": 21, "png": 11, "poet": 11, "point": [2, 3, 9, 10, 11, 18, 20, 21], "polar": 11, "polish": 11, "pop": 11, "popular": 11, "port": [1, 9], "portion": [11, 12, 15], "portrait": 11, "posit": 11, "possibl": [1, 2, 10, 11, 15, 17, 20, 22], "possibli": [0, 11, 15, 21], "post": [3, 6, 8, 9, 11, 14], "potenti": [0, 17], "power": [11, 12], "powershel": 15, "pptx": 11, "pr": 2, "practic": [0, 1, 3, 4, 8, 9, 16, 17, 19], "pre": [6, 11, 13], "precis": [11, 20], "predict": 11, "preexec": 15, "prefer": [2, 11, 12, 15], "premis": 11, "prep": 11, "prepar": [0, 3, 8, 9, 14, 16, 17, 20], "prerequisit": [8, 10, 11, 21], "presemo": 11, "presenc": 11, "present": [1, 3, 5, 7, 8, 9, 11, 14, 20, 21, 22], "presentor": 11, "presist": 11, "press": [9, 15], "presum": 11, "pretend": 11, "pretti": [9, 10, 11, 17], "preview": [9, 10, 11], "previou": [0, 3, 7, 8, 10, 11, 13, 14, 20, 21], "price": 17, "primari": 15, "principl": [0, 11, 21], "print": [11, 15], "prior": 1, "priorit": 11, "prioriti": [11, 21], "privaci": [11, 21, 22], "privat": [2, 11], "prize": 11, "pro": 11, "prob": 11, "probabl": [9, 10, 11, 12, 15, 17, 21, 22], "problem": [1, 2, 4, 6, 11, 20], "procedur": [0, 17], "process": [0, 11, 21], "procur": 17, "produc": [11, 21], "product": [3, 7, 11, 16, 20], "profan": 11, "profession": [17, 20], "profil": [9, 11, 13, 15], "program": [1, 9, 11, 15, 20], "programm": [11, 15], "progress": [2, 3, 11], "project": [3, 7, 8, 9, 10, 11], "prompt": [11, 21], "prompt_command": 15, "proper": [3, 7, 9, 11], "propos": [0, 1, 3, 7, 10, 11], "propsal": 10, "protein": 11, "prove": 11, "proven": 8, "provid": [1, 2, 3, 6, 7, 10, 11, 15, 21], "ps1": 15, "psreadlineopt": 15, "public": [2, 6, 10, 11], "publicli": [1, 11], "publish": [2, 6, 9, 11], "pull": [9, 10, 11, 20, 21], "pulsemix": 11, "pun": 11, "punctuat": 21, "purchas": 12, "pure": 15, "puriti": 11, "purpos": [10, 13], "push": [10, 11, 15], "pushpada": 8, "put": [2, 9, 11, 19], "py": [11, 13], "python": [3, 7, 9, 10, 11, 13, 15, 21], "pyyaml": 21, "q": [2, 11, 14, 19], "qgi": 11, "qua": 11, "qualifi": 1, "qualiti": [8, 9, 21], "quantifi": [6, 11], "quarto": 11, "question": [0, 1, 3, 8, 9, 10, 12, 13, 14, 15, 16, 20], "quick": [2, 9, 11, 21], "quickli": [2, 3, 7, 11, 15, 17, 21], "quicktim": 11, "quiet": [11, 17], "quieter": 11, "quietest": 11, "quit": [2, 11, 20], "quiz": 11, "quizz": 11, "r": [10, 11], "rabbit": 20, "radovan": [8, 11], "rais": [1, 2, 20], "ram": 11, "ran": 11, "random": [7, 9, 11], "rang": [11, 17], "rantaharju": 8, "rapid": 22, "rapidli": 15, "rare": [11, 20], "rate": 11, "rather": [2, 11, 13], "ratio": 11, "raw": 11, "rb": 11, "rd": 11, "re": [11, 13, 16, 17, 20, 21], "reach": [6, 11, 22], "read": [0, 2, 3, 7, 10, 11, 15, 20], "readabl": 15, "reader": 21, "readi": [8, 11, 14, 21], "readili": 11, "readm": 11, "readthedoc": [9, 11], "real": [2, 11, 12, 16, 20, 21], "realist": [11, 15], "realiti": 0, "realiz": [11, 17, 20], "realli": [2, 9, 11, 15], "reason": [2, 6, 9, 11, 12, 17], "recent": [10, 11, 15], "recip": 11, "recogn": 11, "recognit": [4, 11], "recommend": [2, 3, 7, 11, 14, 15, 19, 20, 22], "record": [9, 11, 14, 16, 21], "recov": [9, 15], "recreat": 13, "red": [11, 15], "redesign": 9, "reduc": [0, 2, 11, 15], "reencod": 21, "ref": 13, "refer": [2, 11], "referenc": 10, "refin": [11, 16], "refinari": 11, "refineri": 11, "reformul": 6, "refresh": 11, "regard": [3, 14], "regist": [3, 8], "registr": [3, 6, 7, 8, 11, 14, 22], "regular": [9, 11], "rehears": 11, "reichent": 11, "reign": 11, "rel": 11, "relat": [3, 11, 20], "relationship": 11, "relax": 11, "relearn": 11, "releas": [3, 7, 9, 11, 21], "relev": [0, 9, 11, 15], "reli": 0, "remain": [2, 3, 11], "remark": [0, 11], "remarkj": 11, "rememb": [9, 11, 21], "remind": [2, 11], "remot": [0, 11, 15, 18, 21, 22], "remov": [2, 6, 11, 15, 21], "renam": [11, 15], "render": 11, "repeat": [11, 20], "repetet": 11, "rephras": 11, "repli": 11, "repo": [10, 11], "repons": 11, "report": [3, 6, 11], "repositori": [1, 9, 10, 11, 13], "repres": 11, "reproduc": [1, 6, 11], "request": [9, 10, 11, 20], "requir": [0, 2, 3, 7, 10, 11, 15, 17, 22], "requisit": 11, "research": [1, 6, 11, 15, 20, 22], "reset": 13, "resist": 11, "resiz": [11, 15], "resolut": 13, "resourc": [6, 11], "respect": [10, 11, 13, 17], "respond": 6, "respons": [0, 6, 11], "rest": [10, 11, 21], "restructur": 10, "result": [6, 11, 21], "resus": 11, "return": 15, "reupload": 11, "reus": [8, 9, 10, 11, 14, 16], "reusabl": [6, 11, 22], "reveal": 11, "revealj": 11, "revers": 15, "review": [11, 21, 22], "revis": [0, 11], "revisit": 1, "rewrit": [9, 11], "richard": [8, 11], "right": [2, 6, 11, 14, 15, 17, 20, 21], "rigor": [2, 11], "rise": [6, 11], "risk": [2, 6, 11, 21, 22], "ritchi": 11, "rkdarst": 13, "rmarkdown": [10, 11], "robert": 11, "robot": 11, "role": [0, 2, 3, 7, 11, 18, 21], "room": [0, 2, 9, 17, 20, 21], "room1": 11, "room2": 11, "root": 2, "rough": [9, 11], "roughli": [10, 11], "rse": 11, "rst": [10, 11], "rubi": 9, "rule": 11, "run": [1, 6, 10, 11, 13, 14, 15], "runner": 11, "rush": 11, "rust": 11, "rxqefefl3t5b": 11, "sacr": 11, "safe": 11, "sai": [0, 2, 11, 15, 17, 21], "said": [2, 11, 21], "saluting_fac": 11, "samantha": [8, 11], "same": [0, 3, 7, 10, 11, 15, 17, 18, 20, 21], "sampl": [10, 11], "sandpap": 11, "satisfi": 11, "satur": 15, "save": [0, 6, 11, 15], "sc": 11, "scale": [6, 8, 11, 14, 22], "scan": 2, "scari": 18, "scenario": 11, "scene": [11, 13, 14], "schedul": [3, 7, 21], "scicomp": 21, "scicompintro": 21, "scienc": [11, 21], "scientif": [11, 21], "scip": 21, "scisoft": 9, "scope": [2, 11], "scratch": [12, 13], "scream": 11, "screen": [5, 8, 18, 21], "screencast": 12, "screenkei": 11, "screenshar": [2, 3, 7, 8, 11], "screenshot": [11, 15], "screenshot_2023": 11, "script": [1, 11, 15, 20], "scroll": [11, 21], "scrum": 11, "search": [2, 11, 15], "season": 11, "sec": 11, "second": [3, 11, 12, 21], "section": [1, 2, 11, 13, 14, 21], "secur": 2, "sed": [11, 15], "see": [0, 1, 2, 3, 7, 9, 10, 11, 13, 14, 15, 18, 20], "seed": 11, "seedl": 11, "seek": 11, "seem": [0, 1, 11, 12, 13, 17, 20], "seen": [0, 2, 6, 8, 11], "segment": [11, 21], "seibold": 11, "select": [2, 11], "self": [3, 8, 9, 11, 20], "sell": 10, "seminar": 11, "send": [2, 10, 11, 14, 20], "sens": [1, 2, 11, 12, 13], "sensit": 20, "sent": [3, 7, 11], "sentenc": [11, 20, 21], "sep": [3, 8], "separ": [9, 11, 15, 20, 21, 22], "septemb": 3, "sequenc": 21, "serial": 20, "serv": [0, 11], "server": [13, 15], "servic": [1, 11], "sese": 1, "session": [0, 1, 2, 3, 9, 13, 14, 15, 18, 20, 21], "session_nam": 15, "set": [3, 7, 10, 11, 14, 16, 17, 20, 21], "setup": [3, 7, 8, 9, 12, 17], "sever": [9, 11, 17, 21, 22], "sfor": 11, "share": [2, 3, 6, 7, 8, 10, 13, 14, 16, 18, 20, 21], "shareabl": 10, "sheet": 11, "shell": [9, 10, 11, 15], "shell_command": 15, "shellshar": 11, "shift": 15, "shokingli": 11, "short": [4, 5, 11, 13, 21], "shortcom": 11, "shortcut": [11, 15], "shorten": 14, "shortest": 11, "shot": [11, 22], "shotcut": 11, "should": [2, 6, 9, 10, 11, 15, 17, 20, 21], "shouldn": [2, 11, 17, 18], "show": [0, 1, 3, 6, 7, 9, 10, 11, 14, 15, 17, 19, 20], "shown": 15, "shy": 11, "sick": 11, "side": [3, 7, 11, 15], "sign": [11, 20], "signal": [9, 11, 20], "silenc": 11, "silent": 11, "silli": 11, "similar": [0, 2, 11, 15, 17, 20], "simpl": [9, 11, 15, 20, 21], "simpler": [9, 11], "simpli": [11, 20], "simplic": 11, "simplifi": [11, 15], "simul": [11, 21], "simultan": 11, "sinc": [2, 6, 11, 13, 14, 15, 16, 20, 21], "sine": 11, "singl": [0, 10, 11, 14, 15, 22], "sit": 11, "site": [2, 10, 11], "situat": [0, 15], "six": 11, "size": [11, 22], "skill": [0, 8, 11, 20], "skip": 20, "sleep": 11, "sleepi": 11, "sleeppi": 11, "slice": 21, "slide": [4, 9, 10, 11, 20], "slider": 11, "slido": 11, "slightli": [2, 11, 15], "slot": 11, "slow": [2, 6, 11, 21], "slower": 11, "slowest": 12, "slowli": 15, "slur": 11, "small": [2, 3, 7, 8, 9, 11, 15, 17, 22], "smaller": [11, 14, 15, 19], "smart": 11, "smc": 11, "smil": 11, "smile": 11, "smiley_cat": 11, "smooth": 11, "smoothli": 11, "smut": 8, "snippet": 10, "snore": 11, "so": [0, 1, 2, 3, 6, 7, 9, 10, 11, 12, 14, 15, 17, 18, 20, 21], "social": 11, "softer": 17, "softwar": [1, 6, 8, 10, 15, 17, 20, 22], "software_carpentri": 11, "solidifi": 9, "solo": [0, 11], "solut": [9, 11, 15, 20], "solution": 11, "solv": [1, 4, 11, 20], "some": [0, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 16, 17, 20, 21], "somebodi": [9, 11], "somehow": 11, "someon": [0, 2, 6, 9, 10, 11, 14, 15, 17, 18, 19, 20, 21], "someth": [1, 2, 3, 5, 6, 7, 9, 10, 11, 15, 17, 18, 20, 21], "sometim": [0, 3, 6, 7, 11, 20], "sometimes": 11, "somewhat": 11, "somewher": 11, "song": 11, "soni": 11, "sonor": 11, "soon": [2, 11, 17], "sooner": [2, 11, 20], "sorri": 11, "sort": 11, "soucr": 11, "sound": [0, 3, 7, 8, 20], "sourc": [0, 6, 9, 10, 11, 12, 20], "space": [11, 15], "spade": 11, "spam": 11, "spanish": 11, "spark": 20, "spars": 11, "spatial": 11, "speak": [0, 11, 21], "speaker": 11, "spec": 11, "special": 11, "specif": [1, 9, 11, 20], "specifi": 17, "spectrum": 11, "speech": 11, "speed": [1, 6, 11], "spend": 11, "spent": 20, "sphinx": [3, 7, 9, 11], "spi": 11, "split": [2, 3, 11, 15, 20, 21], "spontan": 11, "spool": 11, "spot": [10, 21], "spotter": 0, "spread": 1, "sprinkl": 9, "srt": 21, "ssh": 15, "stabil": 11, "stabl": [11, 12], "stack": 11, "staff": [2, 21], "stage": 11, "stai": [3, 9, 11, 20, 22], "standard": [9, 10, 15], "star": 11, "stare": 11, "start": [1, 2, 3, 7, 9, 11, 14, 15, 17, 18, 20, 21], "starter": 11, "stat": 11, "state": 11, "statement": [2, 11], "static": 10, "statist": 11, "statu": [2, 11], "steadili": 11, "step": [1, 2, 9, 11, 13, 19, 21], "stepa": 8, "stephan": 8, "steve": 11, "sth": 11, "stick": 21, "sticki": 11, "still": [2, 3, 7, 9, 11, 14, 15], "stockholm": [1, 3, 11], "stop": [11, 20, 21], "storag": 21, "stori": [3, 11, 20], "straight": [10, 11, 18], "straightforward": [10, 11], "strategi": [9, 11, 14], "stream": [0, 3, 7, 8, 12, 13, 14, 15, 16, 19], "streamer": 11, "streamyard": 18, "streme": 11, "strength": 0, "stress": [0, 11], "strike": 11, "string": 11, "strip": 2, "strong": [0, 10, 11], "strongli": [11, 15], "strted": 11, "structur": [0, 2, 8, 11, 14, 20], "struggl": 11, "stuck": 11, "student": [0, 11, 14], "studi": [11, 20], "studio": [3, 7, 12, 13], "stuff": [11, 15], "style": [0, 1, 3, 7, 11, 20], "sub": 15, "subject": [0, 11], "submit": [1, 10], "subtitl": 11, "subtleti": 0, "succe": 11, "succeed": 11, "success": [0, 6, 11, 14, 15, 20], "successfulli": 11, "suffer": [11, 17], "suffici": [1, 11, 20], "suggest": [3, 6, 9, 11], "suit": [3, 11, 13], "suitabl": 14, "sum": [11, 20], "summ": 9, "summari": [9, 11, 14], "summat": 11, "summer": [3, 11, 14, 21], "sun_with_fac": 11, "sunflow": 11, "supercomput": 10, "superior": 11, "superus": 15, "support": [0, 1, 3, 7, 8, 10, 11, 14, 20], "suppos": 11, "sure": [2, 6, 11, 17, 21], "surpris": [11, 20], "surprisingli": 11, "survei": [11, 14], "swap": 17, "swcarpentri": 11, "sweat_smil": 11, "sweden": 6, "sweet": 11, "switch": [2, 8, 11], "symbol": 11, "symbolifi": 11, "sync": 10, "synergi": 0, "syntax": 2, "synthet": 21, "sysparm_articl": 11, "system": [10, 11, 14], "systemat": 17, "t": [0, 3, 6, 7, 9, 10, 11, 15, 17, 18, 20, 21, 22], "tab": [9, 10, 11, 15], "tabl": [11, 21], "tackl": 11, "tag": 2, "tail": [11, 15], "tailor": [0, 11], "take": [0, 2, 5, 10, 11, 14, 15, 17, 18, 20, 21], "taken": [11, 14], "talbert": 11, "talk": [0, 2, 3, 9, 11, 14, 16, 19, 21, 22], "tandem": 11, "target": [8, 11], "task": [3, 8, 11], "tast": 11, "taught": [0, 9, 11, 20, 22], "tavatar": 15, "taxonomi": 9, "tbd": 3, "tea": 11, "teach": [1, 2, 3, 4, 7, 8, 10, 12, 13, 14, 16, 17, 18, 19, 21, 22], "teacher": [0, 11, 14, 20], "teachingstreamingv3": 13, "teachingstreamingzoomv3": 13, "teachtogeth": 11, "team": [10, 11, 17, 22], "teamtopologi": 11, "tear": 11, "tech": [9, 11, 15], "technic": [3, 7, 9, 11, 16], "techniqu": [3, 6, 7, 8, 14, 20], "technologi": [2, 9, 11, 20], "teenag": 11, "tell": [0, 11], "templat": [3, 7, 9, 11], "ten": 9, "tend": [6, 11, 20], "tendend": 11, "term": [11, 18], "termin": 11, "terminologi": 11, "termonologi": 11, "test": [8, 9, 11, 13, 15, 17], "text": [2, 6, 10, 11, 14, 15, 21], "than": [2, 6, 9, 10, 11, 15, 17, 20, 21, 22], "thank": [3, 11], "thankfulli": 11, "thats": 11, "thee": 16, "thei": [0, 1, 2, 5, 6, 9, 10, 11, 14, 15, 17, 18, 20, 21, 22], "them": [1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 16, 17, 18, 20, 22], "themat": 11, "theme": [11, 15], "themselv": [11, 17], "theoret": [1, 11, 19], "theori": [4, 11, 12, 13, 19], "ther": 11, "therefor": [0, 6, 11], "thi": [0, 1, 2, 3, 4, 7, 9, 10, 11, 12, 13, 15, 16, 17, 18, 20, 22], "thing": [0, 3, 6, 7, 8, 9, 13, 14, 15, 16, 17, 18, 20, 21, 22], "think": [2, 3, 6, 7, 8, 9, 10, 17], "thinker": 11, "third": 3, "this_command": 15, "thoroughli": 11, "those": [0, 2, 3, 7, 9, 11], "though": [2, 11, 14, 20], "thought": [9, 11, 14], "thread": 2, "three": [9, 11, 15, 17, 20, 21], "through": [0, 1, 2, 11, 12, 14, 20, 21], "throughout": 11, "throw": 0, "thrown": 20, "thu": [11, 21], "thumbnail": 11, "thumbs_up": 11, "thvmntbjg2y": 21, "tidi": 11, "tighter": 11, "time": [0, 2, 3, 8, 9, 11, 12, 15, 17, 20, 21, 22], "timer": 11, "timestamp": 21, "tini": [10, 11], "tip": [6, 7, 9, 11], "tire": 11, "tired_fac": 11, "titl": [2, 11, 15, 21], "tmp": 15, "tmux": 15, "tmuxp": 15, "todai": [2, 3, 6, 20], "togeth": [0, 9, 10, 11, 22], "token": 13, "toliauta": 8, "tomorrow": 11, "tone": 11, "tongu": 11, "too": [0, 1, 2, 3, 6, 9, 11, 15, 17, 20, 21, 22], "took": 11, "tool": [1, 3, 5, 7, 8, 9, 10, 14, 15, 17, 20, 21, 22], "toolbar": 15, "toolbox": 9, "toolkit": 11, "top": [2, 11, 15], "topic": [1, 3, 7, 8, 9, 11, 20, 21, 22], "total": 11, "touch": [14, 15], "tough": 11, "tour": 18, "toward": [1, 9, 10, 11], "track": [0, 2, 6, 9, 11, 15], "traction": 11, "trade": 15, "tradit": [9, 11, 14, 20, 22], "traffic": 11, "train": [1, 3, 9, 11, 14, 19, 20, 21, 22], "train2": 11, "trainer": [3, 11], "transcript": [11, 21], "transfer": [9, 11], "transform": 11, "transit": [1, 11, 21], "translat": [11, 21], "transmiss": 20, "transpar": 11, "trap": 15, "travel": 22, "tree": 11, "trend": [9, 11], "tri": [0, 1, 6, 11, 17], "trick": [5, 6, 7, 9, 11, 17, 20], "tricki": 11, "trim": 11, "trivial": 11, "troubl": 11, "troughout": 11, "true": 11, "try": [0, 1, 2, 3, 7, 9, 10, 11, 13, 15, 20, 21], "ttt": [10, 11], "ttt24": 3, "tuesdai": [3, 8, 11], "tune": [10, 11], "turn": [3, 11, 14, 17], "tutori": [11, 18, 20], "tweak": 11, "twice": 11, "twist": 20, "twitch": [11, 18, 22], "twitter": 11, "two": [0, 1, 2, 9, 11, 13, 14, 17, 20, 21], "txt": [3, 7, 10, 21], "type": [0, 9, 11, 13, 15, 17, 20], "typic": [1, 11, 15], "typo": [11, 20], "u": [1, 2, 3, 6, 8, 10, 11, 14, 16, 17, 20, 21, 22], "uk": 11, "umbrella": 11, "unabl": 11, "unclear": [2, 20], "uncomfort": [11, 20], "under": [9, 11, 13], "underli": 11, "understand": [0, 1, 6, 9, 10, 11, 12, 14, 17, 20], "understood": 11, "unexpect": 0, "unexpectedli": 18, "unfortun": [11, 15], "uniqu": 11, "univers": [1, 11, 20], "unix": 11, "unknown": 11, "unless": 11, "unlik": 11, "unmanag": 11, "unnecessari": [1, 6], "unpleas": 11, "unprepar": 0, "unprepared": 0, "unproblemat": 11, "unprocess": 21, "unsaf": 11, "unspecifi": 6, "unsur": 11, "until": [1, 2, 6, 11], "unwant": 11, "uo5kbtqdjzbbqb_xldhzuovx5t08fhfgr7dw7tck90i": 11, "up": [0, 1, 2, 3, 6, 7, 9, 10, 11, 12, 14, 16, 20, 21], "upcom": [3, 7, 11], "updat": [2, 3, 6, 7, 11, 13, 14], "upload": 11, "upper": 15, "upstream": 10, "urgent": [14, 17], "url": [2, 11], "us": [0, 1, 2, 3, 4, 5, 7, 8, 11, 12, 13, 15, 16, 17, 19, 20, 22], "usabl": 11, "usag": [1, 9, 11], "usb": 17, "user": [11, 21], "usernam": 2, "usual": [1, 3, 7, 11, 17], "utc": [3, 11], "v": [9, 11, 18, 21], "vagu": 11, "valid": 11, "valu": [11, 15, 20], "valuabl": [2, 6, 11, 15], "variabl": 11, "varieti": [11, 15], "variou": [0, 10, 11], "vastli": 11, "vc": 11, "ve": [11, 20, 22], "vector": 11, "vega": 11, "veri": [0, 1, 2, 3, 5, 7, 10, 11, 15, 17, 19, 20, 21], "versa": 11, "version": [1, 6, 8, 9, 20, 21], "versu": 11, "vertic": 15, "vew": 11, "via": [2, 9, 10, 11, 14], "vice": 11, "video": [3, 7, 8, 12, 13, 16, 22], "vie": 11, "view": [2, 3, 11, 12, 18], "viewpoint": [11, 20], "virtual": [10, 11, 21], "visibl": 11, "vision": 11, "visit": 3, "visual": 11, "visualis": 11, "voic": [0, 2, 11, 17], "volum": [2, 11], "volunt": [11, 14], "voluntari": 11, "vote": 11, "w": 11, "wa": [1, 2, 9, 10, 11, 14, 15, 18, 20, 21], "wai": [0, 10, 11, 12, 14, 15, 19, 20, 21], "wait": [2, 15, 20], "wake": 11, "walk": 18, "wall": 2, "want": [0, 1, 3, 7, 9, 10, 11, 14, 15, 16, 19, 20, 21, 22], "war": 20, "ward": 11, "wasn": 11, "wast": 11, "watch": [0, 10, 11, 14, 15, 20, 21], "wayland": [11, 15], "we": [0, 1, 2, 3, 5, 7, 8, 10, 12, 13, 16, 18, 19, 20], "wear": 11, "web": [2, 9, 10, 11, 14, 15], "webcam": 11, "webpag": [2, 21], "websit": [11, 15], "websocket": 18, "webwhiteboard": 11, "wed": 11, "week": [3, 7, 11, 14, 20], "weird": 16, "welcom": [11, 14, 21], "well": [0, 2, 3, 11, 15, 16, 17, 20], "went": 11, "were": [2, 9, 11, 14, 17, 21], "weren": [11, 20], "what": [0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 14, 15, 16, 17, 20], "whatev": [10, 11, 15], "whatsapp": 11, "when": [0, 1, 2, 3, 6, 9, 11, 18, 20, 21, 22], "whenev": [1, 8, 20], "where": [0, 1, 3, 7, 9, 10, 11, 14, 17, 20, 21], "wherea": 11, "wherev": 17, "whether": [0, 11, 20, 21], "which": [0, 1, 2, 3, 7, 9, 11, 12, 14, 15, 18, 20, 21], "while": [0, 2, 11, 14, 15, 20, 21], "whisper": 11, "whistl": 11, "white": 15, "whiteboard": 11, "who": [0, 1, 2, 3, 6, 7, 11, 17, 19, 21], "whole": [7, 21], "whom": 11, "why": [2, 3, 6, 7, 8, 14, 20], "wide": 11, "wider": 11, "wiki": 11, "william": 11, "win": 11, "window": [2, 11, 12, 15], "window_nam": 15, "winter": 14, "wire": [11, 12, 17, 20], "wireless": 17, "wise": 11, "wiser": 11, "wish": [1, 9, 11, 14], "within": [0, 2, 10, 11, 17, 21], "without": [0, 2, 9, 11, 15, 17, 22], "wittk": 8, "won": [2, 11, 17, 21, 22], "wonder": [11, 15, 20], "woozy_fac": 11, "word": [1, 6, 11, 17, 20, 21], "work": [0, 1, 3, 8, 10, 11, 12, 13, 14, 17, 18, 19, 20, 21], "workaround": [11, 15], "workbench": 11, "workbook": 11, "workflow": [1, 9, 10, 11, 21], "workload": 0, "workplac": 17, "workshop": [0, 3, 7, 9, 15, 17, 18, 20, 21, 22], "world": [11, 20], "worri": [2, 3, 7, 11], "wors": 11, "worsen": 11, "worst": [11, 18], "worth": [11, 21, 22], "worthwhil": [11, 20], "would": [1, 2, 3, 6, 7, 8, 9, 10, 14, 20, 21, 22], "wouldn": 2, "wow": 11, "write": [0, 1, 2, 6, 8, 9, 10, 11], "writer": [9, 11], "written": 11, "wrong": [9, 11, 17], "www": [11, 20, 21], "x": [1, 9, 11, 20], "x11": 15, "xorg": 15, "xx": [2, 3, 11], "xxx": [2, 11], "yawning_fac": 11, "ye": [0, 6, 11, 22], "yeah": 11, "year": [6, 11, 14], "yellow": 15, "yep": 11, "yet": [1, 9, 11, 12, 13, 15, 18, 21], "you": [0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22], "your": [0, 1, 2, 3, 7, 8, 11, 13, 14, 17, 18, 20], "yournam": 2, "yourself": [2, 3, 7, 9, 10, 11, 14], "yourselv": 17, "youtub": [11, 18, 20, 21, 22], "zenodo": [6, 11], "zip": 13, "zm_kb": 11, "zola": 11, "zone": 11, "zoom": [3, 7, 8, 11, 14, 15, 18, 22], "zsh": [11, 15], "zsh_histori": 11, "zulip": [1, 11], "zulipchat": 11}, "titles": ["Co-teaching", "About the CodeRefinery project and CodeRefinery workshops in general", "Collaborative notes", "Communications with participants", "Computational thinking", "Sharing teaching gems", "How we collect feedback and measure impact", "Instructor guide", "Train the trainer workshop", "Lesson design and development", "Lessons with version control", "Collaborative notes archives from workshops", "Open Broadcaster Software (OBS) introduction", "Open Broadcaster Software (OBS) setup", "A workshop seen from different perspectives", "How to prepare a quality screen-share", "Session 4 intro", "Sound", "Behind the stream", "What\u2019s next?", "CodeRefinery teaching philosophies", "Video editing", "Why we stream"], "titleterms": {"": 19, "08": 11, "09": 11, "1": [6, 8, 10, 11, 17, 21], "10": [0, 6], "13": 11, "15": 2, "2": [6, 8, 10, 11, 17, 21], "20": [9, 11, 15, 20], "2024": [8, 11], "24": 11, "27": 11, "3": [6, 8, 10, 11, 17, 21], "4": [6, 8, 10, 11, 16, 21], "5": [9, 10, 11, 21], "6": 21, "7": 21, "A": [12, 13, 14, 18, 21, 22], "One": [11, 14], "The": [9, 13, 17], "about": [1, 9, 11], "accept": 10, "add": 21, "adjust": 17, "adopt": 11, "advanc": 10, "after": 14, "all": [9, 11], "also": [12, 19, 21], "altern": 18, "ani": 0, "approach": 9, "ar": [0, 9, 17, 18], "archiv": 11, "articl": 21, "ask": [2, 6], "audienc": [1, 7, 11], "audio": 17, "august": [8, 11], "b": 21, "backward": 9, "balanc": 17, "basic": [2, 21], "bast": 20, "befor": [2, 6, 13, 14], "behind": [11, 18], "benefit": [0, 22], "best": 11, "better": 9, "between": 15, "bj\u00f8rn": 20, "breaker": 20, "breakout": 11, "breakoutroom": 11, "briefli": 22, "broadcast": [11, 12, 13], "browser": 15, "build": 10, "calendar": 11, "can": 18, "captur": 15, "carpentri": [1, 10], "case": 9, "challeng": 1, "check": [11, 17], "classroom": 11, "clone": 10, "co": [0, 11], "coderefineri": [1, 8, 9, 10, 11, 13, 18, 20], "collabor": [2, 6, 11], "collect": [6, 9, 11], "color": 15, "command": 15, "commun": [1, 3, 14], "compet": 1, "comput": [4, 11], "config": 13, "configur": 15, "contribut": 10, "control": [2, 10, 11, 13, 18], "cool": 11, "cours": [12, 13], "creat": [9, 10, 21], "dai": 11, "darst": 20, "day1": 11, "day4": 11, "defin": 1, "demo": 0, "deploy": 11, "design": [6, 9, 11], "desktop": 15, "develop": [9, 11], "did": 14, "differ": 14, "disadvantag": 22, "discuss": [0, 2, 6, 9, 10, 11, 14, 21], "distribut": 21, "do": [9, 17, 21], "document": [2, 9], "doe": 18, "don": 2, "down": 17, "downsid": 0, "dure": [12, 14], "dynam": 17, "each": [7, 13], "easi": 21, "edit": [2, 11, 21], "editlist": 21, "entir": 15, "environ": 15, "episod": 11, "evalu": [15, 17], "everyon": 2, "exampl": [2, 6, 10], "exercis": [0, 2, 6, 9, 10, 11, 15, 17, 21], "exist": 9, "experi": 11, "featur": 21, "feedback": [2, 6, 11], "ffmpeg": 21, "file": 21, "final": 21, "font": 15, "format": [2, 10], "from": [11, 14], "futur": 22, "gem": [5, 11], "gener": [1, 2, 11, 21], "get": [2, 14, 18, 21], "github": [9, 10], "giver": 0, "go": [10, 13, 18], "goal": 1, "good": 17, "great": 9, "group": [6, 9, 20], "guid": [0, 7], "habit": 15, "handl": 2, "hardwar": 12, "histori": [1, 15, 22], "host": 14, "how": [2, 6, 9, 11, 14, 15, 18, 21], "i": [12, 22], "ic": 20, "icebreak": [11, 22], "icecream": 11, "impact": [6, 11], "import": 17, "improv": [9, 11], "individu": 14, "initi": 13, "instal": 13, "instead": 15, "instructor": [0, 2, 4, 5, 6, 7, 9, 10, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22], "interfac": 12, "interview": 0, "intro": [7, 16], "introduct": [2, 11, 12, 20], "invest": 14, "involv": 14, "iter": 11, "journei": 14, "keypoint": [0, 1, 2, 4, 10, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22], "layout": [15, 18], "lead": 14, "learn": [6, 9, 15], "learner": [14, 15], "lesson": [6, 9, 10, 11], "like": [11, 14], "lindi": 20, "local": [10, 14], "longer": 6, "lot": 14, "make": 21, "manag": 2, "mani": [11, 14], "materi": 9, "measur": [6, 11], "mechan": 2, "min": [0, 2, 6, 9, 15], "minut": 20, "model": 0, "modifi": 10, "more": 21, "most": 2, "need": 15, "new": 9, "next": 19, "note": [0, 2, 4, 5, 6, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22], "novic": 1, "ob": [11, 12, 13], "object": [0, 1, 2, 4, 5, 6, 9, 10, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22], "onlin": 15, "open": [11, 12, 13], "option": 10, "other": [14, 15], "our": [1, 9], "output": 21, "overview": 0, "overwhelm": 2, "own": [10, 15], "panel": 18, "part": 14, "particip": [3, 7], "peopl": 14, "perspect": [11, 14, 15], "philosophi": [11, 20], "point": 7, "poll": 11, "portrait": 15, "post": 2, "practic": [2, 11], "practition": 1, "prepar": [7, 11, 15], "present": [0, 10], "primari": 21, "privaci": 2, "problem": [9, 17], "process": [9, 10], "project": 1, "prompt": 15, "prospect": 22, "q": [12, 13, 18, 22], "qualiti": [11, 15, 17], "question": [2, 6, 11, 22], "radovan": 20, "raw": 21, "razick": 20, "recommend": 17, "record": [20, 22], "relat": [1, 21], "remot": 13, "requir": 12, "resourc": [8, 9, 15], "result": 9, "richard": 20, "role": 14, "room": 11, "run": 21, "sabri": 20, "sampl": 21, "scene": 18, "schedul": 11, "scheme": 15, "screen": [11, 15], "see": [12, 19, 21], "seen": 14, "septemb": [8, 11], "sessiion": 11, "session": [7, 8, 11, 16], "set": [13, 15, 18], "setup": [11, 13, 14, 15], "share": [5, 9, 11, 15], "size": 15, "smallest": 10, "softwar": [11, 12, 13], "solut": 21, "sound": [11, 14, 17], "speak": 17, "specif": 0, "sphinx": 10, "step": 14, "stepa": 20, "stone": 14, "stream": [11, 18, 21, 22], "subtitl": 21, "summari": [0, 10, 17, 20, 21], "survei": 6, "switch": 15, "t": 2, "take": 6, "talk": 7, "target": [1, 7], "teach": [0, 5, 6, 9, 11, 15, 20], "team": [0, 14], "techniqu": 11, "templat": [2, 10], "term": 6, "termin": 15, "test": 21, "thi": [14, 21], "thing": [2, 11], "think": [4, 11], "through": [10, 13], "time": [6, 7, 14], "tip": 17, "todai": 11, "toliauta": 20, "tool": 11, "tour": 10, "train": 8, "trainer": 8, "try": 6, "typic": 9, "un": 15, "up": [13, 15, 17, 18], "us": [6, 9, 10, 21], "user": 12, "vc": 10, "version": [10, 11], "video": [11, 20, 21], "view": 20, "volum": 17, "we": [6, 9, 11, 14, 15, 21, 22], "websit": 2, "what": [12, 18, 19, 21, 22], "when": [15, 17], "whisper": 21, "who": 18, "why": [10, 11, 22], "window": 18, "work": [9, 15], "workshop": [1, 2, 6, 8, 11, 14], "would": 11, "wrapup": 11, "wrong": 18, "yaml": 21, "you": 9, "your": [6, 9, 10, 15, 21]}}) \ No newline at end of file diff --git a/branch/comms/session-4-intro/index.html b/branch/comms/session-4-intro/index.html new file mode 100644 index 0000000..ac8cde9 --- /dev/null +++ b/branch/comms/session-4-intro/index.html @@ -0,0 +1,190 @@ + + + + + + + Session 4 intro — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Session 4 intro

+

This session covers streaming and technical production. Some +introductory notes:

+
    +
  • (As of 2024) This is the first and only comprehensive introduction +to our online streaming.

  • +
  • These practices are new and well-refined internally, but a +different kind of refinement is needed to teach and reuse them.

  • +
  • The lessons have outlines of what to talk about, but it’s just an +outline. It is not refined, since thees things are new. Many +things will have to be figured out as we talk.

  • +
  • This session is a demo of lots of basics.

    +
      +
    • Ask questions - otherwise it will be boring

    • +
    • If you want to use this in real life: you will need mentoring +sessions and active help. Contact us to do that.

    • +
    +
  • +
+
+

Warning

+

Audio and video weirdness

+

We are setting up video and audio recording, but also capturing that +for re-sharing it. There may be anomalies as video or audio +feedback. Please be prepared.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/singlehtml/_images/BYOC.png b/branch/comms/singlehtml/_images/BYOC.png new file mode 100644 index 0000000..94702a1 Binary files /dev/null and b/branch/comms/singlehtml/_images/BYOC.png differ diff --git a/branch/comms/singlehtml/_images/CR_workshop_setup.png b/branch/comms/singlehtml/_images/CR_workshop_setup.png new file mode 100644 index 0000000..47b4502 Binary files /dev/null and b/branch/comms/singlehtml/_images/CR_workshop_setup.png differ diff --git a/branch/comms/singlehtml/_images/community.png b/branch/comms/singlehtml/_images/community.png new file mode 100644 index 0000000..ddd9a62 Binary files /dev/null and b/branch/comms/singlehtml/_images/community.png differ diff --git a/branch/comms/singlehtml/_images/hackmd--controls.png b/branch/comms/singlehtml/_images/hackmd--controls.png new file mode 100644 index 0000000..46a74c7 Binary files /dev/null and b/branch/comms/singlehtml/_images/hackmd--controls.png differ diff --git a/branch/comms/singlehtml/_images/hackmd--full-demo.png b/branch/comms/singlehtml/_images/hackmd--full-demo.png new file mode 100644 index 0000000..0988b6f Binary files /dev/null and b/branch/comms/singlehtml/_images/hackmd--full-demo.png differ diff --git a/branch/comms/singlehtml/_images/hackmd--questions2.png b/branch/comms/singlehtml/_images/hackmd--questions2.png new file mode 100644 index 0000000..a609199 Binary files /dev/null and b/branch/comms/singlehtml/_images/hackmd--questions2.png differ diff --git a/branch/comms/singlehtml/_images/history-landscape-dark.png b/branch/comms/singlehtml/_images/history-landscape-dark.png new file mode 100644 index 0000000..a1aef3c Binary files /dev/null and b/branch/comms/singlehtml/_images/history-landscape-dark.png differ diff --git a/branch/comms/singlehtml/_images/history-portrait-dark.png b/branch/comms/singlehtml/_images/history-portrait-dark.png new file mode 100644 index 0000000..2fc1fa6 Binary files /dev/null and b/branch/comms/singlehtml/_images/history-portrait-dark.png differ diff --git a/branch/comms/singlehtml/_images/history-portrait-light.png b/branch/comms/singlehtml/_images/history-portrait-light.png new file mode 100644 index 0000000..5f4361c Binary files /dev/null and b/branch/comms/singlehtml/_images/history-portrait-light.png differ diff --git a/branch/comms/singlehtml/_images/history-portrait.png b/branch/comms/singlehtml/_images/history-portrait.png new file mode 100644 index 0000000..28e18b0 Binary files /dev/null and b/branch/comms/singlehtml/_images/history-portrait.png differ diff --git a/branch/comms/singlehtml/_images/history-rsh.png b/branch/comms/singlehtml/_images/history-rsh.png new file mode 100644 index 0000000..1bbb1cc Binary files /dev/null and b/branch/comms/singlehtml/_images/history-rsh.png differ diff --git a/branch/comms/singlehtml/_images/instructor.png b/branch/comms/singlehtml/_images/instructor.png new file mode 100644 index 0000000..718f2a8 Binary files /dev/null and b/branch/comms/singlehtml/_images/instructor.png differ diff --git a/branch/comms/singlehtml/_images/landscape.png b/branch/comms/singlehtml/_images/landscape.png new file mode 100644 index 0000000..eda9d42 Binary files /dev/null and b/branch/comms/singlehtml/_images/landscape.png differ diff --git a/branch/comms/singlehtml/_images/learner-large.png b/branch/comms/singlehtml/_images/learner-large.png new file mode 100644 index 0000000..3b6d2cd Binary files /dev/null and b/branch/comms/singlehtml/_images/learner-large.png differ diff --git a/branch/comms/singlehtml/_images/learner-normal.png b/branch/comms/singlehtml/_images/learner-normal.png new file mode 100644 index 0000000..590135e Binary files /dev/null and b/branch/comms/singlehtml/_images/learner-normal.png differ diff --git a/branch/comms/singlehtml/_images/learner-small.png b/branch/comms/singlehtml/_images/learner-small.png new file mode 100644 index 0000000..5d5f421 Binary files /dev/null and b/branch/comms/singlehtml/_images/learner-small.png differ diff --git a/branch/comms/singlehtml/_images/portrait.png b/branch/comms/singlehtml/_images/portrait.png new file mode 100644 index 0000000..415799f Binary files /dev/null and b/branch/comms/singlehtml/_images/portrait.png differ diff --git a/branch/comms/singlehtml/_images/steps.png b/branch/comms/singlehtml/_images/steps.png new file mode 100644 index 0000000..6c978b5 Binary files /dev/null and b/branch/comms/singlehtml/_images/steps.png differ diff --git a/branch/comms/singlehtml/_images/survey-impact1.png b/branch/comms/singlehtml/_images/survey-impact1.png new file mode 100644 index 0000000..7dd0ddc Binary files /dev/null and b/branch/comms/singlehtml/_images/survey-impact1.png differ diff --git a/branch/comms/singlehtml/_images/survey-impact2.png b/branch/comms/singlehtml/_images/survey-impact2.png new file mode 100644 index 0000000..8771bff Binary files /dev/null and b/branch/comms/singlehtml/_images/survey-impact2.png differ diff --git a/branch/comms/singlehtml/_images/welcome.png b/branch/comms/singlehtml/_images/welcome.png new file mode 100644 index 0000000..302082c Binary files /dev/null and b/branch/comms/singlehtml/_images/welcome.png differ diff --git a/branch/comms/singlehtml/_sphinx_design_static/design-tabs.js b/branch/comms/singlehtml/_sphinx_design_static/design-tabs.js new file mode 100644 index 0000000..b25bd6a --- /dev/null +++ b/branch/comms/singlehtml/_sphinx_design_static/design-tabs.js @@ -0,0 +1,101 @@ +// @ts-check + +// Extra JS capability for selected tabs to be synced +// The selection is stored in local storage so that it persists across page loads. + +/** + * @type {Record} + */ +let sd_id_to_elements = {}; +const storageKeyPrefix = "sphinx-design-tab-id-"; + +/** + * Create a key for a tab element. + * @param {HTMLElement} el - The tab element. + * @returns {[string, string, string] | null} - The key. + * + */ +function create_key(el) { + let syncId = el.getAttribute("data-sync-id"); + let syncGroup = el.getAttribute("data-sync-group"); + if (!syncId || !syncGroup) return null; + return [syncGroup, syncId, syncGroup + "--" + syncId]; +} + +/** + * Initialize the tab selection. + * + */ +function ready() { + // Find all tabs with sync data + + /** @type {string[]} */ + let groups = []; + + document.querySelectorAll(".sd-tab-label").forEach((label) => { + if (label instanceof HTMLElement) { + let data = create_key(label); + if (data) { + let [group, id, key] = data; + + // add click event listener + // @ts-ignore + label.onclick = onSDLabelClick; + + // store map of key to elements + if (!sd_id_to_elements[key]) { + sd_id_to_elements[key] = []; + } + sd_id_to_elements[key].push(label); + + if (groups.indexOf(group) === -1) { + groups.push(group); + // Check if a specific tab has been selected via URL parameter + const tabParam = new URLSearchParams(window.location.search).get( + group + ); + if (tabParam) { + console.log( + "sphinx-design: Selecting tab id for group '" + + group + + "' from URL parameter: " + + tabParam + ); + window.sessionStorage.setItem(storageKeyPrefix + group, tabParam); + } + } + + // Check is a specific tab has been selected previously + let previousId = window.sessionStorage.getItem( + storageKeyPrefix + group + ); + if (previousId === id) { + // console.log( + // "sphinx-design: Selecting tab from session storage: " + id + // ); + // @ts-ignore + label.previousElementSibling.checked = true; + } + } + } + }); +} + +/** + * Activate other tabs with the same sync id. + * + * @this {HTMLElement} - The element that was clicked. + */ +function onSDLabelClick() { + let data = create_key(this); + if (!data) return; + let [group, id, key] = data; + for (const label of sd_id_to_elements[key]) { + if (label === this) continue; + // @ts-ignore + label.previousElementSibling.checked = true; + } + window.sessionStorage.setItem(storageKeyPrefix + group, id); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/branch/comms/singlehtml/_sphinx_design_static/sphinx-design.min.css b/branch/comms/singlehtml/_sphinx_design_static/sphinx-design.min.css new file mode 100644 index 0000000..860c36d --- /dev/null +++ b/branch/comms/singlehtml/_sphinx_design_static/sphinx-design.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative;font-size:var(--sd-fontsize-dropdown)}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary.sd-summary-title{padding:.5em .6em .5em 1em;font-size:var(--sd-fontsize-dropdown-title);font-weight:var(--sd-fontweight-dropdown-title);user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;list-style:none;display:inline-flex;justify-content:space-between}details.sd-dropdown summary.sd-summary-title::-webkit-details-marker{display:none}details.sd-dropdown summary.sd-summary-title:focus{outline:none}details.sd-dropdown summary.sd-summary-title .sd-summary-icon{margin-right:.6em;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary.sd-summary-title .sd-summary-text{flex-grow:1;line-height:1.5;padding-right:.5rem}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker{pointer-events:none;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker svg{opacity:.6}details.sd-dropdown summary.sd-summary-title:hover .sd-summary-state-marker svg{opacity:1;transform:scale(1.1)}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown .sd-summary-chevron-right{transition:.25s}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-right{transform:rotate(90deg)}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-down{transform:rotate(180deg)}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-bg: rgba(0, 113, 188, 0.2);--sd-color-secondary-bg: rgba(108, 117, 125, 0.2);--sd-color-success-bg: rgba(40, 167, 69, 0.2);--sd-color-info-bg: rgba(23, 162, 184, 0.2);--sd-color-warning-bg: rgba(240, 179, 126, 0.2);--sd-color-danger-bg: rgba(220, 53, 69, 0.2);--sd-color-light-bg: rgba(248, 249, 250, 0.2);--sd-color-muted-bg: rgba(108, 117, 125, 0.2);--sd-color-dark-bg: rgba(33, 37, 41, 0.2);--sd-color-black-bg: rgba(0, 0, 0, 0.2);--sd-color-white-bg: rgba(255, 255, 255, 0.2);--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem;--sd-fontsize-dropdown: inherit;--sd-fontsize-dropdown-title: 1rem;--sd-fontweight-dropdown-title: 700} diff --git a/branch/comms/singlehtml/_static/_sphinx_javascript_frameworks_compat.js b/branch/comms/singlehtml/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 0000000..8141580 --- /dev/null +++ b/branch/comms/singlehtml/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/branch/comms/singlehtml/_static/basic.css b/branch/comms/singlehtml/_static/basic.css new file mode 100644 index 0000000..f316efc --- /dev/null +++ b/branch/comms/singlehtml/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/branch/comms/singlehtml/_static/check-solid.svg b/branch/comms/singlehtml/_static/check-solid.svg new file mode 100644 index 0000000..92fad4b --- /dev/null +++ b/branch/comms/singlehtml/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/branch/comms/singlehtml/_static/clipboard.min.js b/branch/comms/singlehtml/_static/clipboard.min.js new file mode 100644 index 0000000..54b3c46 --- /dev/null +++ b/branch/comms/singlehtml/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/branch/comms/singlehtml/_static/copybutton.css b/branch/comms/singlehtml/_static/copybutton.css new file mode 100644 index 0000000..f1916ec --- /dev/null +++ b/branch/comms/singlehtml/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/branch/comms/singlehtml/_static/copybutton.js b/branch/comms/singlehtml/_static/copybutton.js new file mode 100644 index 0000000..2ea7ff3 --- /dev/null +++ b/branch/comms/singlehtml/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/branch/comms/singlehtml/_static/copybutton_funcs.js b/branch/comms/singlehtml/_static/copybutton_funcs.js new file mode 100644 index 0000000..dbe1aaa --- /dev/null +++ b/branch/comms/singlehtml/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/branch/comms/singlehtml/_static/css/badge_only.css b/branch/comms/singlehtml/_static/css/badge_only.css new file mode 100644 index 0000000..c718cee --- /dev/null +++ b/branch/comms/singlehtml/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/branch/comms/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff b/branch/comms/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/branch/comms/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/branch/comms/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff2 b/branch/comms/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/branch/comms/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/branch/comms/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff b/branch/comms/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/branch/comms/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/branch/comms/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff2 b/branch/comms/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/branch/comms/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/branch/comms/singlehtml/_static/css/fonts/fontawesome-webfont.eot b/branch/comms/singlehtml/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/branch/comms/singlehtml/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/branch/comms/singlehtml/_static/css/fonts/fontawesome-webfont.svg b/branch/comms/singlehtml/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/branch/comms/singlehtml/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/branch/comms/singlehtml/_static/css/fonts/fontawesome-webfont.ttf b/branch/comms/singlehtml/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/branch/comms/singlehtml/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/branch/comms/singlehtml/_static/css/fonts/fontawesome-webfont.woff b/branch/comms/singlehtml/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/branch/comms/singlehtml/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/branch/comms/singlehtml/_static/css/fonts/fontawesome-webfont.woff2 b/branch/comms/singlehtml/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/branch/comms/singlehtml/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/branch/comms/singlehtml/_static/css/fonts/lato-bold-italic.woff b/branch/comms/singlehtml/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/branch/comms/singlehtml/_static/css/fonts/lato-bold-italic.woff differ diff --git a/branch/comms/singlehtml/_static/css/fonts/lato-bold-italic.woff2 b/branch/comms/singlehtml/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/branch/comms/singlehtml/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/branch/comms/singlehtml/_static/css/fonts/lato-bold.woff b/branch/comms/singlehtml/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/branch/comms/singlehtml/_static/css/fonts/lato-bold.woff differ diff --git a/branch/comms/singlehtml/_static/css/fonts/lato-bold.woff2 b/branch/comms/singlehtml/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/branch/comms/singlehtml/_static/css/fonts/lato-bold.woff2 differ diff --git a/branch/comms/singlehtml/_static/css/fonts/lato-normal-italic.woff b/branch/comms/singlehtml/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/branch/comms/singlehtml/_static/css/fonts/lato-normal-italic.woff differ diff --git a/branch/comms/singlehtml/_static/css/fonts/lato-normal-italic.woff2 b/branch/comms/singlehtml/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/branch/comms/singlehtml/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/branch/comms/singlehtml/_static/css/fonts/lato-normal.woff b/branch/comms/singlehtml/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/branch/comms/singlehtml/_static/css/fonts/lato-normal.woff differ diff --git a/branch/comms/singlehtml/_static/css/fonts/lato-normal.woff2 b/branch/comms/singlehtml/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/branch/comms/singlehtml/_static/css/fonts/lato-normal.woff2 differ diff --git a/branch/comms/singlehtml/_static/css/theme.css b/branch/comms/singlehtml/_static/css/theme.css new file mode 100644 index 0000000..19a446a --- /dev/null +++ b/branch/comms/singlehtml/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/branch/comms/singlehtml/_static/design-tabs.js b/branch/comms/singlehtml/_static/design-tabs.js new file mode 100644 index 0000000..b25bd6a --- /dev/null +++ b/branch/comms/singlehtml/_static/design-tabs.js @@ -0,0 +1,101 @@ +// @ts-check + +// Extra JS capability for selected tabs to be synced +// The selection is stored in local storage so that it persists across page loads. + +/** + * @type {Record} + */ +let sd_id_to_elements = {}; +const storageKeyPrefix = "sphinx-design-tab-id-"; + +/** + * Create a key for a tab element. + * @param {HTMLElement} el - The tab element. + * @returns {[string, string, string] | null} - The key. + * + */ +function create_key(el) { + let syncId = el.getAttribute("data-sync-id"); + let syncGroup = el.getAttribute("data-sync-group"); + if (!syncId || !syncGroup) return null; + return [syncGroup, syncId, syncGroup + "--" + syncId]; +} + +/** + * Initialize the tab selection. + * + */ +function ready() { + // Find all tabs with sync data + + /** @type {string[]} */ + let groups = []; + + document.querySelectorAll(".sd-tab-label").forEach((label) => { + if (label instanceof HTMLElement) { + let data = create_key(label); + if (data) { + let [group, id, key] = data; + + // add click event listener + // @ts-ignore + label.onclick = onSDLabelClick; + + // store map of key to elements + if (!sd_id_to_elements[key]) { + sd_id_to_elements[key] = []; + } + sd_id_to_elements[key].push(label); + + if (groups.indexOf(group) === -1) { + groups.push(group); + // Check if a specific tab has been selected via URL parameter + const tabParam = new URLSearchParams(window.location.search).get( + group + ); + if (tabParam) { + console.log( + "sphinx-design: Selecting tab id for group '" + + group + + "' from URL parameter: " + + tabParam + ); + window.sessionStorage.setItem(storageKeyPrefix + group, tabParam); + } + } + + // Check is a specific tab has been selected previously + let previousId = window.sessionStorage.getItem( + storageKeyPrefix + group + ); + if (previousId === id) { + // console.log( + // "sphinx-design: Selecting tab from session storage: " + id + // ); + // @ts-ignore + label.previousElementSibling.checked = true; + } + } + } + }); +} + +/** + * Activate other tabs with the same sync id. + * + * @this {HTMLElement} - The element that was clicked. + */ +function onSDLabelClick() { + let data = create_key(this); + if (!data) return; + let [group, id, key] = data; + for (const label of sd_id_to_elements[key]) { + if (label === this) continue; + // @ts-ignore + label.previousElementSibling.checked = true; + } + window.sessionStorage.setItem(storageKeyPrefix + group, id); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/branch/comms/singlehtml/_static/doctools.js b/branch/comms/singlehtml/_static/doctools.js new file mode 100644 index 0000000..4d67807 --- /dev/null +++ b/branch/comms/singlehtml/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/branch/comms/singlehtml/_static/documentation_options.js b/branch/comms/singlehtml/_static/documentation_options.js new file mode 100644 index 0000000..89003c6 --- /dev/null +++ b/branch/comms/singlehtml/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'singlehtml', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/branch/comms/singlehtml/_static/file.png b/branch/comms/singlehtml/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/branch/comms/singlehtml/_static/file.png differ diff --git a/branch/comms/singlehtml/_static/jquery.js b/branch/comms/singlehtml/_static/jquery.js new file mode 100644 index 0000000..c4c6022 --- /dev/null +++ b/branch/comms/singlehtml/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!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(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=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,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).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 w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\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(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.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,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){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 H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.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--)b.attrHandle[n[r]]=t}function pe(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 de(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 d=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")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.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}},b.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[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.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},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),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(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.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},j=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)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(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==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(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?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{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 G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.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("(^|"+M+")"+e+"("+M+"|$)"))&&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:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.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 S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(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").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.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),m(t)&&(t=t.call(e,n,S.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)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.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"===S.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"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.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)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.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?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.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)}}),S.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){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/comms/singlehtml/_static/js/html5shiv.min.js b/branch/comms/singlehtml/_static/js/html5shiv.min.js new file mode 100644 index 0000000..cd1c674 --- /dev/null +++ b/branch/comms/singlehtml/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/comms/singlehtml/_static/js/theme.js b/branch/comms/singlehtml/_static/js/theme.js new file mode 100644 index 0000000..1fddb6e --- /dev/null +++ b/branch/comms/singlehtml/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/branch/comms/singlehtml/_static/minipres.js b/branch/comms/singlehtml/_static/minipres.js new file mode 100644 index 0000000..ad11c87 --- /dev/null +++ b/branch/comms/singlehtml/_static/minipres.js @@ -0,0 +1,223 @@ +// Add goTo method to elements +// http://stackoverflow.com/questions/4801655/how-to-go-to-a-specific-element-on-page +(function($) { + $.fn.goTo = function() { + $('html, body').animate({ + scrollTop: $(this).offset().top //+ 'px' + }, 'fast'); + return this; // for chaining... + } +})(jQuery); + +// NO good way to do this!. Copy a hack from here +// https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript +// https://stackoverflow.com/a/2880929 +var urlParams; +(window.onpopstate = function () { + var match, + pl = /\+/g, // Regex for replacing addition symbol with a space + search = /([^&=]+)=?([^&]*)/g, + decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, + query = window.location.search.substring(1); + urlParams = {}; + while (match = search.exec(query)) + urlParams[decode(match[1])] = decode(match[2]); +})(); + +// Select heading levels +var maxHeading = urlParams['h'] +if (maxHeading === undefined) maxHeading = 2 +var headingLevels = []; +for (h=2 ; h (sections.length-1) ) { + // if we would scroll past bottom, or above top, do nothing + return; + } + + console.log('xxxxxx'); + var targetSection = sections[targetPos]; + console.log(targetSection, typeof(targetSection)); + + // Return targetSection top and height + var secProperties = section_top_and_height(targetSection); + var top = secProperties['top']; + var height = secProperties['height'] + var win_height = window.innerHeight; + //console.info(top, height, win_height) + + var scroll_to = 0; + if (height >= win_height || height == 0) { + scroll_to = top; + } else { + scroll_to = top - (win_height-height)/3.; + } + //console.info(top, height, win_height, scroll_to) + + $('html, body').animate({ + scrollTop: scroll_to //+ 'px' + }, 'fast'); + +} + + +function minipres() { + /* Enable the minipres mode: + - call the hide() function + - set up the scrolling listener + */ + document.addEventListener('keydown', function (event) { + switch(event.which) { + case 37: // left + switch_slide(-1); + event.preventDefault(); + return false; + break; + //case 38: // up + case 39: // right + switch_slide(+1); + event.preventDefault(); + return false; + break; + //case 40: // down + default: + return; // exit this handler for other keys + } + }, true) + + hide() + + // Increase space between sections + //$("div .section").css('margin-bottom', '50%'); + $(sectionSelector).css('margin-top', '50%'); + + // Reduce size/color of other sections + if (hiddenSectionSelector.length > 0) { + var hideNodes = $(hiddenSectionSelector); + console.log(typeof hideNodes, hideNodes); + for (node in hideNodes) { + console.log("a", typeof node, node); + node = hideNodes[node]; // what's right way to iterate values? + console.log("b", typeof node, node); + if (node.parentNode && node.parentNode.className == "section") { + node = node.parentNode; + console.log("c", typeof node, node); + //node.css['transform'] = 'scale(.5)'; + //node.css['transform-origin'] = 'top center'; + $(node).css('color', 'lightgrey'); + //$(node).css('font-size', '20%'); + //$(node).css('visibility', 'collapse'); + //ntahousnatouhasno; + } + } + } +} + +function hide() { + /* Hide all non-essential elements on the page + */ + + // This is for sphinx_rst_theme and readthedocs + $(".wy-nav-side").remove(); + $(".wy-nav-content-wrap").css('margin-left', 0); + $('.rst-versions').remove(); // readthedocs version selector + + // Add other formats here. +} + + +var slideshow = minipres; + +if (window.location.search.match(/[?&](minipres|slideshow|pres)([=&]|$)/) ) { + //minipres() + window.addEventListener("load", minipres); +} else if (window.location.search.match(/[?&](plain)([=&]|$)/) ) { + window.addEventListener("load", hide); +} diff --git a/branch/comms/singlehtml/_static/minus.png b/branch/comms/singlehtml/_static/minus.png new file mode 100644 index 0000000..d96755f Binary files /dev/null and b/branch/comms/singlehtml/_static/minus.png differ diff --git a/branch/comms/singlehtml/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css b/branch/comms/singlehtml/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css new file mode 100644 index 0000000..3356631 --- /dev/null +++ b/branch/comms/singlehtml/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css @@ -0,0 +1,2342 @@ +/* Variables */ +:root { + --mystnb-source-bg-color: #f7f7f7; + --mystnb-stdout-bg-color: #fcfcfc; + --mystnb-stderr-bg-color: #fdd; + --mystnb-traceback-bg-color: #fcfcfc; + --mystnb-source-border-color: #ccc; + --mystnb-source-margin-color: green; + --mystnb-stdout-border-color: #f7f7f7; + --mystnb-stderr-border-color: #f7f7f7; + --mystnb-traceback-border-color: #ffd6d6; + --mystnb-hide-prompt-opacity: 70%; + --mystnb-source-border-radius: .4em; + --mystnb-source-border-width: 1px; +} + +/* Whole cell */ +div.container.cell { + padding-left: 0; + margin-bottom: 1em; +} + +/* Removing all background formatting so we can control at the div level */ +.cell_input div.highlight, +.cell_output pre, +.cell_input pre, +.cell_output .output { + border: none; + box-shadow: none; +} + +.cell_output .output pre, +.cell_input pre { + margin: 0px; +} + +/* Input cells */ +div.cell div.cell_input, +div.cell details.above-input>summary { + padding-left: 0em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + background-color: var(--mystnb-source-bg-color); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; + border-radius: var(--mystnb-source-border-radius); +} + +div.cell_input>div, +div.cell_output div.output>div.highlight { + margin: 0em !important; + border: none !important; +} + +/* All cell outputs */ +.cell_output { + padding-left: 1em; + padding-right: 0em; + margin-top: 1em; +} + +/* Text outputs from cells */ +.cell_output .output.text_plain, +.cell_output .output.traceback, +.cell_output .output.stream, +.cell_output .output.stderr { + margin-top: 1em; + margin-bottom: 0em; + box-shadow: none; +} + +.cell_output .output.text_plain, +.cell_output .output.stream { + background: var(--mystnb-stdout-bg-color); + border: 1px solid var(--mystnb-stdout-border-color); +} + +.cell_output .output.stderr { + background: var(--mystnb-stderr-bg-color); + border: 1px solid var(--mystnb-stderr-border-color); +} + +.cell_output .output.traceback { + background: var(--mystnb-traceback-bg-color); + border: 1px solid var(--mystnb-traceback-border-color); +} + +/* Collapsible cell content */ +div.cell details.above-input div.cell_input { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-top: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; +} + +div.cell div.cell_input.above-output-prompt { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +div.cell details.above-input>summary { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; + padding-left: 1em; + margin-bottom: 0; +} + +div.cell details.above-output>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.below-input>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-top: none; + border-bottom-left-radius: var(--mystnb-source-border-radius); + border-bottom-right-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.hide>summary>span { + opacity: var(--mystnb-hide-prompt-opacity); +} + +div.cell details.hide[open]>summary>span.collapsed { + display: none; +} + +div.cell details.hide:not([open])>summary>span.expanded { + display: none; +} + +@keyframes collapsed-fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} +div.cell details.hide[open]>summary~* { + -moz-animation: collapsed-fade-in 0.3s ease-in-out; + -webkit-animation: collapsed-fade-in 0.3s ease-in-out; + animation: collapsed-fade-in 0.3s ease-in-out; +} + +/* Math align to the left */ +.cell_output .MathJax_Display { + text-align: left !important; +} + +/* Pandas tables. Pulled from the Jupyter / nbsphinx CSS */ +div.cell_output table { + border: none; + border-collapse: collapse; + border-spacing: 0; + color: black; + font-size: 1em; + table-layout: fixed; +} + +div.cell_output thead { + border-bottom: 1px solid black; + vertical-align: bottom; +} + +div.cell_output tr, +div.cell_output th, +div.cell_output td { + text-align: right; + vertical-align: middle; + padding: 0.5em 0.5em; + line-height: normal; + white-space: normal; + max-width: none; + border: none; +} + +div.cell_output th { + font-weight: bold; +} + +div.cell_output tbody tr:nth-child(odd) { + background: #f5f5f5; +} + +div.cell_output tbody tr:hover { + background: rgba(66, 165, 245, 0.2); +} + +/** source code line numbers **/ +span.linenos { + opacity: 0.5; +} + +/* Inline text from `paste` operation */ + +span.pasted-text { + font-weight: bold; +} + +span.pasted-inline img { + max-height: 2em; +} + +tbody span.pasted-inline img { + max-height: none; +} + +/* Font colors for translated ANSI escape sequences +Color values are copied from Jupyter Notebook +https://github.com/jupyter/notebook/blob/52581f8eda9b319eb0390ac77fe5903c38f81e3e/notebook/static/notebook/less/ansicolors.less#L14-L21 +Background colors from +https://nbsphinx.readthedocs.io/en/latest/code-cells.html#ANSI-Colors +*/ +div.highlight .-Color-Bold { + font-weight: bold; +} + +div.highlight .-Color[class*=-Black] { + color: #3E424D +} + +div.highlight .-Color[class*=-Red] { + color: #E75C58 +} + +div.highlight .-Color[class*=-Green] { + color: #00A250 +} + +div.highlight .-Color[class*=-Yellow] { + color: #DDB62B +} + +div.highlight .-Color[class*=-Blue] { + color: #208FFB +} + +div.highlight .-Color[class*=-Magenta] { + color: #D160C4 +} + +div.highlight .-Color[class*=-Cyan] { + color: #60C6C8 +} + +div.highlight .-Color[class*=-White] { + color: #C5C1B4 +} + +div.highlight .-Color[class*=-BGBlack] { + background-color: #3E424D +} + +div.highlight .-Color[class*=-BGRed] { + background-color: #E75C58 +} + +div.highlight .-Color[class*=-BGGreen] { + background-color: #00A250 +} + +div.highlight .-Color[class*=-BGYellow] { + background-color: #DDB62B +} + +div.highlight .-Color[class*=-BGBlue] { + background-color: #208FFB +} + +div.highlight .-Color[class*=-BGMagenta] { + background-color: #D160C4 +} + +div.highlight .-Color[class*=-BGCyan] { + background-color: #60C6C8 +} + +div.highlight .-Color[class*=-BGWhite] { + background-color: #C5C1B4 +} + +/* Font colors for 8-bit ANSI */ + +div.highlight .-Color[class*=-C0] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC0] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C1] { + color: #800000 +} + +div.highlight .-Color[class*=-BGC1] { + background-color: #800000 +} + +div.highlight .-Color[class*=-C2] { + color: #008000 +} + +div.highlight .-Color[class*=-BGC2] { + background-color: #008000 +} + +div.highlight .-Color[class*=-C3] { + color: #808000 +} + +div.highlight .-Color[class*=-BGC3] { + background-color: #808000 +} + +div.highlight .-Color[class*=-C4] { + color: #000080 +} + +div.highlight .-Color[class*=-BGC4] { + background-color: #000080 +} + +div.highlight .-Color[class*=-C5] { + color: #800080 +} + +div.highlight .-Color[class*=-BGC5] { + background-color: #800080 +} + +div.highlight .-Color[class*=-C6] { + color: #008080 +} + +div.highlight .-Color[class*=-BGC6] { + background-color: #008080 +} + +div.highlight .-Color[class*=-C7] { + color: #C0C0C0 +} + +div.highlight .-Color[class*=-BGC7] { + background-color: #C0C0C0 +} + +div.highlight .-Color[class*=-C8] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC8] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C9] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC9] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C10] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC10] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C11] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC11] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C12] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC12] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C13] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC13] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C14] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC14] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C15] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC15] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C16] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC16] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C17] { + color: #00005F +} + +div.highlight .-Color[class*=-BGC17] { + background-color: #00005F +} + +div.highlight .-Color[class*=-C18] { + color: #000087 +} + +div.highlight .-Color[class*=-BGC18] { + background-color: #000087 +} + +div.highlight .-Color[class*=-C19] { + color: #0000AF +} + +div.highlight .-Color[class*=-BGC19] { + background-color: #0000AF +} + +div.highlight .-Color[class*=-C20] { + color: #0000D7 +} + +div.highlight .-Color[class*=-BGC20] { + background-color: #0000D7 +} + +div.highlight .-Color[class*=-C21] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC21] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C22] { + color: #005F00 +} + +div.highlight .-Color[class*=-BGC22] { + background-color: #005F00 +} + +div.highlight .-Color[class*=-C23] { + color: #005F5F +} + +div.highlight .-Color[class*=-BGC23] { + background-color: #005F5F +} + +div.highlight .-Color[class*=-C24] { + color: #005F87 +} + +div.highlight .-Color[class*=-BGC24] { + background-color: #005F87 +} + +div.highlight .-Color[class*=-C25] { + color: #005FAF +} + +div.highlight .-Color[class*=-BGC25] { + background-color: #005FAF +} + +div.highlight .-Color[class*=-C26] { + color: #005FD7 +} + +div.highlight .-Color[class*=-BGC26] { + background-color: #005FD7 +} + +div.highlight .-Color[class*=-C27] { + color: #005FFF +} + +div.highlight .-Color[class*=-BGC27] { + background-color: #005FFF +} + +div.highlight .-Color[class*=-C28] { + color: #008700 +} + +div.highlight .-Color[class*=-BGC28] { + background-color: #008700 +} + +div.highlight .-Color[class*=-C29] { + color: #00875F +} + +div.highlight .-Color[class*=-BGC29] { + background-color: #00875F +} + +div.highlight .-Color[class*=-C30] { + color: #008787 +} + +div.highlight .-Color[class*=-BGC30] { + background-color: #008787 +} + +div.highlight .-Color[class*=-C31] { + color: #0087AF +} + +div.highlight .-Color[class*=-BGC31] { + background-color: #0087AF +} + +div.highlight .-Color[class*=-C32] { + color: #0087D7 +} + +div.highlight .-Color[class*=-BGC32] { + background-color: #0087D7 +} + +div.highlight .-Color[class*=-C33] { + color: #0087FF +} + +div.highlight .-Color[class*=-BGC33] { + background-color: #0087FF +} + +div.highlight .-Color[class*=-C34] { + color: #00AF00 +} + +div.highlight .-Color[class*=-BGC34] { + background-color: #00AF00 +} + +div.highlight .-Color[class*=-C35] { + color: #00AF5F +} + +div.highlight .-Color[class*=-BGC35] { + background-color: #00AF5F +} + +div.highlight .-Color[class*=-C36] { + color: #00AF87 +} + +div.highlight .-Color[class*=-BGC36] { + background-color: #00AF87 +} + +div.highlight .-Color[class*=-C37] { + color: #00AFAF +} + +div.highlight .-Color[class*=-BGC37] { + background-color: #00AFAF +} + +div.highlight .-Color[class*=-C38] { + color: #00AFD7 +} + +div.highlight .-Color[class*=-BGC38] { + background-color: #00AFD7 +} + +div.highlight .-Color[class*=-C39] { + color: #00AFFF +} + +div.highlight .-Color[class*=-BGC39] { + background-color: #00AFFF +} + +div.highlight .-Color[class*=-C40] { + color: #00D700 +} + +div.highlight .-Color[class*=-BGC40] { + background-color: #00D700 +} + +div.highlight .-Color[class*=-C41] { + color: #00D75F +} + +div.highlight .-Color[class*=-BGC41] { + background-color: #00D75F +} + +div.highlight .-Color[class*=-C42] { + color: #00D787 +} + +div.highlight .-Color[class*=-BGC42] { + background-color: #00D787 +} + +div.highlight .-Color[class*=-C43] { + color: #00D7AF +} + +div.highlight .-Color[class*=-BGC43] { + background-color: #00D7AF +} + +div.highlight .-Color[class*=-C44] { + color: #00D7D7 +} + +div.highlight .-Color[class*=-BGC44] { + background-color: #00D7D7 +} + +div.highlight .-Color[class*=-C45] { + color: #00D7FF +} + +div.highlight .-Color[class*=-BGC45] { + background-color: #00D7FF +} + +div.highlight .-Color[class*=-C46] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC46] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C47] { + color: #00FF5F +} + +div.highlight .-Color[class*=-BGC47] { + background-color: #00FF5F +} + +div.highlight .-Color[class*=-C48] { + color: #00FF87 +} + +div.highlight .-Color[class*=-BGC48] { + background-color: #00FF87 +} + +div.highlight .-Color[class*=-C49] { + color: #00FFAF +} + +div.highlight .-Color[class*=-BGC49] { + background-color: #00FFAF +} + +div.highlight .-Color[class*=-C50] { + color: #00FFD7 +} + +div.highlight .-Color[class*=-BGC50] { + background-color: #00FFD7 +} + +div.highlight .-Color[class*=-C51] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC51] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C52] { + color: #5F0000 +} + +div.highlight .-Color[class*=-BGC52] { + background-color: #5F0000 +} + +div.highlight .-Color[class*=-C53] { + color: #5F005F +} + +div.highlight .-Color[class*=-BGC53] { + background-color: #5F005F +} + +div.highlight .-Color[class*=-C54] { + color: #5F0087 +} + +div.highlight .-Color[class*=-BGC54] { + background-color: #5F0087 +} + +div.highlight .-Color[class*=-C55] { + color: #5F00AF +} + +div.highlight .-Color[class*=-BGC55] { + background-color: #5F00AF +} + +div.highlight .-Color[class*=-C56] { + color: #5F00D7 +} + +div.highlight .-Color[class*=-BGC56] { + background-color: #5F00D7 +} + +div.highlight .-Color[class*=-C57] { + color: #5F00FF +} + +div.highlight .-Color[class*=-BGC57] { + background-color: #5F00FF +} + +div.highlight .-Color[class*=-C58] { + color: #5F5F00 +} + +div.highlight .-Color[class*=-BGC58] { + background-color: #5F5F00 +} + +div.highlight .-Color[class*=-C59] { + color: #5F5F5F +} + +div.highlight .-Color[class*=-BGC59] { + background-color: #5F5F5F +} + +div.highlight .-Color[class*=-C60] { + color: #5F5F87 +} + +div.highlight .-Color[class*=-BGC60] { + background-color: #5F5F87 +} + +div.highlight .-Color[class*=-C61] { + color: #5F5FAF +} + +div.highlight .-Color[class*=-BGC61] { + background-color: #5F5FAF +} + +div.highlight .-Color[class*=-C62] { + color: #5F5FD7 +} + +div.highlight .-Color[class*=-BGC62] { + background-color: #5F5FD7 +} + +div.highlight .-Color[class*=-C63] { + color: #5F5FFF +} + +div.highlight .-Color[class*=-BGC63] { + background-color: #5F5FFF +} + +div.highlight .-Color[class*=-C64] { + color: #5F8700 +} + +div.highlight .-Color[class*=-BGC64] { + background-color: #5F8700 +} + +div.highlight .-Color[class*=-C65] { + color: #5F875F +} + +div.highlight .-Color[class*=-BGC65] { + background-color: #5F875F +} + +div.highlight .-Color[class*=-C66] { + color: #5F8787 +} + +div.highlight .-Color[class*=-BGC66] { + background-color: #5F8787 +} + +div.highlight .-Color[class*=-C67] { + color: #5F87AF +} + +div.highlight .-Color[class*=-BGC67] { + background-color: #5F87AF +} + +div.highlight .-Color[class*=-C68] { + color: #5F87D7 +} + +div.highlight .-Color[class*=-BGC68] { + background-color: #5F87D7 +} + +div.highlight .-Color[class*=-C69] { + color: #5F87FF +} + +div.highlight .-Color[class*=-BGC69] { + background-color: #5F87FF +} + +div.highlight .-Color[class*=-C70] { + color: #5FAF00 +} + +div.highlight .-Color[class*=-BGC70] { + background-color: #5FAF00 +} + +div.highlight .-Color[class*=-C71] { + color: #5FAF5F +} + +div.highlight .-Color[class*=-BGC71] { + background-color: #5FAF5F +} + +div.highlight .-Color[class*=-C72] { + color: #5FAF87 +} + +div.highlight .-Color[class*=-BGC72] { + background-color: #5FAF87 +} + +div.highlight .-Color[class*=-C73] { + color: #5FAFAF +} + +div.highlight .-Color[class*=-BGC73] { + background-color: #5FAFAF +} + +div.highlight .-Color[class*=-C74] { + color: #5FAFD7 +} + +div.highlight .-Color[class*=-BGC74] { + background-color: #5FAFD7 +} + +div.highlight .-Color[class*=-C75] { + color: #5FAFFF +} + +div.highlight .-Color[class*=-BGC75] { + background-color: #5FAFFF +} + +div.highlight .-Color[class*=-C76] { + color: #5FD700 +} + +div.highlight .-Color[class*=-BGC76] { + background-color: #5FD700 +} + +div.highlight .-Color[class*=-C77] { + color: #5FD75F +} + +div.highlight .-Color[class*=-BGC77] { + background-color: #5FD75F +} + +div.highlight .-Color[class*=-C78] { + color: #5FD787 +} + +div.highlight .-Color[class*=-BGC78] { + background-color: #5FD787 +} + +div.highlight .-Color[class*=-C79] { + color: #5FD7AF +} + +div.highlight .-Color[class*=-BGC79] { + background-color: #5FD7AF +} + +div.highlight .-Color[class*=-C80] { + color: #5FD7D7 +} + +div.highlight .-Color[class*=-BGC80] { + background-color: #5FD7D7 +} + +div.highlight .-Color[class*=-C81] { + color: #5FD7FF +} + +div.highlight .-Color[class*=-BGC81] { + background-color: #5FD7FF +} + +div.highlight .-Color[class*=-C82] { + color: #5FFF00 +} + +div.highlight .-Color[class*=-BGC82] { + background-color: #5FFF00 +} + +div.highlight .-Color[class*=-C83] { + color: #5FFF5F +} + +div.highlight .-Color[class*=-BGC83] { + background-color: #5FFF5F +} + +div.highlight .-Color[class*=-C84] { + color: #5FFF87 +} + +div.highlight .-Color[class*=-BGC84] { + background-color: #5FFF87 +} + +div.highlight .-Color[class*=-C85] { + color: #5FFFAF +} + +div.highlight .-Color[class*=-BGC85] { + background-color: #5FFFAF +} + +div.highlight .-Color[class*=-C86] { + color: #5FFFD7 +} + +div.highlight .-Color[class*=-BGC86] { + background-color: #5FFFD7 +} + +div.highlight .-Color[class*=-C87] { + color: #5FFFFF +} + +div.highlight .-Color[class*=-BGC87] { + background-color: #5FFFFF +} + +div.highlight .-Color[class*=-C88] { + color: #870000 +} + +div.highlight .-Color[class*=-BGC88] { + background-color: #870000 +} + +div.highlight .-Color[class*=-C89] { + color: #87005F +} + +div.highlight .-Color[class*=-BGC89] { + background-color: #87005F +} + +div.highlight .-Color[class*=-C90] { + color: #870087 +} + +div.highlight .-Color[class*=-BGC90] { + background-color: #870087 +} + +div.highlight .-Color[class*=-C91] { + color: #8700AF +} + +div.highlight .-Color[class*=-BGC91] { + background-color: #8700AF +} + +div.highlight .-Color[class*=-C92] { + color: #8700D7 +} + +div.highlight .-Color[class*=-BGC92] { + background-color: #8700D7 +} + +div.highlight .-Color[class*=-C93] { + color: #8700FF +} + +div.highlight .-Color[class*=-BGC93] { + background-color: #8700FF +} + +div.highlight .-Color[class*=-C94] { + color: #875F00 +} + +div.highlight .-Color[class*=-BGC94] { + background-color: #875F00 +} + +div.highlight .-Color[class*=-C95] { + color: #875F5F +} + +div.highlight .-Color[class*=-BGC95] { + background-color: #875F5F +} + +div.highlight .-Color[class*=-C96] { + color: #875F87 +} + +div.highlight .-Color[class*=-BGC96] { + background-color: #875F87 +} + +div.highlight .-Color[class*=-C97] { + color: #875FAF +} + +div.highlight .-Color[class*=-BGC97] { + background-color: #875FAF +} + +div.highlight .-Color[class*=-C98] { + color: #875FD7 +} + +div.highlight .-Color[class*=-BGC98] { + background-color: #875FD7 +} + +div.highlight .-Color[class*=-C99] { + color: #875FFF +} + +div.highlight .-Color[class*=-BGC99] { + background-color: #875FFF +} + +div.highlight .-Color[class*=-C100] { + color: #878700 +} + +div.highlight .-Color[class*=-BGC100] { + background-color: #878700 +} + +div.highlight .-Color[class*=-C101] { + color: #87875F +} + +div.highlight .-Color[class*=-BGC101] { + background-color: #87875F +} + +div.highlight .-Color[class*=-C102] { + color: #878787 +} + +div.highlight .-Color[class*=-BGC102] { + background-color: #878787 +} + +div.highlight .-Color[class*=-C103] { + color: #8787AF +} + +div.highlight .-Color[class*=-BGC103] { + background-color: #8787AF +} + +div.highlight .-Color[class*=-C104] { + color: #8787D7 +} + +div.highlight .-Color[class*=-BGC104] { + background-color: #8787D7 +} + +div.highlight .-Color[class*=-C105] { + color: #8787FF +} + +div.highlight .-Color[class*=-BGC105] { + background-color: #8787FF +} + +div.highlight .-Color[class*=-C106] { + color: #87AF00 +} + +div.highlight .-Color[class*=-BGC106] { + background-color: #87AF00 +} + +div.highlight .-Color[class*=-C107] { + color: #87AF5F +} + +div.highlight .-Color[class*=-BGC107] { + background-color: #87AF5F +} + +div.highlight .-Color[class*=-C108] { + color: #87AF87 +} + +div.highlight .-Color[class*=-BGC108] { + background-color: #87AF87 +} + +div.highlight .-Color[class*=-C109] { + color: #87AFAF +} + +div.highlight .-Color[class*=-BGC109] { + background-color: #87AFAF +} + +div.highlight .-Color[class*=-C110] { + color: #87AFD7 +} + +div.highlight .-Color[class*=-BGC110] { + background-color: #87AFD7 +} + +div.highlight .-Color[class*=-C111] { + color: #87AFFF +} + +div.highlight .-Color[class*=-BGC111] { + background-color: #87AFFF +} + +div.highlight .-Color[class*=-C112] { + color: #87D700 +} + +div.highlight .-Color[class*=-BGC112] { + background-color: #87D700 +} + +div.highlight .-Color[class*=-C113] { + color: #87D75F +} + +div.highlight .-Color[class*=-BGC113] { + background-color: #87D75F +} + +div.highlight .-Color[class*=-C114] { + color: #87D787 +} + +div.highlight .-Color[class*=-BGC114] { + background-color: #87D787 +} + +div.highlight .-Color[class*=-C115] { + color: #87D7AF +} + +div.highlight .-Color[class*=-BGC115] { + background-color: #87D7AF +} + +div.highlight .-Color[class*=-C116] { + color: #87D7D7 +} + +div.highlight .-Color[class*=-BGC116] { + background-color: #87D7D7 +} + +div.highlight .-Color[class*=-C117] { + color: #87D7FF +} + +div.highlight .-Color[class*=-BGC117] { + background-color: #87D7FF +} + +div.highlight .-Color[class*=-C118] { + color: #87FF00 +} + +div.highlight .-Color[class*=-BGC118] { + background-color: #87FF00 +} + +div.highlight .-Color[class*=-C119] { + color: #87FF5F +} + +div.highlight .-Color[class*=-BGC119] { + background-color: #87FF5F +} + +div.highlight .-Color[class*=-C120] { + color: #87FF87 +} + +div.highlight .-Color[class*=-BGC120] { + background-color: #87FF87 +} + +div.highlight .-Color[class*=-C121] { + color: #87FFAF +} + +div.highlight .-Color[class*=-BGC121] { + background-color: #87FFAF +} + +div.highlight .-Color[class*=-C122] { + color: #87FFD7 +} + +div.highlight .-Color[class*=-BGC122] { + background-color: #87FFD7 +} + +div.highlight .-Color[class*=-C123] { + color: #87FFFF +} + +div.highlight .-Color[class*=-BGC123] { + background-color: #87FFFF +} + +div.highlight .-Color[class*=-C124] { + color: #AF0000 +} + +div.highlight .-Color[class*=-BGC124] { + background-color: #AF0000 +} + +div.highlight .-Color[class*=-C125] { + color: #AF005F +} + +div.highlight .-Color[class*=-BGC125] { + background-color: #AF005F +} + +div.highlight .-Color[class*=-C126] { + color: #AF0087 +} + +div.highlight .-Color[class*=-BGC126] { + background-color: #AF0087 +} + +div.highlight .-Color[class*=-C127] { + color: #AF00AF +} + +div.highlight .-Color[class*=-BGC127] { + background-color: #AF00AF +} + +div.highlight .-Color[class*=-C128] { + color: #AF00D7 +} + +div.highlight .-Color[class*=-BGC128] { + background-color: #AF00D7 +} + +div.highlight .-Color[class*=-C129] { + color: #AF00FF +} + +div.highlight .-Color[class*=-BGC129] { + background-color: #AF00FF +} + +div.highlight .-Color[class*=-C130] { + color: #AF5F00 +} + +div.highlight .-Color[class*=-BGC130] { + background-color: #AF5F00 +} + +div.highlight .-Color[class*=-C131] { + color: #AF5F5F +} + +div.highlight .-Color[class*=-BGC131] { + background-color: #AF5F5F +} + +div.highlight .-Color[class*=-C132] { + color: #AF5F87 +} + +div.highlight .-Color[class*=-BGC132] { + background-color: #AF5F87 +} + +div.highlight .-Color[class*=-C133] { + color: #AF5FAF +} + +div.highlight .-Color[class*=-BGC133] { + background-color: #AF5FAF +} + +div.highlight .-Color[class*=-C134] { + color: #AF5FD7 +} + +div.highlight .-Color[class*=-BGC134] { + background-color: #AF5FD7 +} + +div.highlight .-Color[class*=-C135] { + color: #AF5FFF +} + +div.highlight .-Color[class*=-BGC135] { + background-color: #AF5FFF +} + +div.highlight .-Color[class*=-C136] { + color: #AF8700 +} + +div.highlight .-Color[class*=-BGC136] { + background-color: #AF8700 +} + +div.highlight .-Color[class*=-C137] { + color: #AF875F +} + +div.highlight .-Color[class*=-BGC137] { + background-color: #AF875F +} + +div.highlight .-Color[class*=-C138] { + color: #AF8787 +} + +div.highlight .-Color[class*=-BGC138] { + background-color: #AF8787 +} + +div.highlight .-Color[class*=-C139] { + color: #AF87AF +} + +div.highlight .-Color[class*=-BGC139] { + background-color: #AF87AF +} + +div.highlight .-Color[class*=-C140] { + color: #AF87D7 +} + +div.highlight .-Color[class*=-BGC140] { + background-color: #AF87D7 +} + +div.highlight .-Color[class*=-C141] { + color: #AF87FF +} + +div.highlight .-Color[class*=-BGC141] { + background-color: #AF87FF +} + +div.highlight .-Color[class*=-C142] { + color: #AFAF00 +} + +div.highlight .-Color[class*=-BGC142] { + background-color: #AFAF00 +} + +div.highlight .-Color[class*=-C143] { + color: #AFAF5F +} + +div.highlight .-Color[class*=-BGC143] { + background-color: #AFAF5F +} + +div.highlight .-Color[class*=-C144] { + color: #AFAF87 +} + +div.highlight .-Color[class*=-BGC144] { + background-color: #AFAF87 +} + +div.highlight .-Color[class*=-C145] { + color: #AFAFAF +} + +div.highlight .-Color[class*=-BGC145] { + background-color: #AFAFAF +} + +div.highlight .-Color[class*=-C146] { + color: #AFAFD7 +} + +div.highlight .-Color[class*=-BGC146] { + background-color: #AFAFD7 +} + +div.highlight .-Color[class*=-C147] { + color: #AFAFFF +} + +div.highlight .-Color[class*=-BGC147] { + background-color: #AFAFFF +} + +div.highlight .-Color[class*=-C148] { + color: #AFD700 +} + +div.highlight .-Color[class*=-BGC148] { + background-color: #AFD700 +} + +div.highlight .-Color[class*=-C149] { + color: #AFD75F +} + +div.highlight .-Color[class*=-BGC149] { + background-color: #AFD75F +} + +div.highlight .-Color[class*=-C150] { + color: #AFD787 +} + +div.highlight .-Color[class*=-BGC150] { + background-color: #AFD787 +} + +div.highlight .-Color[class*=-C151] { + color: #AFD7AF +} + +div.highlight .-Color[class*=-BGC151] { + background-color: #AFD7AF +} + +div.highlight .-Color[class*=-C152] { + color: #AFD7D7 +} + +div.highlight .-Color[class*=-BGC152] { + background-color: #AFD7D7 +} + +div.highlight .-Color[class*=-C153] { + color: #AFD7FF +} + +div.highlight .-Color[class*=-BGC153] { + background-color: #AFD7FF +} + +div.highlight .-Color[class*=-C154] { + color: #AFFF00 +} + +div.highlight .-Color[class*=-BGC154] { + background-color: #AFFF00 +} + +div.highlight .-Color[class*=-C155] { + color: #AFFF5F +} + +div.highlight .-Color[class*=-BGC155] { + background-color: #AFFF5F +} + +div.highlight .-Color[class*=-C156] { + color: #AFFF87 +} + +div.highlight .-Color[class*=-BGC156] { + background-color: #AFFF87 +} + +div.highlight .-Color[class*=-C157] { + color: #AFFFAF +} + +div.highlight .-Color[class*=-BGC157] { + background-color: #AFFFAF +} + +div.highlight .-Color[class*=-C158] { + color: #AFFFD7 +} + +div.highlight .-Color[class*=-BGC158] { + background-color: #AFFFD7 +} + +div.highlight .-Color[class*=-C159] { + color: #AFFFFF +} + +div.highlight .-Color[class*=-BGC159] { + background-color: #AFFFFF +} + +div.highlight .-Color[class*=-C160] { + color: #D70000 +} + +div.highlight .-Color[class*=-BGC160] { + background-color: #D70000 +} + +div.highlight .-Color[class*=-C161] { + color: #D7005F +} + +div.highlight .-Color[class*=-BGC161] { + background-color: #D7005F +} + +div.highlight .-Color[class*=-C162] { + color: #D70087 +} + +div.highlight .-Color[class*=-BGC162] { + background-color: #D70087 +} + +div.highlight .-Color[class*=-C163] { + color: #D700AF +} + +div.highlight .-Color[class*=-BGC163] { + background-color: #D700AF +} + +div.highlight .-Color[class*=-C164] { + color: #D700D7 +} + +div.highlight .-Color[class*=-BGC164] { + background-color: #D700D7 +} + +div.highlight .-Color[class*=-C165] { + color: #D700FF +} + +div.highlight .-Color[class*=-BGC165] { + background-color: #D700FF +} + +div.highlight .-Color[class*=-C166] { + color: #D75F00 +} + +div.highlight .-Color[class*=-BGC166] { + background-color: #D75F00 +} + +div.highlight .-Color[class*=-C167] { + color: #D75F5F +} + +div.highlight .-Color[class*=-BGC167] { + background-color: #D75F5F +} + +div.highlight .-Color[class*=-C168] { + color: #D75F87 +} + +div.highlight .-Color[class*=-BGC168] { + background-color: #D75F87 +} + +div.highlight .-Color[class*=-C169] { + color: #D75FAF +} + +div.highlight .-Color[class*=-BGC169] { + background-color: #D75FAF +} + +div.highlight .-Color[class*=-C170] { + color: #D75FD7 +} + +div.highlight .-Color[class*=-BGC170] { + background-color: #D75FD7 +} + +div.highlight .-Color[class*=-C171] { + color: #D75FFF +} + +div.highlight .-Color[class*=-BGC171] { + background-color: #D75FFF +} + +div.highlight .-Color[class*=-C172] { + color: #D78700 +} + +div.highlight .-Color[class*=-BGC172] { + background-color: #D78700 +} + +div.highlight .-Color[class*=-C173] { + color: #D7875F +} + +div.highlight .-Color[class*=-BGC173] { + background-color: #D7875F +} + +div.highlight .-Color[class*=-C174] { + color: #D78787 +} + +div.highlight .-Color[class*=-BGC174] { + background-color: #D78787 +} + +div.highlight .-Color[class*=-C175] { + color: #D787AF +} + +div.highlight .-Color[class*=-BGC175] { + background-color: #D787AF +} + +div.highlight .-Color[class*=-C176] { + color: #D787D7 +} + +div.highlight .-Color[class*=-BGC176] { + background-color: #D787D7 +} + +div.highlight .-Color[class*=-C177] { + color: #D787FF +} + +div.highlight .-Color[class*=-BGC177] { + background-color: #D787FF +} + +div.highlight .-Color[class*=-C178] { + color: #D7AF00 +} + +div.highlight .-Color[class*=-BGC178] { + background-color: #D7AF00 +} + +div.highlight .-Color[class*=-C179] { + color: #D7AF5F +} + +div.highlight .-Color[class*=-BGC179] { + background-color: #D7AF5F +} + +div.highlight .-Color[class*=-C180] { + color: #D7AF87 +} + +div.highlight .-Color[class*=-BGC180] { + background-color: #D7AF87 +} + +div.highlight .-Color[class*=-C181] { + color: #D7AFAF +} + +div.highlight .-Color[class*=-BGC181] { + background-color: #D7AFAF +} + +div.highlight .-Color[class*=-C182] { + color: #D7AFD7 +} + +div.highlight .-Color[class*=-BGC182] { + background-color: #D7AFD7 +} + +div.highlight .-Color[class*=-C183] { + color: #D7AFFF +} + +div.highlight .-Color[class*=-BGC183] { + background-color: #D7AFFF +} + +div.highlight .-Color[class*=-C184] { + color: #D7D700 +} + +div.highlight .-Color[class*=-BGC184] { + background-color: #D7D700 +} + +div.highlight .-Color[class*=-C185] { + color: #D7D75F +} + +div.highlight .-Color[class*=-BGC185] { + background-color: #D7D75F +} + +div.highlight .-Color[class*=-C186] { + color: #D7D787 +} + +div.highlight .-Color[class*=-BGC186] { + background-color: #D7D787 +} + +div.highlight .-Color[class*=-C187] { + color: #D7D7AF +} + +div.highlight .-Color[class*=-BGC187] { + background-color: #D7D7AF +} + +div.highlight .-Color[class*=-C188] { + color: #D7D7D7 +} + +div.highlight .-Color[class*=-BGC188] { + background-color: #D7D7D7 +} + +div.highlight .-Color[class*=-C189] { + color: #D7D7FF +} + +div.highlight .-Color[class*=-BGC189] { + background-color: #D7D7FF +} + +div.highlight .-Color[class*=-C190] { + color: #D7FF00 +} + +div.highlight .-Color[class*=-BGC190] { + background-color: #D7FF00 +} + +div.highlight .-Color[class*=-C191] { + color: #D7FF5F +} + +div.highlight .-Color[class*=-BGC191] { + background-color: #D7FF5F +} + +div.highlight .-Color[class*=-C192] { + color: #D7FF87 +} + +div.highlight .-Color[class*=-BGC192] { + background-color: #D7FF87 +} + +div.highlight .-Color[class*=-C193] { + color: #D7FFAF +} + +div.highlight .-Color[class*=-BGC193] { + background-color: #D7FFAF +} + +div.highlight .-Color[class*=-C194] { + color: #D7FFD7 +} + +div.highlight .-Color[class*=-BGC194] { + background-color: #D7FFD7 +} + +div.highlight .-Color[class*=-C195] { + color: #D7FFFF +} + +div.highlight .-Color[class*=-BGC195] { + background-color: #D7FFFF +} + +div.highlight .-Color[class*=-C196] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC196] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C197] { + color: #FF005F +} + +div.highlight .-Color[class*=-BGC197] { + background-color: #FF005F +} + +div.highlight .-Color[class*=-C198] { + color: #FF0087 +} + +div.highlight .-Color[class*=-BGC198] { + background-color: #FF0087 +} + +div.highlight .-Color[class*=-C199] { + color: #FF00AF +} + +div.highlight .-Color[class*=-BGC199] { + background-color: #FF00AF +} + +div.highlight .-Color[class*=-C200] { + color: #FF00D7 +} + +div.highlight .-Color[class*=-BGC200] { + background-color: #FF00D7 +} + +div.highlight .-Color[class*=-C201] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC201] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C202] { + color: #FF5F00 +} + +div.highlight .-Color[class*=-BGC202] { + background-color: #FF5F00 +} + +div.highlight .-Color[class*=-C203] { + color: #FF5F5F +} + +div.highlight .-Color[class*=-BGC203] { + background-color: #FF5F5F +} + +div.highlight .-Color[class*=-C204] { + color: #FF5F87 +} + +div.highlight .-Color[class*=-BGC204] { + background-color: #FF5F87 +} + +div.highlight .-Color[class*=-C205] { + color: #FF5FAF +} + +div.highlight .-Color[class*=-BGC205] { + background-color: #FF5FAF +} + +div.highlight .-Color[class*=-C206] { + color: #FF5FD7 +} + +div.highlight .-Color[class*=-BGC206] { + background-color: #FF5FD7 +} + +div.highlight .-Color[class*=-C207] { + color: #FF5FFF +} + +div.highlight .-Color[class*=-BGC207] { + background-color: #FF5FFF +} + +div.highlight .-Color[class*=-C208] { + color: #FF8700 +} + +div.highlight .-Color[class*=-BGC208] { + background-color: #FF8700 +} + +div.highlight .-Color[class*=-C209] { + color: #FF875F +} + +div.highlight .-Color[class*=-BGC209] { + background-color: #FF875F +} + +div.highlight .-Color[class*=-C210] { + color: #FF8787 +} + +div.highlight .-Color[class*=-BGC210] { + background-color: #FF8787 +} + +div.highlight .-Color[class*=-C211] { + color: #FF87AF +} + +div.highlight .-Color[class*=-BGC211] { + background-color: #FF87AF +} + +div.highlight .-Color[class*=-C212] { + color: #FF87D7 +} + +div.highlight .-Color[class*=-BGC212] { + background-color: #FF87D7 +} + +div.highlight .-Color[class*=-C213] { + color: #FF87FF +} + +div.highlight .-Color[class*=-BGC213] { + background-color: #FF87FF +} + +div.highlight .-Color[class*=-C214] { + color: #FFAF00 +} + +div.highlight .-Color[class*=-BGC214] { + background-color: #FFAF00 +} + +div.highlight .-Color[class*=-C215] { + color: #FFAF5F +} + +div.highlight .-Color[class*=-BGC215] { + background-color: #FFAF5F +} + +div.highlight .-Color[class*=-C216] { + color: #FFAF87 +} + +div.highlight .-Color[class*=-BGC216] { + background-color: #FFAF87 +} + +div.highlight .-Color[class*=-C217] { + color: #FFAFAF +} + +div.highlight .-Color[class*=-BGC217] { + background-color: #FFAFAF +} + +div.highlight .-Color[class*=-C218] { + color: #FFAFD7 +} + +div.highlight .-Color[class*=-BGC218] { + background-color: #FFAFD7 +} + +div.highlight .-Color[class*=-C219] { + color: #FFAFFF +} + +div.highlight .-Color[class*=-BGC219] { + background-color: #FFAFFF +} + +div.highlight .-Color[class*=-C220] { + color: #FFD700 +} + +div.highlight .-Color[class*=-BGC220] { + background-color: #FFD700 +} + +div.highlight .-Color[class*=-C221] { + color: #FFD75F +} + +div.highlight .-Color[class*=-BGC221] { + background-color: #FFD75F +} + +div.highlight .-Color[class*=-C222] { + color: #FFD787 +} + +div.highlight .-Color[class*=-BGC222] { + background-color: #FFD787 +} + +div.highlight .-Color[class*=-C223] { + color: #FFD7AF +} + +div.highlight .-Color[class*=-BGC223] { + background-color: #FFD7AF +} + +div.highlight .-Color[class*=-C224] { + color: #FFD7D7 +} + +div.highlight .-Color[class*=-BGC224] { + background-color: #FFD7D7 +} + +div.highlight .-Color[class*=-C225] { + color: #FFD7FF +} + +div.highlight .-Color[class*=-BGC225] { + background-color: #FFD7FF +} + +div.highlight .-Color[class*=-C226] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC226] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C227] { + color: #FFFF5F +} + +div.highlight .-Color[class*=-BGC227] { + background-color: #FFFF5F +} + +div.highlight .-Color[class*=-C228] { + color: #FFFF87 +} + +div.highlight .-Color[class*=-BGC228] { + background-color: #FFFF87 +} + +div.highlight .-Color[class*=-C229] { + color: #FFFFAF +} + +div.highlight .-Color[class*=-BGC229] { + background-color: #FFFFAF +} + +div.highlight .-Color[class*=-C230] { + color: #FFFFD7 +} + +div.highlight .-Color[class*=-BGC230] { + background-color: #FFFFD7 +} + +div.highlight .-Color[class*=-C231] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC231] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C232] { + color: #080808 +} + +div.highlight .-Color[class*=-BGC232] { + background-color: #080808 +} + +div.highlight .-Color[class*=-C233] { + color: #121212 +} + +div.highlight .-Color[class*=-BGC233] { + background-color: #121212 +} + +div.highlight .-Color[class*=-C234] { + color: #1C1C1C +} + +div.highlight .-Color[class*=-BGC234] { + background-color: #1C1C1C +} + +div.highlight .-Color[class*=-C235] { + color: #262626 +} + +div.highlight .-Color[class*=-BGC235] { + background-color: #262626 +} + +div.highlight .-Color[class*=-C236] { + color: #303030 +} + +div.highlight .-Color[class*=-BGC236] { + background-color: #303030 +} + +div.highlight .-Color[class*=-C237] { + color: #3A3A3A +} + +div.highlight .-Color[class*=-BGC237] { + background-color: #3A3A3A +} + +div.highlight .-Color[class*=-C238] { + color: #444444 +} + +div.highlight .-Color[class*=-BGC238] { + background-color: #444444 +} + +div.highlight .-Color[class*=-C239] { + color: #4E4E4E +} + +div.highlight .-Color[class*=-BGC239] { + background-color: #4E4E4E +} + +div.highlight .-Color[class*=-C240] { + color: #585858 +} + +div.highlight .-Color[class*=-BGC240] { + background-color: #585858 +} + +div.highlight .-Color[class*=-C241] { + color: #626262 +} + +div.highlight .-Color[class*=-BGC241] { + background-color: #626262 +} + +div.highlight .-Color[class*=-C242] { + color: #6C6C6C +} + +div.highlight .-Color[class*=-BGC242] { + background-color: #6C6C6C +} + +div.highlight .-Color[class*=-C243] { + color: #767676 +} + +div.highlight .-Color[class*=-BGC243] { + background-color: #767676 +} + +div.highlight .-Color[class*=-C244] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC244] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C245] { + color: #8A8A8A +} + +div.highlight .-Color[class*=-BGC245] { + background-color: #8A8A8A +} + +div.highlight .-Color[class*=-C246] { + color: #949494 +} + +div.highlight .-Color[class*=-BGC246] { + background-color: #949494 +} + +div.highlight .-Color[class*=-C247] { + color: #9E9E9E +} + +div.highlight .-Color[class*=-BGC247] { + background-color: #9E9E9E +} + +div.highlight .-Color[class*=-C248] { + color: #A8A8A8 +} + +div.highlight .-Color[class*=-BGC248] { + background-color: #A8A8A8 +} + +div.highlight .-Color[class*=-C249] { + color: #B2B2B2 +} + +div.highlight .-Color[class*=-BGC249] { + background-color: #B2B2B2 +} + +div.highlight .-Color[class*=-C250] { + color: #BCBCBC +} + +div.highlight .-Color[class*=-BGC250] { + background-color: #BCBCBC +} + +div.highlight .-Color[class*=-C251] { + color: #C6C6C6 +} + +div.highlight .-Color[class*=-BGC251] { + background-color: #C6C6C6 +} + +div.highlight .-Color[class*=-C252] { + color: #D0D0D0 +} + +div.highlight .-Color[class*=-BGC252] { + background-color: #D0D0D0 +} + +div.highlight .-Color[class*=-C253] { + color: #DADADA +} + +div.highlight .-Color[class*=-BGC253] { + background-color: #DADADA +} + +div.highlight .-Color[class*=-C254] { + color: #E4E4E4 +} + +div.highlight .-Color[class*=-BGC254] { + background-color: #E4E4E4 +} + +div.highlight .-Color[class*=-C255] { + color: #EEEEEE +} + +div.highlight .-Color[class*=-BGC255] { + background-color: #EEEEEE +} diff --git a/branch/comms/singlehtml/_static/plus.png b/branch/comms/singlehtml/_static/plus.png new file mode 100644 index 0000000..7107cec Binary files /dev/null and b/branch/comms/singlehtml/_static/plus.png differ diff --git a/branch/comms/singlehtml/_static/pygments.css b/branch/comms/singlehtml/_static/pygments.css new file mode 100644 index 0000000..84ab303 --- /dev/null +++ b/branch/comms/singlehtml/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/branch/comms/singlehtml/_static/searchtools.js b/branch/comms/singlehtml/_static/searchtools.js new file mode 100644 index 0000000..b08d58c --- /dev/null +++ b/branch/comms/singlehtml/_static/searchtools.js @@ -0,0 +1,620 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/branch/comms/singlehtml/_static/sphinx-design.min.css b/branch/comms/singlehtml/_static/sphinx-design.min.css new file mode 100644 index 0000000..860c36d --- /dev/null +++ b/branch/comms/singlehtml/_static/sphinx-design.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative;font-size:var(--sd-fontsize-dropdown)}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary.sd-summary-title{padding:.5em .6em .5em 1em;font-size:var(--sd-fontsize-dropdown-title);font-weight:var(--sd-fontweight-dropdown-title);user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;list-style:none;display:inline-flex;justify-content:space-between}details.sd-dropdown summary.sd-summary-title::-webkit-details-marker{display:none}details.sd-dropdown summary.sd-summary-title:focus{outline:none}details.sd-dropdown summary.sd-summary-title .sd-summary-icon{margin-right:.6em;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary.sd-summary-title .sd-summary-text{flex-grow:1;line-height:1.5;padding-right:.5rem}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker{pointer-events:none;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker svg{opacity:.6}details.sd-dropdown summary.sd-summary-title:hover .sd-summary-state-marker svg{opacity:1;transform:scale(1.1)}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown .sd-summary-chevron-right{transition:.25s}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-right{transform:rotate(90deg)}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-down{transform:rotate(180deg)}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-bg: rgba(0, 113, 188, 0.2);--sd-color-secondary-bg: rgba(108, 117, 125, 0.2);--sd-color-success-bg: rgba(40, 167, 69, 0.2);--sd-color-info-bg: rgba(23, 162, 184, 0.2);--sd-color-warning-bg: rgba(240, 179, 126, 0.2);--sd-color-danger-bg: rgba(220, 53, 69, 0.2);--sd-color-light-bg: rgba(248, 249, 250, 0.2);--sd-color-muted-bg: rgba(108, 117, 125, 0.2);--sd-color-dark-bg: rgba(33, 37, 41, 0.2);--sd-color-black-bg: rgba(0, 0, 0, 0.2);--sd-color-white-bg: rgba(255, 255, 255, 0.2);--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem;--sd-fontsize-dropdown: inherit;--sd-fontsize-dropdown-title: 1rem;--sd-fontweight-dropdown-title: 700} diff --git a/branch/comms/singlehtml/_static/sphinx_highlight.js b/branch/comms/singlehtml/_static/sphinx_highlight.js new file mode 100644 index 0000000..8a96c69 --- /dev/null +++ b/branch/comms/singlehtml/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/branch/comms/singlehtml/_static/sphinx_lesson.css b/branch/comms/singlehtml/_static/sphinx_lesson.css new file mode 100644 index 0000000..14b20c6 --- /dev/null +++ b/branch/comms/singlehtml/_static/sphinx_lesson.css @@ -0,0 +1,51 @@ +/* sphinx_lesson.css */ + +body.wy-body-for-nav img.with-border { + border: 2px solid; +} + +.rst-content .admonition-no-content { + padding-bottom: 0px; +} + +.rst-content .demo > .admonition-title::before { + content: "\01F440"; /* Eyes */ } +.rst-content .type-along > .admonition-title::before { + content: "\02328\0FE0F"; /* Keyboard */ } +.rst-content .exercise > .admonition-title::before { + content: "\0270D\0FE0F"; /* Hand */ } +.rst-content .solution > .admonition-title::before { + content: "\02714\0FE0E"; /* Check mark */ } +.rst-content .homework > .admonition-title::before { + content: "\01F4DD"; /* Memo */ } +.rst-content .discussion > .admonition-title::before { + content: "\01F4AC"; /* Speech balloon */ } +.rst-content .questions > .admonition-title::before { + content: "\02753\0FE0E"; /* Question mark */ } +.rst-content .prerequisites > .admonition-title::before { + content: "\02699"; /* Gear */ } +.rst-content .seealso > .admonition-title::before { + content: "\027A1\0FE0E"; /* Question mark */ } + + +/* instructor-note */ +.rst-content .instructor-note { + background: #e7e7e7; +} +.rst-content .instructor-note > .admonition-title { + background: #6a6a6a; +} +.rst-content .instructor-note > .admonition-title::before { + content: ""; +} + + +/* sphinx_toggle_button, make the font white */ +.rst-content .toggle.admonition button.toggle-button { + color: white; +} + +/* sphinx-togglebutton, remove underflow when toggled to hidden mode */ +.rst-content .admonition.toggle-hidden { + padding-bottom: 0px; +} diff --git a/branch/comms/singlehtml/_static/sphinx_rtd_theme_ext_color_contrast.css b/branch/comms/singlehtml/_static/sphinx_rtd_theme_ext_color_contrast.css new file mode 100644 index 0000000..e68feb8 --- /dev/null +++ b/branch/comms/singlehtml/_static/sphinx_rtd_theme_ext_color_contrast.css @@ -0,0 +1,47 @@ +/* The following are for web accessibility of sphinx_rtd_theme: they + * solve some of the most frequent contrast issues. Remove when this + * solved: + * https://github.com/readthedocs/sphinx_rtd_theme/issues/971 + */ +/* background: #fcfcfc, note boxes #E7F2FA */ +a { color: #2573A7; } /* original #2980B9, #1F5C84; */ +body { color: #242424; } /* original #404040, #383838 */ +.wy-side-nav-search>a, .wy-side-nav-search .wy-dropdown>a { + color: #ffffff; +} /* original #fcfcfc */ +footer { color: #737373; } /* original gray=#808080*/ +footer span.commit code, footer span.commit .rst-content tt, .rst-content footer span.commit tt { + color: #737373; +} /* original gray=#808080*/ +.rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal { + color: #AB2314; +} +/* Sidebar background */ +.wy-side-nav-search { background-color: #277CB4;} + +/* Same, but for pygments */ +.highlight .ch { color: #3E7A89; } /* #! line */ +.highlight .c1 { color: #3E7A89; } /* also comments */ +.highlight .nv { color: #AD3ECC; } /* variable */ +.highlight .gp { color: #B45608; } /* prompt character, $*/ +.highlight .si { color: #3975B1; } /* ${} variable text */ +.highlight .nc { color: #0C78A7; } + +/* Sphinx admonitions */ +/* warning */ +.wy-alert.wy-alert-warning .wy-alert-title, .rst-content .wy-alert-warning.note .wy-alert-title, .rst-content .attention .wy-alert-title, .rst-content .caution .wy-alert-title, .rst-content .wy-alert-warning.danger .wy-alert-title, .rst-content .wy-alert-warning.error .wy-alert-title, .rst-content .wy-alert-warning.hint .wy-alert-title, .rst-content .wy-alert-warning.important .wy-alert-title, .rst-content .wy-alert-warning.tip .wy-alert-title, .rst-content .warning .wy-alert-title, .rst-content .wy-alert-warning.seealso .wy-alert-title, .rst-content .admonition-todo .wy-alert-title, .rst-content .wy-alert-warning.admonition .wy-alert-title, .wy-alert.wy-alert-warning .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-warning .admonition-title, .rst-content .wy-alert-warning.note .admonition-title, .rst-content .attention .admonition-title, .rst-content .caution .admonition-title, .rst-content .wy-alert-warning.danger .admonition-title, .rst-content .wy-alert-warning.error .admonition-title, .rst-content .wy-alert-warning.hint .admonition-title, .rst-content .wy-alert-warning.important .admonition-title, .rst-content .wy-alert-warning.tip .admonition-title, .rst-content .warning .admonition-title, .rst-content .wy-alert-warning.seealso .admonition-title, .rst-content .admonition-todo .admonition-title, .rst-content .wy-alert-warning.admonition .admonition-title { + background: #B15E16; } +/* important */ +.wy-alert.wy-alert-success .wy-alert-title, .rst-content .wy-alert-success.note .wy-alert-title, .rst-content .wy-alert-success.attention .wy-alert-title, .rst-content .wy-alert-success.caution .wy-alert-title, .rst-content .wy-alert-success.danger .wy-alert-title, .rst-content .wy-alert-success.error .wy-alert-title, .rst-content .hint .wy-alert-title, .rst-content .important .wy-alert-title, .rst-content .tip .wy-alert-title, .rst-content .wy-alert-success.warning .wy-alert-title, .rst-content .wy-alert-success.seealso .wy-alert-title, .rst-content .wy-alert-success.admonition-todo .wy-alert-title, .rst-content .wy-alert-success.admonition .wy-alert-title, .wy-alert.wy-alert-success .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-success .admonition-title, .rst-content .wy-alert-success.note .admonition-title, .rst-content .wy-alert-success.attention .admonition-title, .rst-content .wy-alert-success.caution .admonition-title, .rst-content .wy-alert-success.danger .admonition-title, .rst-content .wy-alert-success.error .admonition-title, .rst-content .hint .admonition-title, .rst-content .important .admonition-title, .rst-content .tip .admonition-title, .rst-content .wy-alert-success.warning .admonition-title, .rst-content .wy-alert-success.seealso .admonition-title, .rst-content .wy-alert-success.admonition-todo .admonition-title, .rst-content .wy-alert-success.admonition .admonition-title { + background: #12826C; } +/* seealso, note, etc */ +.wy-alert.wy-alert-info .wy-alert-title, .rst-content .note .wy-alert-title, .rst-content .wy-alert-info.attention .wy-alert-title, .rst-content .wy-alert-info.caution .wy-alert-title, .rst-content .wy-alert-info.danger .wy-alert-title, .rst-content .wy-alert-info.error .wy-alert-title, .rst-content .wy-alert-info.hint .wy-alert-title, .rst-content .wy-alert-info.important .wy-alert-title, .rst-content .wy-alert-info.tip .wy-alert-title, .rst-content .wy-alert-info.warning .wy-alert-title, .rst-content .seealso .wy-alert-title, .rst-content .wy-alert-info.admonition-todo .wy-alert-title, .rst-content .wy-alert-info.admonition .wy-alert-title, .wy-alert.wy-alert-info .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-info .admonition-title, .rst-content .note .admonition-title, .rst-content .wy-alert-info.attention .admonition-title, .rst-content .wy-alert-info.caution .admonition-title, .rst-content .wy-alert-info.danger .admonition-title, .rst-content .wy-alert-info.error .admonition-title, .rst-content .wy-alert-info.hint .admonition-title, .rst-content .wy-alert-info.important .admonition-title, .rst-content .wy-alert-info.tip .admonition-title, .rst-content .wy-alert-info.warning .admonition-title, .rst-content .seealso .admonition-title, .rst-content .wy-alert-info.admonition-todo .admonition-title, .rst-content .wy-alert-info.admonition .admonition-title { + background: #277CB4; } +/* error, danger */ +.rst-content .danger .admonition-title, .rst-content .danger .wy-alert-title, .rst-content .error .admonition-title, .rst-content .error .wy-alert-title, .rst-content .wy-alert-danger.admonition-todo .admonition-title, .rst-content .wy-alert-danger.admonition-todo .wy-alert-title, .rst-content .wy-alert-danger.admonition .admonition-title, .rst-content .wy-alert-danger.admonition .wy-alert-title, .rst-content .wy-alert-danger.attention .admonition-title, .rst-content .wy-alert-danger.attention .wy-alert-title, .rst-content .wy-alert-danger.caution .admonition-title, .rst-content .wy-alert-danger.caution .wy-alert-title, .rst-content .wy-alert-danger.hint .admonition-title, .rst-content .wy-alert-danger.hint .wy-alert-title, .rst-content .wy-alert-danger.important .admonition-title, .rst-content .wy-alert-danger.important .wy-alert-title, .rst-content .wy-alert-danger.note .admonition-title, .rst-content .wy-alert-danger.note .wy-alert-title, .rst-content .wy-alert-danger.seealso .admonition-title, .rst-content .wy-alert-danger.seealso .wy-alert-title, .rst-content .wy-alert-danger.tip .admonition-title, .rst-content .wy-alert-danger.tip .wy-alert-title, .rst-content .wy-alert-danger.warning .admonition-title, .rst-content .wy-alert-danger.warning .wy-alert-title, .rst-content .wy-alert.wy-alert-danger .admonition-title, .wy-alert.wy-alert-danger .rst-content .admonition-title, .wy-alert.wy-alert-danger .wy-alert-title { + background: #e31704; +} + +/* Generic admonition titles */ +.wy-alert-title, .rst-content .admonition-title { + background: #277CB4; } diff --git a/branch/comms/singlehtml/_static/tabs.css b/branch/comms/singlehtml/_static/tabs.css new file mode 100644 index 0000000..957ba60 --- /dev/null +++ b/branch/comms/singlehtml/_static/tabs.css @@ -0,0 +1,89 @@ +.sphinx-tabs { + margin-bottom: 1rem; +} + +[role="tablist"] { + border-bottom: 1px solid #a0b3bf; +} + +.sphinx-tabs-tab { + position: relative; + font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; + color: #1D5C87; + line-height: 24px; + margin: 0; + font-size: 16px; + font-weight: 400; + background-color: rgba(255, 255, 255, 0); + border-radius: 5px 5px 0 0; + border: 0; + padding: 1rem 1.5rem; + margin-bottom: 0; +} + +.sphinx-tabs-tab[aria-selected="true"] { + font-weight: 700; + border: 1px solid #a0b3bf; + border-bottom: 1px solid white; + margin: -1px; + background-color: white; +} + +.sphinx-tabs-tab:focus { + z-index: 1; + outline-offset: 1px; +} + +.sphinx-tabs-panel { + position: relative; + padding: 1rem; + border: 1px solid #a0b3bf; + margin: 0px -1px -1px -1px; + border-radius: 0 0 5px 5px; + border-top: 0; + background: white; +} + +.sphinx-tabs-panel.code-tab { + padding: 0.4rem; +} + +.sphinx-tab img { + margin-bottom: 24 px; +} + +/* Dark theme preference styling */ + +@media (prefers-color-scheme: dark) { + body[data-theme="auto"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); + } + + body[data-theme="auto"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); + } + + body[data-theme="auto"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 1px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); + } +} + +/* Explicit dark theme styling */ + +body[data-theme="dark"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); +} + +body[data-theme="dark"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); +} + +body[data-theme="dark"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 2px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); +} diff --git a/branch/comms/singlehtml/_static/tabs.js b/branch/comms/singlehtml/_static/tabs.js new file mode 100644 index 0000000..48dc303 --- /dev/null +++ b/branch/comms/singlehtml/_static/tabs.js @@ -0,0 +1,145 @@ +try { + var session = window.sessionStorage || {}; +} catch (e) { + var session = {}; +} + +window.addEventListener("DOMContentLoaded", () => { + const allTabs = document.querySelectorAll('.sphinx-tabs-tab'); + const tabLists = document.querySelectorAll('[role="tablist"]'); + + allTabs.forEach(tab => { + tab.addEventListener("click", changeTabs); + }); + + tabLists.forEach(tabList => { + tabList.addEventListener("keydown", keyTabs); + }); + + // Restore group tab selection from session + const lastSelected = session.getItem('sphinx-tabs-last-selected'); + if (lastSelected != null) selectNamedTabs(lastSelected); +}); + +/** + * Key focus left and right between sibling elements using arrows + * @param {Node} e the element in focus when key was pressed + */ +function keyTabs(e) { + const tab = e.target; + let nextTab = null; + if (e.keyCode === 39 || e.keyCode === 37) { + tab.setAttribute("tabindex", -1); + // Move right + if (e.keyCode === 39) { + nextTab = tab.nextElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.firstElementChild; + } + // Move left + } else if (e.keyCode === 37) { + nextTab = tab.previousElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.lastElementChild; + } + } + } + + if (nextTab !== null) { + nextTab.setAttribute("tabindex", 0); + nextTab.focus(); + } +} + +/** + * Select or deselect clicked tab. If a group tab + * is selected, also select tab in other tabLists. + * @param {Node} e the element that was clicked + */ +function changeTabs(e) { + // Use this instead of the element that was clicked, in case it's a child + const notSelected = this.getAttribute("aria-selected") === "false"; + const positionBefore = this.parentNode.getBoundingClientRect().top; + const notClosable = !this.parentNode.classList.contains("closeable"); + + deselectTabList(this); + + if (notSelected || notClosable) { + selectTab(this); + const name = this.getAttribute("name"); + selectNamedTabs(name, this.id); + + if (this.classList.contains("group-tab")) { + // Persist during session + session.setItem('sphinx-tabs-last-selected', name); + } + } + + const positionAfter = this.parentNode.getBoundingClientRect().top; + const positionDelta = positionAfter - positionBefore; + // Scroll to offset content resizing + window.scrollTo(0, window.scrollY + positionDelta); +} + +/** + * Select tab and show associated panel. + * @param {Node} tab tab to select + */ +function selectTab(tab) { + tab.setAttribute("aria-selected", true); + + // Show the associated panel + document + .getElementById(tab.getAttribute("aria-controls")) + .removeAttribute("hidden"); +} + +/** + * Hide the panels associated with all tabs within the + * tablist containing this tab. + * @param {Node} tab a tab within the tablist to deselect + */ +function deselectTabList(tab) { + const parent = tab.parentNode; + const grandparent = parent.parentNode; + + Array.from(parent.children) + .forEach(t => t.setAttribute("aria-selected", false)); + + Array.from(grandparent.children) + .slice(1) // Skip tablist + .forEach(panel => panel.setAttribute("hidden", true)); +} + +/** + * Select grouped tabs with the same name, but no the tab + * with the given id. + * @param {Node} name name of grouped tab to be selected + * @param {Node} clickedId id of clicked tab + */ +function selectNamedTabs(name, clickedId=null) { + const groupedTabs = document.querySelectorAll(`.sphinx-tabs-tab[name="${name}"]`); + const tabLists = Array.from(groupedTabs).map(tab => tab.parentNode); + + tabLists + .forEach(tabList => { + // Don't want to change the tabList containing the clicked tab + const clickedTab = tabList.querySelector(`[id="${clickedId}"]`); + if (clickedTab === null ) { + // Select first tab with matching name + const tab = tabList.querySelector(`.sphinx-tabs-tab[name="${name}"]`); + deselectTabList(tab); + selectTab(tab); + } + }) +} + +if (typeof exports === 'undefined') { + exports = {}; +} + +exports.keyTabs = keyTabs; +exports.changeTabs = changeTabs; +exports.selectTab = selectTab; +exports.deselectTabList = deselectTabList; +exports.selectNamedTabs = selectNamedTabs; diff --git a/branch/comms/singlehtml/_static/term_role_formatting.css b/branch/comms/singlehtml/_static/term_role_formatting.css new file mode 100644 index 0000000..0b66095 --- /dev/null +++ b/branch/comms/singlehtml/_static/term_role_formatting.css @@ -0,0 +1,4 @@ +/* Make terms bold */ +a.reference span.std-term { + font-weight: bold; +} diff --git a/branch/comms/singlehtml/_static/togglebutton.css b/branch/comms/singlehtml/_static/togglebutton.css new file mode 100644 index 0000000..54a6787 --- /dev/null +++ b/branch/comms/singlehtml/_static/togglebutton.css @@ -0,0 +1,160 @@ +/** + * Admonition-based toggles + */ + +/* Visibility of the target */ +.admonition.toggle .admonition-title ~ * { + transition: opacity .3s, height .3s; +} + +/* Toggle buttons inside admonitions so we see the title */ +.admonition.toggle { + position: relative; +} + +/* Titles should cut off earlier to avoid overlapping w/ button */ +.admonition.toggle .admonition-title { + padding-right: 25%; + cursor: pointer; +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:hover { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 1%); +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:active { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 3%); +} + +/* Remove extra whitespace below the admonition title when hidden */ +.admonition.toggle-hidden { + padding-bottom: 0; +} + +.admonition.toggle-hidden .admonition-title { + margin-bottom: 0; +} + +/* hides all the content of a page until de-toggled */ +.admonition.toggle-hidden .admonition-title ~ * { + height: 0; + margin: 0; + opacity: 0; + visibility: hidden; +} + +/* General button style and position*/ +button.toggle-button { + /** + * Background and shape. By default there's no background + * but users can style as they wish + */ + background: none; + border: none; + outline: none; + + /* Positioning just inside the admonition title */ + position: absolute; + right: 0.5em; + padding: 0px; + border: none; + outline: none; +} + +/* Display the toggle hint on wide screens */ +@media (min-width: 768px) { + button.toggle-button.toggle-button-hidden:before { + content: attr(data-toggle-hint); /* This will be filled in by JS */ + font-size: .8em; + align-self: center; + } +} + +/* Icon behavior */ +.tb-icon { + transition: transform .2s ease-out; + height: 1.5em; + width: 1.5em; + stroke: currentColor; /* So that we inherit the color of other text */ +} + +/* The icon should point right when closed, down when open. */ +/* Open */ +.admonition.toggle button .tb-icon { + transform: rotate(90deg); +} + +/* Closed */ +.admonition.toggle button.toggle-button-hidden .tb-icon { + transform: rotate(0deg); +} + +/* With details toggles, we don't rotate the icon so it points right */ +details.toggle-details .tb-icon { + height: 1.4em; + width: 1.4em; + margin-top: 0.1em; /* To center the button vertically */ +} + + +/** + * Details-based toggles. + * In this case, we wrap elements with `.toggle` in a details block. + */ + +/* Details blocks */ +details.toggle-details { + margin: 1em 0; +} + + +details.toggle-details summary { + display: flex; + align-items: center; + cursor: pointer; + list-style: none; + border-radius: .2em; + border-left: 3px solid #1976d2; + background-color: rgb(204 204 204 / 10%); + padding: 0.2em 0.7em 0.3em 0.5em; /* Less padding on left because the SVG has left margin */ + font-size: 0.9em; +} + +details.toggle-details summary:hover { + background-color: rgb(204 204 204 / 20%); +} + +details.toggle-details summary:active { + background: rgb(204 204 204 / 28%); +} + +.toggle-details__summary-text { + margin-left: 0.2em; +} + +details.toggle-details[open] summary { + margin-bottom: .5em; +} + +details.toggle-details[open] summary .tb-icon { + transform: rotate(90deg); +} + +details.toggle-details[open] summary ~ * { + animation: toggle-fade-in .3s ease-out; +} + +@keyframes toggle-fade-in { + from {opacity: 0%;} + to {opacity: 100%;} +} + +/* Print rules - we hide all toggle button elements at print */ +@media print { + /* Always hide the summary so the button doesn't show up */ + details.toggle-details summary { + display: none; + } +} \ No newline at end of file diff --git a/branch/comms/singlehtml/_static/togglebutton.js b/branch/comms/singlehtml/_static/togglebutton.js new file mode 100644 index 0000000..215a7ee --- /dev/null +++ b/branch/comms/singlehtml/_static/togglebutton.js @@ -0,0 +1,187 @@ +/** + * Add Toggle Buttons to elements + */ + +let toggleChevron = ` + + + +`; + +var initToggleItems = () => { + var itemsToToggle = document.querySelectorAll(togglebuttonSelector); + console.log(`[togglebutton]: Adding toggle buttons to ${itemsToToggle.length} items`) + // Add the button to each admonition and hook up a callback to toggle visibility + itemsToToggle.forEach((item, index) => { + if (item.classList.contains("admonition")) { + // If it's an admonition block, then we'll add a button inside + // Generate unique IDs for this item + var toggleID = `toggle-${index}`; + var buttonID = `button-${toggleID}`; + + item.setAttribute('id', toggleID); + if (!item.classList.contains("toggle")){ + item.classList.add("toggle"); + } + // This is the button that will be added to each item to trigger the toggle + var collapseButton = ` + `; + + title = item.querySelector(".admonition-title") + title.insertAdjacentHTML("beforeend", collapseButton); + thisButton = document.getElementById(buttonID); + + // Add click handlers for the button + admonition title (if admonition) + admonitionTitle = document.querySelector(`#${toggleID} > .admonition-title`) + if (admonitionTitle) { + // If an admonition, then make the whole title block clickable + admonitionTitle.addEventListener('click', toggleClickHandler); + admonitionTitle.dataset.target = toggleID + admonitionTitle.dataset.button = buttonID + } else { + // If not an admonition then we'll listen for the button click + thisButton.addEventListener('click', toggleClickHandler); + } + + // Now hide the item for this toggle button unless explicitly noted to show + if (!item.classList.contains("toggle-shown")) { + toggleHidden(thisButton); + } + } else { + // If not an admonition, wrap the block in a
block + // Define the structure of the details block and insert it as a sibling + var detailsBlock = ` +
+ + ${toggleChevron} + ${toggleHintShow} + +
`; + item.insertAdjacentHTML("beforebegin", detailsBlock); + + // Now move the toggle-able content inside of the details block + details = item.previousElementSibling + details.appendChild(item) + item.classList.add("toggle-details__container") + + // Set up a click trigger to change the text as needed + details.addEventListener('click', (click) => { + let parent = click.target.parentElement; + if (parent.tagName.toLowerCase() == "details") { + summary = parent.querySelector("summary"); + details = parent; + } else { + summary = parent; + details = parent.parentElement; + } + // Update the inner text for the proper hint + if (details.open) { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintShow; + } else { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintHide; + } + + }); + + // If we have a toggle-shown class, open details block should be open + if (item.classList.contains("toggle-shown")) { + details.click(); + } + } + }) +}; + +// This should simply add / remove the collapsed class and change the button text +var toggleHidden = (button) => { + target = button.dataset['target'] + var itemToToggle = document.getElementById(target); + if (itemToToggle.classList.contains("toggle-hidden")) { + itemToToggle.classList.remove("toggle-hidden"); + button.classList.remove("toggle-button-hidden"); + } else { + itemToToggle.classList.add("toggle-hidden"); + button.classList.add("toggle-button-hidden"); + } +} + +var toggleClickHandler = (click) => { + // Be cause the admonition title is clickable and extends to the whole admonition + // We only look for a click event on this title to trigger the toggle. + + if (click.target.classList.contains("admonition-title")) { + button = click.target.querySelector(".toggle-button"); + } else if (click.target.classList.contains("tb-icon")) { + // We've clicked the icon and need to search up one parent for the button + button = click.target.parentElement; + } else if (click.target.tagName == "polyline") { + // We've clicked the SVG elements inside the button, need to up 2 layers + button = click.target.parentElement.parentElement; + } else if (click.target.classList.contains("toggle-button")) { + // We've clicked the button itself and so don't need to do anything + button = click.target; + } else { + console.log(`[togglebutton]: Couldn't find button for ${click.target}`) + } + target = document.getElementById(button.dataset['button']); + toggleHidden(target); +} + +// If we want to blanket-add toggle classes to certain cells +var addToggleToSelector = () => { + const selector = ""; + if (selector.length > 0) { + document.querySelectorAll(selector).forEach((item) => { + item.classList.add("toggle"); + }) + } +} + +// Helper function to run when the DOM is finished +const sphinxToggleRunWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} +sphinxToggleRunWhenDOMLoaded(addToggleToSelector) +sphinxToggleRunWhenDOMLoaded(initToggleItems) + +/** Toggle details blocks to be open when printing */ +if (toggleOpenOnPrint == "true") { + window.addEventListener("beforeprint", () => { + // Open the details + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.dataset["togglestatus"] = el.open; + el.open = true; + }); + + // Open the admonitions + document.querySelectorAll(".admonition.toggle.toggle-hidden").forEach((el) => { + console.log(el); + el.querySelector("button.toggle-button").click(); + el.dataset["toggle_after_print"] = "true"; + }); + }); + window.addEventListener("afterprint", () => { + // Re-close the details that were closed + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.open = el.dataset["togglestatus"] == "true"; + delete el.dataset["togglestatus"]; + }); + + // Re-close the admonition toggle buttons + document.querySelectorAll(".admonition.toggle").forEach((el) => { + if (el.dataset["toggle_after_print"] == "true") { + el.querySelector("button.toggle-button").click(); + delete el.dataset["toggle_after_print"]; + } + }); + }); +} diff --git a/branch/comms/singlehtml/index.html b/branch/comms/singlehtml/index.html new file mode 100644 index 0000000..020d914 --- /dev/null +++ b/branch/comms/singlehtml/index.html @@ -0,0 +1,6234 @@ + + + + + + + Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Train the trainer workshop

+
+

August/September 2024 CodeRefinery train the trainer workshop

+

Do you teach the use of computers and computational tools? Are you curious about scaling your training and learn about tested and proven practices from CodeRefinery workshops and other trainers? Join us for the CodeRefinery train the trainer workshop: four self-contained sessions on tools and techniques for computational training offer a great chance to enhance your teaching skills and learn about new tools and practices. What you will learn is also used a lot outside CodeRefinery, whenever good beginner friendly training is needed.

+

Learning objectives:

+
    +
  • Learn about tools and techniques and practice to create engaging online teaching experiences (screenshare, audio, etc.).

  • +
  • Become mentally ready to be an instructor in a collaborative interactive online workshop (not only large workshops but in general).

  • +
  • Learn how to design and develop lesson material collaboratively.

  • +
+

Target audience:

+
    +
  • Everyone teaching online workshops about computational topics or interested in teaching.

  • +
  • Previous and future instructors and helpers of CodeRefinery workshops.

  • +
+

Prerequisites: +An interest in teaching.

+

Workshop structure: +We aim for a mix of modular presentations and work in small groups. The latter will be done in breakoutrooms - +be prepared to switch on your camera and have a fruitful exchange with fellow participants!

+

Organizers and instructors:

+

The workshop is organized by partner organizations of the CodeRefinery project.

+

Facilitators and instructors:

+
    +
  • Radovan Bast

  • +
  • Richard Darst

  • +
  • Bjørn Lindi

  • +
  • Dhanya Pushpadas

  • +
  • Jarno Rantaharju

  • +
  • Stephan Smuts

  • +
  • Stepas Toliautas

  • +
  • Samantha Wittke

  • +
+

Content and timing:

+

The workshop consists of four sessions every Tuesday between August +13th and September 3rd 2024, + to +:

+
    +
  • Session 1: About lesson design, deployment and iterative improvement (Aug 13)

  • +
  • Session 2: Tools and techniques adopted in CodeRefinery workshops (Aug 20)

  • +
  • Session 3: About teaching & cool things we all would like to share (Aug 27)

  • +
  • Session 4: Workshop streaming practices and post-workshop tasks (Sep 3)

  • +
+

You can join all sessions, or the just the ones that interest you. More details on each session will be shared later.

+

The workshop is free of charge for everyone, please register below to get the Zoom link and other useful information for the workshop.

+

The workshop is over and registration is closed now.

+

If you have any questions, please write to support@coderefinery.org.

+
+
+
+

Lesson design and development

+
+

Objectives

+
    +
  • We share our design processes for teaching material and presentations.

  • +
  • Learn how to design lessons “backwards”, starting from learning objectives +and learner personas.

  • +
  • Learn good practices for improving existing material based on feedback.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 20 min

  • +
  • Exercises: 35 min

  • +
+
+
+

Exercise: How do you design your teaching material?

+
+

We collect notes using a shared document (5 min)

+
    +
  • When you start preparing a new lesson or training material, where do you start?

  • +
  • What tricks help you with “writer’s block” or the empty page problem?

  • +
  • Maybe you haven’t designed training material yet. But how do you start when creating a new presentation?

  • +
  • If your design process has changed over time, please describe what you used to do and what you do now instead.

  • +
  • What do you know now about preparing lessons/training/presentations that you wish you knew earlier?

  • +
+
+
+
+

Creating new teaching material

+
+

Typical problems

+
    +
  • Someone creates a lesson, but they think about what is interesting to them, +not what is important for the learners.

  • +
  • “I want to show a number of things which I think are cool about +tool X - how do I press these into 90 minutes?”

  • +
  • Write down material you want to cover and then sprinkle in some exercises.

  • +
  • Thinking about how I work, not how the learners work.

  • +
  • Trying to bring learners to their level/setup, not trying to meet the learners +where they are.

  • +
  • Not really knowing the learning objectives or the learner personas.

  • +
+
+
+

Better approach

+

Good questions to ask and discuss with a group of colleagues from diverse backgrounds:

+
    +
  • What is the expected educational level of my audience?

  • +
  • Have they been already exposed to the technologies I am planning to teach?

  • +
  • What tools do they already use?

  • +
  • What are the main issues they are currently experiencing?

  • +
  • What do they need to remember/understand/apply/analyze/evaluate/create +(Bloom’s taxonomy)?

  • +
  • Define learner personas.

  • +
  • It may be an advantage to share an imperfect lesson with others early to +collect feedback and suggestions before the lesson “solidifies” too much. +Draft it and collect feedback. The result will probably be better than +working in isolation towards a “perfect” lesson.

  • +
+
+
+

The process of designing a lesson “backwards”

+

As described in “A lesson design process” in the book Teaching Tech +Together:

+
    +
  1. Understand your learners.

  2. +
  3. Brainstorm rough ideas.

  4. +
  5. Create an summative assessment to know your overall goal.

    +
    +

    [Think of the things your learners will be able to do at the end of the lesson]

    +
    +
  6. +
  7. Create formative assessments to go from the starting point to this.

    +
    +

    [Think of some engaging and active exercises]

    +
    +
  8. +
  9. Order the formative assessments (exercises) into a reasonable order.

  10. +
  11. Write just enough material to get from one assessment (exercise) to +another.

  12. +
  13. Describe the course so the learners know if it is relevant to them.

  14. +
+
+
+
+

Improving existing lessons

+
+

All CodeRefinery lessons are on GitHub

+ +
+

Collect feedback during the workshop:

+
    +
  • Collect feedback from learners and instructors (Example from a past +workshop).

  • +
  • Convert feedback about lessons and suggestions for improvements into issues +so that these don’t get lost and stay close to the lesson material.

  • +
+

Collect feedback before you start a big rewrite:

+
    +
  • First open an issue and describe your idea and collect feedback before you +start with an extensive rewrite.

  • +
  • For things still under construction, open a draft pull/merge request to collect +feedback and to signal to others what you are working on.

  • +
+

Small picture changes vs. big picture changes:

+
    +
  • Lesson changes should be accompanied with instructor guide changes (it’s like +a documentation for the lesson material).

  • +
  • Instructor guide is essential for new instructors.

  • +
  • Before making larger changes, talk with somebody and discuss these changes.

  • +
+
+
+

Use case: our lessons

+

As an example to demonstrate the process of designing and improving lessons, we +will have a look at one of our own lessons: Introduction to version control +with Git.

+
    +
  • Initial 2014-2016 version

    + +
  • +
  • Some time in 2014-2015 attended Carpentries instructor training.

  • +
  • 2016: CodeRefinery started.

  • +
  • 2017: Started a new repository based on the Carpentries lesson template (at the time using Jekyll).

    +
      +
    • Exercises become part of the lesson.

    • +
    • We start in the command line and only later move to GitHub.

    • +
    +
  • +
  • 2019: A lot more thought about learning objectives and personas.

    +
      +
    • Also license change to CC-BY.

    • +
    +
  • +
  • 2022: Convert lesson from Jekyll to Sphinx.

    +
      +
    • Using the tools that we teach/advocate.

    • +
    • We can have tabs and better code highlighting/emphasis.

    • +
    • Easier local preview (Python environment instead of Ruby environment which we were not used to in our daily work).

    • +
    +
  • +
  • 2024: Big redesign. We move the lesson closer to where learners are.

    +
      +
    • Start from GitHub instead of on the command line.

    • +
    • Start from an existing repository instead of with an empty one.

    • +
    • Offer several tracks to participate in the lesson (GitHub, VS Code, and command line) and learners can choose which one they want to follow.

    • +
    • Blog post: We have completely changed our Git lessons. Hopefully to the better.

    • +
    +
  • +
  • Next steps?

    +
      +
    • Making the lesson citable following +our blog post.

    • +
    • Improvements based on what we learn from this workshop.

    • +
    +
  • +
+

The overarching trend was to make the lesson simpler and more accessible - to +meet the learners where they are instead of pulling them to the tool choices of +the instructors. Looking back, we learned a lot and the learning process is +not over yet.

+
+
+

Exercise: Discussion about learning objectives and exercise design

+
+

We work in groups but use the shared document as result (20 min)

+
    +
  1. As a group pick a lesson topic. It can be one of the topics listed here but +you can also choose something else that your group is interested in, or a topic +that you have taught before or would like to teach. Some suggestions:

    +
      +
    • Git: Creating a repository and porting your project to Git and GitHub

    • +
    • Git: Basic commands

    • +
    • Git: Branching and merging

    • +
    • Git: Recovering from typical mistakes

    • +
    • Code documentation

    • +
    • Jupyter Notebooks

    • +
    • Collaboration using Git and GitHub/GitLab

    • +
    • Using GitHub without the command line

    • +
    • Project organization

    • +
    • Automated testing

    • +
    • Data transfer

    • +
    • Data management and versioning

    • +
    • Code quality and good practices

    • +
    • Modular code development

    • +
    • How to release and publish your code

    • +
    • How to document and track code dependencies

    • +
    • Recording environments in containers

    • +
    • Profiling memory and CPU usage

    • +
    • Strategies for parallelization

    • +
    • Conda environments

    • +
    • Data processing using workflow managers

    • +
    • Regular expressions

    • +
    • Making papers in LaTeX

    • +
    • Making figures in your favorite programming language

    • +
    • Linux shell basics

    • +
    • Something non-technical, such as painting a room

    • +
    • Introduction to high-performance computing

    • +
    • A lesson you always wanted to teach

    • +
    • +
    +
  2. +
  3. Try to define 2-3 learning objectives for the lesson and write them down. +You can think of these as “three simple enough messages that someone will +remember the next day” - they need to be pretty simple.

  4. +
  5. Can you come up with one or two engaging exercises that could be used to +demonstrate one of those objectives? +They should be simple enough people can actually do them. Creating simple exercises is not easy. +Some standard exercise types:

    +
      +
    • Multiple choice (easy to get feedback via a classroom tool - try to design each wrong answer so that it identifies a specific misconception).

    • +
    • Code yourself (traditional programming)

    • +
    • Code yourself + multiple choice to see what the answer is (allows you to get feedback)

    • +
    • Inverted coding (given code, have to debug)

    • +
    • Parsons problems (working solution but lines in random order, learner must only put in proper order)

    • +
    • Fill in the blank

    • +
    • Discussions, self directed learning exercises

    • +
    +
  6. +
+
+
+
+

Great resources

+ +
+
+
+

Lessons with version control

+
+

Objectives

+
    +
  • Understand why version control is useful even for teaching material

  • +
  • Understand how version control managed lessons can be modified.

  • +
  • Understand how the CodeRefinery lesson template is used to create new lessons

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 25 min

  • +
  • Exercises or demos: 20 min

  • +
+
+
+

Why version control?

+
    +
  • If you are in CodeRefinery TTT, you probably know what version +control is and why it is important.

  • +
  • The benefits of version control also extend to lessons:

    +
      +
    • Change history

    • +
    • Others can submit contributions

    • +
    • Others can make derived versions and sync up later

    • +
    • Same workflow as everything else

    • +
    • Write it like documentation: probably more reading after than +watching it as a presentation.

    • +
    +
  • +
  • Disadvantages

    +
      +
    • “What you see is what you get” editing is hard

    • +
    • Requires knowing version control

    • +
    +
  • +
+
+

Accepting the smallest contribution

+

Question: if someone wants to make a tiny fix to your material, can they?

+
+
+
+

Tour of lesson templates options

+

There are different ways to make lessons with git. Some dedicated to +teaching:

+ +

Our philosophy is that anything works: it doesn’t have to be just +designed for lessons

+
    +
  • Jupyter Book

    +
      +
    • Example: https://jupyterbook.org/

    • +
    • Note: is based on sphinx, many extensions here are used in CR lessons

    • +
    +
  • +
  • Various ways to make slides out of Markdown

  • +
  • Cicero: GitHub-hosted Markdown to slides easily

    + +
  • +
  • Whatever your existing documentation is.

  • +
+

We like the CodeRefinery format, but think that you should use +whatever fits your needs the most.

+
+
+

Sphinx

+
    +
  • We build all our lesson material with Sphinx

  • +
  • Generate HTML/PDF/LaTeX from RST and Markdown.

  • +
  • Many Python projects use Sphinx for documentation but Sphinx is not limited to Python.

  • +
  • Read the docs hosts public Sphinx documentation for free!

  • +
  • Also hostable anywhere else, like Github pages, like our lesson material

  • +
  • For code a selling point for Sphinx is that also API documentation +is possible.

  • +
+

Sphinx is a doc generator, not HTML generator. It can:

+
    +
  • Markdown, Jupyter, and ReST (and more…) inputs. Executable inputs.

    +
      +
    • jupyter-book is Sphinx, so anything it can do we can do. This was one of the +inspirations for using Sphinx

    • +
    +
  • +
  • Good support for inline code. Much more than static code display, if +you want to look at extensions.

  • +
  • Generate different output formats (html, single-page html, pdf, epub, etc.)

  • +
  • Strong cross-referencing within and between projects

  • +
+
+
+

CodeRefinery lesson template

+

It is “just a normal Sphinx project” - with extensions:

+
    +
  • Sphinx lesson extension

    +
      +
    • adds is various directives (boxes) tuned to lesson purposes

    • +
    • provides a sample organization and template repo you can use so that lessons look consistent

    • +
    +
  • +
  • Sphinx gives us other nice features for free

    +
      +
    • Tabs: they are very important for us and allow us to customize in-place instead of copying everything and fragmenting lessons

    • +
    • Emphasize lines: they make it easier to spot what has changed in longer code snippets

    • +
    • Various input formats

      +
        +
      • Markdown (via the MyST-parser), ReStructured text, Jupyter +Notebooks.

      • +
      +
    • +
    • Many other features designed for presenting and interacting with code

    • +
    +
  • +
  • It’s fine if you use some other static site generator or git-based lesson method.

  • +
+
+

Instructors go through the building and contributing process

+

Depending on the course, instructors will demo what is roughly +exercise 4 below. Or a course might go straight to exercises.

+
    +
  • Instructors decide what change they would want to make

  • +
  • Instructors clone the repository

  • +
  • Instructors make the change

  • +
  • Instructors set up the build environment

  • +
  • Instructors build and preview

  • +
  • Instructors command and send upstream

  • +
+
+
+
+

Exercises

+

Some exercises have prerequisites (Git or Github accounts). Most +instances of this course will have you do 1 and 2 below.

+
+

Lesson-VCS-1: Present and discuss your own lesson formats

+

We don’t want to push everyone towards one format, but as long as you +use Git, it’s easy to share and reuse.

+
    +
  • Discuss what formats you do use

  • +
  • Within your team, show examples of the lessons formats you use +now. Discuss what is good and to-be-improved about them.

  • +
  • Look at how they source is managed and how easy it might be to edit.

  • +
+
+
+

Lesson-VCS-2: Tour a CodeRefinery or Carpentries lesson on Github

+
    +
  • Look at either a CodeRefinery or Carpentries lesson

    + +
  • +
  • Can you find

    +
      +
    • Where is the content of the lessons?

    • +
    • What recent change propsals (pull requests) have been made?

    • +
    • What are the open issues?

    • +
    • How you would contribute something?

    • +
    • How would you use this yourself?

    • +
    +
  • +
+
+
+

Lesson-VCS-3: Modify a CodeRefinery example lesson on Github

+

In this, you will make a change to a lesson on Github, using only the +Github interface. (Github account required, and we assume some +knowledge of Github. Ask for help in your team if it is new to you!)

+
    +
  • Navigate to the example lesson we have set up: +repo, web

  • +
  • Go to some page and follow the link to go to the respective page on +Github. (Alternatively, you can find the page from the Github repo directly).

  • +
  • Follow the Github flow to make a change, and open a Pull Request +with the change proposal:

    +
      +
    • Click on the pencil icon

    • +
    • Make a change

    • +
    • Follow the flow to make a commit and change. You’ll fork the +repository to make your own copy, add a message, and open a pull +request.

    • +
    +
  • +
+

We will look at these together and accept some changes.

+
+
+

Lesson-VCS-4: Clone and build a CodeRefinery lesson locally

+

In this exercise, you will use Git to clone one a CodeRefinery lesson +and try to preview it locally. It assumes installation and knowledge +of Git.

+
    +
  • Use this sample repository: +git-intro (or whatever +else you would like)

  • +
  • Clone the repository to your own computer

  • +
  • Create a virtual environment using the requirements.txt +contained within the repository.

  • +
  • Build the lesson.

    +
      +
    • Most people will probably run: sphinx-build content/ _build/

    • +
    • If you have make installed you can make html

    • +
    • Look in the _build directory for the built HTML files.

    • +
    +
  • +
+

Overall, this is pretty easy and straightforward, if you have a Python +environment set up. The CodeRefinery documentation +lesson teaches +this for every operating system.

+

This same tool can be used to build documentation for other software +projects and is pretty standard.

+
+
+

Lesson-VCS-5: (advanced) Create your own lesson using the CodeRefinery format

+

In this lesson, you’ll copy the CodeRefinery template and do basic +modifications for your own lesson.

+
    +
  • Clone the lesson template: +https://github.com/coderefinery/sphinx-lesson-template

  • +
  • Attempt to build it as it is (see the previous exercise)

  • +
  • How can you do tabs?

  • +
  • How can you highlight lines in code boxes?

  • +
  • How can you change color, logo and fonts?

  • +
  • What directives are available?

  • +
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Version control takes teaching materials to the next level: +shareable and easy to contribute

  • +
  • There are different formats that use version control, but we like +Sphinx with a sphinx-lesson extension.

  • +
+
+
+
+
+

How we collect feedback and measure impact

+
+

Objectives

+
    +
  • Discuss how one can collect feedback from learners (“what can we improve?”).

  • +
  • Discuss how we convert feedback into actionable items.

  • +
  • Discuss how we measure the impact of teaching (“did we achieve our goals?”).

  • +
  • Discuss the “why”.

  • +
  • Get to know the reasons and sources of inspiration behind major lesson and workshop updates.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 20 min

  • +
  • Exercises: 10 min

  • +
+
+
+

Asking questions before the workshop

+ +
+
+

Collecting feedback as we teach

+
    +
  • Each day we ask for feedback in the collaborative notes.

    +
      +
    • One good thing about today.

    • +
    • One thing to improve for next time.

    • +
    • Any other comments?

    • +
    +
  • +
  • During the workshop we sometimes check in and ask about the pace, example:

    +
    How is the speed so far? (add an "o")
    +- Too fast:   oooooo
    +- Too slow:   ooo
    +- Just right: ooooooooooooooooooo
    +
    +
    +
  • +
  • We publish all questions, answers, and feedback. Example: https://coderefinery.github.io/2024-03-12-workshop/questions/

  • +
  • How we follow up:

    +
      +
    • Some problems we can fix already before the next workshop day.

    • +
    • We convert feedback/problems into GitHub issues and track these close to the lesson material.

    • +
    +
  • +
+
+
+

Trying to measure impact with longer-term surveys

+ +
+
+

Lessons learned

+
    +
  • Think about how to measure impact/success from the beginning.

  • +
  • Make the feedback and survey results public.

  • +
  • Make the results persistent and citable.

  • +
  • Have a mechanism to follow-up on feedback.

  • +
  • Anonymization is more than just removing or dissociating names.

  • +
  • Take time designing your survey and collect feedback on the survey itself.

  • +
+
+
+

Take time designing your survey

+

We are not experts in survey design but we reached out to RISE Research +Institutes of Sweden to get feedback on our survey questions. They provided us +with a lot of valuable feedback and suggestions for improvements. +Below are few examples.

+
+

Example 1

+

First version of our survey question about impact:

+
    +
  • “Do our workshops help to save time in future?” Please quantify in hours saved: …

  • +
+

Feedback:

+
    +
  • Difficult to answer.

  • +
  • Since when? Until all eternity?

  • +
+
+Screenshot of earlier version of the survey question about impact. +
+

Earlier version of the survey question about impact.

+
+
+

Feedback:

+
    +
  • The question “Do our workshops help to save time in future?” is unspecified, +unnecessary, and leading.

  • +
  • “No time saving” does not match the wording “save time” in the question.

  • +
+
+Screenshot of later version of the survey question about impact. +
+

Later version of the survey question about impact.

+
+
+
    +
  • The wording “have you saved” now matches “No time saved”.

  • +
+
+
+

Example 2

+
    +
  • Earlier version:

    +
    Would you judge your code to be better reusable/reproducible/modular/documented
    +as a result of attending the workshop?
    +
    +- More reusable
    +- More reproducible
    +- More modular
    +- Better documented
    +- None of the above
    +
    +
    +
  • +
  • Feedback: The question is not neutrally formulated and risks leading to +over-reporting of yes answers. Consider balancing so that the questions are +formulated more neutrally.

  • +
  • Reformulated to:

    +
    After attending the workshop, would you judge your code to be
    +more reusable or not more reusable?
    +
    +- My code is more reusable
    +- My code is not more reusable
    +- Not sure
    +
    +
    +
  • +
+
+
+

Example 3

+
    +
  • Early version:

    +
    What else has changed in how you write code since attending the workshop?
    +
    +[free-form text field]
    +
    +
    +
  • +
  • Feedback: Leading and assumes that something has changed.

  • +
  • Reformulated to:

    +
    Has anything else changed in how you write code for your research after
    +attending the workshop?
    +
    +[free-form text field]
    +
    +
    +
  • +
+
+
+

Example 4

+
    +
  • Earlier version:

    +
    Has it become easier for you to collaborate on software development with your
    +colleagues and collaborators?
    +
    +- Yes
    +- Not sure
    +- No
    +
    +
    +
  • +
  • Feedback:

    +
      +
    • Leading question.

    • +
    • Avoid “Yes” and “No” response options because respondents tend to answer +“Yes” if that option is available, leading to a risk of measurement error +(acquiescence bias).

    • +
    • Do not place “Not sure” in the middle of the scale because it captures +participants who actually don’t know and should therefore be placed at the +bottom instead of in the middle of the scale.

    • +
    +
  • +
  • Reformulated to:

    +
    After attending the workshop, has it become easier or not for you to
    +collaborate on software development with your colleagues and collaborators?
    +
    +- Collaboration is easier
    +- Collaboration is not easier
    +- Not sure
    +
    +
    +
  • +
+
+
+
+

Exercise: Group discussion (10 min)

+
+

Group discussion using the collaborative notes

+
    +
  • What tricks/techniques have you tried in your teaching or seen in someone +else’s teaching that you think have been particularly effective in collecting +feedback from learners?

  • +
  • Can you give tips or share your experiences about how to convert feedback +into actionable items?

  • +
  • How do you measure the impact of your teaching? Any tips or experiences about +what you have tried or seen other courses do?

  • +
  • Anybody knows of good resources on survey design? Please link them in +the collaborative notes.

  • +
+
+
+
+
+
+
+

About the CodeRefinery project and CodeRefinery workshops in general

+
+

Objectives

+
    +
  • Discuss what CodeRefinery is and how we got here

  • +
  • Understand about the challenges to define our target audience

  • +
+
+

CodeRefinery is a +Nordic e-Infrastructure Collaboration (NeIC) +project that has started in October 2016 and is currently +funded until February 2025. We are working on the continuation plans.

+

The funding from 2022-2025 is designed to keep this project active +beyond 2025 by forming a support network and building a community of +instructors and contributors.

+
+

History

+

The CodeRefinery project idea grew out of two SeSE courses given at KTH Stockholm in 2014 and 2016. +The project proposal itself was submitted to NeIC in 2015, accepted in 2015, and started in 2016.

+

We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form.

+
+
+

Goals

+
    +
  • Develop and maintain training material on good enough software development practices for researchers that write code/scripts/notebooks.

  • +
  • Our material addresses all academic disciplines and tries to be as programming language-independent as possible.

  • +
  • Provide a code repository hosting service that is open and free +for all researchers based in universities and research institutes from Nordic countries.

  • +
  • Provide training opportunities in the Nordics using (Carpentries and) CodeRefinery training materials.

  • +
  • Evolve the project towards a community-driven project with a network of instructors and contributors.

  • +
+
+
+

Community

+
+_images/community.png +
+

Image showing the key areas of the CodeRefinery community: Workshops, chat inlcuding help channel, online meetings and co-working, +other collaborative training, eg on High Performance Computing topics.

+
+
+

CodeRefinery is not just workshops, we are community and want you to be part of it!

+

There are many different levels of involvement, from the occasional commenter in chat, +CodeRefinery ambassador (people who like the project and workshops and help us spreading the word) or lesson issue creators and lesson contributors to +local host, co-instructor or co-organizer.

+

Best first step in any case is to join the CodeRefinery Zulip chat +or let us know about your interest at support@coderefinery.org.

+
+
+

Target audience

+

One common question we get is how do we relate to the Carpentries. +This section describes how we see it:

+
+

Carpentries audience

+

The Carpentries aims to teach computational competence to learners through an applied approach, +avoiding the theoretical and general in favor of the practical and specific.

+

Mostly, learners do not need to have any prior experience in programming. +One major goal of a Carpentries workshop is to raise awareness on the tools researchers can learn/use to speed up their research.

+

By showing learners how to solve specific problems with specific tools and providing hands-on practice, +learners develops confidence for future learning.

+
+

Novices

+

We often qualify Carpentries learners as novices: they do not know what they need to learn yet. +A typical example is the usage of version control: the Carpentries lesson +Version Control with Git +aims to give a +very high level conceptual overview of Git but it does not explain how it can be used in research projects.

+
+
+
+

CodeRefinery audience

+

In that sense, CodeRefinery workshops differ from Carpentries workshops as we assume +our audience already writes code and scripts and we aim at teaching them best software practices.

+

Our learners usually do not have a good overview of best software practices but are aware of the need to learn them. +Very often, they know of the tools (Git, Jupyter, etc.) we are teaching +but have difficulties to make the best use of them in their software development workflow.

+

Whenever we can, we direct learners that do not have sufficient coding experience to Carpentries workshops.

+
+

Competent practitioners

+

We often qualify CodeRefinery learners as competent practitioners because they already have an understanding of their needs.

+
+ +
+
+

Keypoints: CodeRefinery

+
    +
  • Teaches intermediate-level software development tool lessons

  • +
  • It is difficult to define “best practices”, we try to teach “good enough” practices

  • +
  • Training network for other lessons

  • +
  • Publicly-funded discrete projects (3 projects actually) transitioning towards an open community project

  • +
  • We have online material, teaching, and exercise sessions

  • +
  • Our main target audience are competent practitioners, but also novices and experts can get something out of the workshops

  • +
  • We want more people to work with us, and to work with more people

  • +
+
+
+
+
+
+

Collaborative notes

+
+

Objectives

+
    +
  • Be able to provide a highly interactive online workshop environment with collaborative documents

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Exercise: 15 min

  • +
  • Questions & Answers: 5 min

  • +
+
+
+

Introduction

+

The Collaborative document is how you interact with the participants. +The participants can ask questions and give feedback through the collaborative +document. During a CodeRefinery session there can be a large a volume of questions. +A dedicated person, a Collaborative document-manager, is needed to answer and edit the collaborative document. +Let us see how the collaborative document is used, then discuss the role of +the editor or collaborative document-manager.

+
+
+

Collaborative document mechanics and controls

+

Technologies that can be used as a collaborative document are Hackmd, HedgeDoc, +or Google Docs

+

Hackmd or HedgeDoc are real-time text editor online. We use it to:

+
    +
  • As a threaded chat, to answer questions and provide other information without +interrupting the main flow of the room.

  • +
  • provide everyone with a more equal opportunity to ask questions.

  • +
  • create notes which will be archived, for your later reference.

  • +
+

You do not need to login/create an account to be able to edit the document.

+
+

Basic controls

+
+_images/hackmd--controls.png +
+

This may look slightly different on mobile devices and small windows.

+
+
+
    +
  • At the top (left or right), you can switch between view, +edit, and split view and edit modes.

  • +
  • You write in markdown here. Don’t +worry about the syntax, just see what others do and try to be like +that! Someone will come and fix any problems there may be.

  • +
  • Please go back to view mode if you think you won’t edit for a +while - it will still live update.

  • +
+
+
+

Asking questions

+

Always ask questions and add new sections at the very bottom. +You can also answer and comment on older questions, too.

+
+_images/hackmd--questions2.png +
+

Questions and answers in bullet points

+
+
+

Since we plan to publish the questions and answers later as part +of the workshop page, we recommend to not use any names. You can indicate +your own name to make it easier to discuss more during the workshop but +then always use this form: [name=Myname]. This makes it easier for +us to automatically remove all names before publishing the notes.

+

Other hints:

+
    +
  • Use +1 to agree with a statement or question (we are more likely +to comment on it).

  • +
  • Please leave some blank lines at the bottom

  • +
  • NOTE: Please don’t “select all”, it highlights for everyone and adds a +risk of losing data (there are periodic backups, but not instant).

  • +
  • It can be quite demanding to follow the collaborative document closely. Keep an eye +on it, but consider how distracted you may get from the course. For +things beyond the scope of the course, we may come back and answer +later.

  • +
+
+
+

Don’t get overwhelmed

+

There can be a flood of information on the collaborative document. Scan for what is +important, then if you would like come back later. But it is +important to keep checking it.

+
+
+

Privacy

+
    +
  • Assume the collaborative document is public and published: you never +need to put your name there.

  • +
  • The collaborative document will be published on the website afterwards. We will +remove all non-instructors names, but it’s easier if you don’t add +it there in the first place.

  • +
  • Please keep the link private during the workshop, since since +security is “editable by those who have the link”.

  • +
  • You can use [name=YOURNAME], to name yourself. We will remove +all names (but not the comments) before archiving the notes (use +this format to make it easy for us).

  • +
+
+
+
+

Exercise

+
+

Discuss how to collaborate and handle questions (15 min)

+

Write down your conclusions in the shared document. Items to discuss are:

+
    +
  • What is your experience with questions and discussions while teaching?

  • +
  • How do you deal with them?

  • +
  • What kind of technologies do you prefer: chat, shared document, or voices +and discussion raised during instruction? And why?

  • +
+
+
+
+

Collaborative Document Manager

+

We have one person who is a “Collaborative Document helper”. This isn’t the only +person that should edit and answer, but one person shouldn’t have too +much else on their mind so can focus on it. They also make sure that +the collaborative document is updated with exercise, break, and other meta-information to +keep people on track.

+

Below, (*) = important.

+
+

Before the workshop

+
    +
  • Create a new collaborative document for the workshop

  • +
  • make sure that editing is enabled for anyone without login

  • +
  • Add workshop information, links to the workshop page and material +and an example question and answer to the top of the collaborative document(see below)

  • +
+
+
+

Most things to edit (everyone)

+

Make it easy to post after the course and consistent to follow:

+
    +
  • Tag all names with [name=XXX] (so they can be removed later), +remove other personal data or make it obvious.

  • +
  • Add in information on exercises (new section for them, link, end +time, what to accomplish)

  • +
  • Make a logical section structure (# for title, ## for sections, +### for episodes, etc. - or what makes sense)

  • +
+
+
+

General Collaborative Document practices

+
+_images/hackmd--full-demo.png +
+

A live demo of a Collaborative Document during a Q&A time. The two instructors are +discussing some of the import answers. Multiple learners have asked +questions, multiple answers, and some remaining to be answered

+
+
+

Keep it formatted well:

+
    +
  • (*) Tag names you see with [name=XXX] so that we can remove it +later.

  • +
  • Heading level # is only the page title

  • +
  • Add a new ## heading when a new lesson or similar thing is +started (introduction, icebreaker, break between lessons, etc)

  • +
  • Add a new ### heading when a new episode, exercise, break +(within exercise session)

  • +
  • Ensure people are asking questions at the bottom, direct them there +if they aren’t.

  • +
  • (*) Ensure each question is a bullet point. Each answer or follow-up +should be a bullet point below.

    +
      +
    • Should you use more deeply nested bullet points, or have only one +level below the initial question? It depends on the context, but +if a conversation goes on too long, try not to let it go too +deep.

    • +
    +
  • +
+

Update with meta-talk, so that learners can follow along easily:

+
    +
  • Add Icebreaker and introductory material of the day. Try to talk to +people as they joined to get them to open the collaborative document and answer.

  • +
  • Anything important for following along should not be only said via +voice. It needs to be in the collaborative document, too.

  • +
  • New lessons or episodes, with links to them.

  • +
  • For exercises, link to exercise and add the duration, end time, +goals. If these are unclear, bring it up to the instructor by voice.

  • +
  • Add a status display about breaks.

  • +
+

Screenshare it when necessary:

+
    +
  • During breaks and other times, share the collaborative document(including the +notification about break, and when it ends).

  • +
  • It is nice if the arrangement allows some of the latest questions to +be seen, so people are reminded to ask there.

  • +
  • Someone else may do this, but should make sure it happens.

  • +
+

Answer questions

+
    +
  • If there is an question that should be answered by the instructor by +voice, bring it up (by voice) to the instructor immediately.

  • +
  • How soon do you answer questions? Two points of view:

    +
      +
    • Answer questions right away: can be really intense to follow.

    • +
    • Wait some so that we don’t overload learners: reduces the info +flow. But then do people need to check back more often.

    • +
    • You need to find your own balance. Maybe a quick answer right +away, and more detailed later. Or delay answers during the most +important parts of the lecture.

    • +
    +
  • +
  • Avoid wall-of-text answers. If reading an answer takes too long, it +puts the person (and other people who even try to read it) behind +even more by taking up valuable mental energy. If an answer needs a +wall of text, consider these alternatives:

    +
      +
    • Progressive bullet points getting more detailed (first ones +useful alone for basic cases)

    • +
    • Don’t be worried to say “don’t worry about this now, let’s talk +later.”

    • +
    • Figure out the root problem instead of answering every possible +interpretation

    • +
    • Declare it advanced and that you will come back later.

    • +
    +
  • +
+

Ensure it can be posted quickly:

+
    +
  • The collaborative document gets posted to the workshop webpage. For this, it needs some +minimal amount of formatting (it doesn’t need to be perfect, just +not horrible).

  • +
  • All names and private information needs to be stripped. This is why +you should rigorously tag all names with [name=XXX] so they can be +removed (see above).

    +
      +
    • Learner names can be completely removed. CR staff names can be +[name=CR] or something similar.

    • +
    • There may be other private URLs at the top or bottom.

    • +
    +
  • +
  • If possible, send the PR adding the collaborative document to the workshop webpage +(though others can do this, too).

  • +
+
+
+

Collaborative document format example

+
# Workshop, day 1
+
+
+## Lesson name
+https://coderefinery.github.io/lesson/
+
+### Episode name
+https://coderefinery.github.io/01-episode/
+
+- This is a question
+  - Anwser
+  - More detailed answer
+- question
+  - answer
+
+### Exercises:
+https://link-to-exercise/.../.../#section
+20 minutes, until xx:45
+Try to accomplish all of points 1-3.  Parts 4-5 are optional.
+
+Breakout room status:
+- room 2, need help with Linux permissions
+- room 5, done
+
+### Break
+:::danger
+We are on a 10 minute break until xx:10
+:::
+
+
+## Lesson 2
+https://coderefinery.github.io/lesson-2/
+
+
+
+
+
+

Posting the collaborative document to the website

+

The collaborative document should be posted sooner rather than later, and hopefully the +steps above will make it easy to do so quickly. You could wait a few +hours, to allow any remaining questions to be asked an answered.

+
    +
  • Download as markdown

  • +
  • Remove any private links at the top

  • +
  • Adjust headings so that they are reasonable

  • +
  • Look for private info and remove it

    +
      +
    • Search document for [name=???] (change to [name=staff] or +[name=learner])

    • +
    • Any names not tagged with [name=]

    • +
    • usernames in URLs

    • +
    • private links

    • +
    +
  • +
+
+
+

Feedback template

+
## Feedback, day N
+
+:::info
+### News for day N+1
+- .
+- .
+:::
+
+### Today was (multi-answer):
+- too fast: 
+- just right: 
+- too slow: 
+- too easy: 
+- right level: 
+- too advanced: 
+- I would recommend this course to others: 
+- Exercises were good: 
+- I would recommend today to others: 
+- I wouldn't recommend today: 
+
+### One good thing about today:
+- ...
+- ...
+
+### One thing to be improved for next time:
+- ...
+- ...
+
+### Any other comments:
+- ...
+- ...
+
+
+
+

Keypoints

+
    +
  • Having a collaborative document improves communication and interaction.

  • +
  • Answering questions requires a dedicated person - A Collaborative Document Manager.

  • +
  • The collaborative document should be posted on the web site as soon as possible.

  • +
+
+
+
+
+
+

A workshop seen from different perspectives

+
+

Objectives

+
    +
  • Understand the general structure of CodeRefinery workshops and why it is the way it is

  • +
  • Get to know the different roles of a workshop and which ones are the most essential ones

  • +
  • Understand the importance of installation instructions and how they contribute to learners success

  • +
  • Understand the importance of onboarding and a welcoming community for volunteers in a workshop

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 15 min

  • +
  • Roles journeys can be shortened to looking only at instructor role.

  • +
+
+
+

Note

+

This episode focuses on the large scale streamed workshop setup. Some of the features can also be applied to smaller scale workshops though.

+
+
+

Discussion

+
+

Discussion

+

In breakoutrooms: choose one or two questions to talk about your own experiences; summary in collaborative notes:

+
    +
  • What kind of roles have you been in yourself regarding workshops?

  • +
  • How were you prepared for your role?

  • +
  • What are the things you would like to know before a workshop?

  • +
  • How are you preparing your participants for your trainings?

  • +
  • What was the best workshop experience for you as learner, helper or instructor? What made it great?

  • +
+
+
+
+

One workshop - many parts

+
+_images/CR_workshop_setup.png +
+

Image showing the different phases of a CodeRefinery workshop described below. Also showing that while there is only two people teaching, many people work behind the scenes.

+
+
+
+

Before the workshop

+
    +
  • During winter/summer: “Someone” takes the coordinator role for the next workshop

  • +
  • Coordinator fills other roles:

    +
      +
    • Coordinator: collects necessary lesson updates, supports other coordinators

    • +
    • Registration coordinator: Sets up web page, starts and manages registration

    • +
    • Instructor coordinator: Finds instructors and onboards them

    • +
    • Advertising coordinator: Prepares advertizement texts and finds people to distribute them

    • +
    • Team coordinator: Gathers local organizers/teams

    • +
    • Bring your own code session coordinator: If available, offer BYOC session after main workshop

    • +
    +
  • +
  • Instructor: Onboarding with (instructor-) coordinator and previous instructor of lesson; update of lesson materials (urgent issues and personal touches)

  • +
  • Local organizer/Team lead: Group onboarding ~ week/or two before workshop

  • +
  • Learner: Gets installation instructions, invited to installation help session, workshop info from event page and summary via e-mail

  • +
  • Collaborative notes manager sets up the notes document

  • +
+
+

Note

+

Onboarding manuals

+
    +
  • Outline of what will happen during the workshop

  • +
  • Discussion of different strategies to handle the exercise sessions

  • +
  • Lowering the barrier to ask for support by meeting some organizers

  • +
  • Q&A

  • +
+
+
+

Note

+

Installation instructions

+
    +
  • Instructions for all operating systems

  • +
  • Goal: Learners leave the workshop and are ready to apply the learned tools and techniques to their own work

  • +
  • Support session for installation challenges

  • +
+
+
+
+

During the workshop

+
+_images/BYOC.png +
+

Image showing the different ways learners can do the exercises. No matter which way they choose, they always watch the stream and interact with instructors and organizers via collaborative notes. Individual learners do the exercises alone, people in online or local classrooms in addition get to discuss with their peers.

+
+
+
    +
  • Everyone watches stream

  • +
  • Co-instructors +- Present content +- Answer questions in collaborative notes

  • +
  • Collaborative notes manager

    +
      +
    • Keeps the collaborative notes clean

    • +
    • Helps answering questions

    • +
    • Adds sections

    • +
    • Archives the document after each day

    • +
    +
  • +
  • Learners do exercises individually or in team

  • +
  • Local organizer / Team lead

    +
      +
    • Guides learners through exercises

    • +
    • Facilitates discussion

    • +
    +
  • +
  • (Registration-) coordinator sends out e-mails to participants after each day (summary + preparation)

  • +
  • Director/Broadcaster manages the streaming (see session 4)

  • +
+
+
+

After the workshop

+
    +
  • Coordinator collects lessons learned based on experience and feedback and turns them into issues

  • +
  • Coordinator organizes debriefing week after the workshop, where anyone can join to give feedback

  • +
  • “Someone” sends out post-workshop survey half a year after workshop

  • +
  • Coordinator organizes “Bring your own code” sessions

  • +
  • Broadcaster prepares and shares recording (see session 4)

  • +
+
+

Note

+

Bring your own code sessions

+

We want to support learners to apply what they have learned in the workshop to their own work by offering one/two sessions where they can drop in, and discuss challenges with CodeRefinery instructors and helpers.

+
+_images/welcome.png +
+

Image showing a classroom learning about git leading to a discussion between student and teacher to start a welcoming environment for asking for help.

+
+
+
+
+
+
+

This sounds like a lot of people and time investment!

+
    +
  • Many roles can be combined or adjusted as needed

  • +
  • Some roles can be taken on by multiple people

  • +
+

So how many people are needed for this kind of workshop?

+
    +
  • Recommended minimum: 2-3 people

  • +
  • Optimum: ~ 4-5 people +The more people you involve, the more time goes into coordination work.

  • +
+
+
+

How did we get to this setup?

+
    +
  • Collaborative in-person workshops since 2016 around the Nordics

  • +
  • Moved online in 2020

  • +
  • Started with “traditional zoom” workshops, breakoutrooms, volunteer helpers

  • +
  • Thought about scaling and ease of joining -> current setup (More about this in session 4)

  • +
  • Continuous development

  • +
+

We also still do smaller scale local workshops, if instructors are available. +You can offer your own CodeRefinery workshop by inviting other CodeRefinery instructors. +You can also reuse single lessons and integrate them into your own teaching.

+
+
+

Workshop roles and their journeys

+
+

Individual learner journey

+
    +
  • Registration

  • +
  • Installation

  • +
  • (if appicable: Invited to local meetup)

  • +
  • Workshop

    +
      +
    • Watch stream

    • +
    • Q&A in notes

    • +
    • Exercises alone or in team

    • +
    • Daily feedback

    • +
    +
  • +
  • Debrief/ Feedback session

  • +
  • Post workshop survey

  • +
+
+
+

Instructor journey

+
    +
  • Indicate interest in CodeRefinery chat

  • +
  • Onboarding

  • +
  • Lesson material updates

  • +
  • Teaching

  • +
  • (if wished: supports answering questions in notes)

  • +
  • Debrief

  • +
+
+
+

Team lead / Local host journey

+
    +
  • Registration

  • +
  • (if applicable: run own registration)

  • +
  • Onboarding

  • +
  • Workshop

    +
      +
    • Watch stream

    • +
    • Facilitate exercises/discussions

    • +
    • Daily feedback

    • +
    +
  • +
  • Debrief / feedback / survey

  • +
+
+
+

Other roles

+

Director and broadcaster roles will be discussed in Session 4. +For more in-depth descriptions and other roles (host, instructor, registration coordinator, etc), see also our CodeRefinery manuals.

+
+
+
+

Different roles as stepping stones for community involvement

+
+_images/steps.png +
+

Image showing a person jumping from step to step following learner, helper, expert helper, co-instructor, co-organizer.

+
+
+

There is no “one way” to get involved. Do what feels right. +Interested in teaching with us? Let us know and we can discuss what is a suitable path for you!

+
+

Keypoints

+
    +
  • CodeRefinery workshops are a collaborative effort with many different roles

  • +
  • Onboarding the different roles is one key aspect of our workshops

  • +
  • Everyone has their own path

  • +
+
+
+
+
+

Sound

+
+

Objectives

+
    +
  • Understand that sound quality is very important

  • +
  • Evaluate your and others sound quality and know how to improve it

  • +
  • Test tips and tricks for achieving good sound quality

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Exercises: 10 min

  • +
+
+
+

The importance of audio

+
    +
  • Pleasing audio quality makes events much more enjoyable

  • +
  • Audio is one of the most important things you can control

  • +
  • Things that can go wrong:

    +
      +
    • Too quiet

    • +
    • Too loud

    • +
    • Instructors’ volumes imbalanced

    • +
    • Background noise

    • +
    • Low-quality/breaking up audio hard to hear.

    • +
    • “Ducking” (first words lower volume, or lower volume other times)

    • +
    +
  • +
+
+
+

Tips for good sound quality

+
    +
  • Have a headset with mounted microphone

    +
      +
    • Even if you have a professional external microphone, it doesn’t +matter if your room has bad acoustics.

    • +
    • The close pickup can’t be beat with normal tools.

    • +
    • As long as it’s headset mounted, price doesn’t seem to matter +that much.

    • +
    +
  • +
  • Don’t use Bluetooth

    +
      +
    • Bluetooth can have too much latency (300-500ms)

    • +
    • This may seem small but for interactive work, it’s a lot

    • +
    • Use a wired headset, or wireless with a non-Bluetooth USB plug +(like gaming headsets have). These have much lower latency.

    • +
    • Bluetooth 5 can have much lower latency, but you probably +shouldn’t count on that without testing.

    • +
    • It can also have lower sound quality on some devices due to +bandwidth limitations.

    • +
    +
  • +
  • Once you have a headset, turn input noise cancellation to low +(wherever it might be: headphone, meeting software, etc.).

  • +
+
+
+

Balancing and dynamic adjustment

+
    +
  • It’s important that instructors volumes match.

  • +
  • An exercise will go over a systematic procedure for matching +volumes.

    +
      +
    • Practice so that you can do this quickly.

    • +
    +
  • +
  • May need re-adjusting when instructors swap out or start getting +excited.

  • +
  • An exercise below will demonstrate our procedure.

  • +
+
+
+

Speak up when there are problems

+
    +
  • If you notice someone with audio issues, let them know right away +(voice if bad, or chat/notes if less urgent).

  • +
  • Take the time to fix it as soon as practical.

  • +
  • Make a culture of speaking up, helping, and not suffering.

  • +
+
+
+

Recommendations

+
    +
  • Procure some reasonable headset.

  • +
  • Low/medium-priced gaming-type headsets have worked well for us.

    +
      +
    • (gaming headsets usually aren’t Bluetooth, because gaming needs +low latency.)

    • +
    +
  • +
  • Show this page to your workplace (if you have one) and call a good +headset work equipment.

  • +
+
+
+

Exercises

+
+

Sound-1: Evaluate sound quality

+

It’s important to be able to discuss with others the quality of their +audio. They can’t hear themselves, after all.

+
    +
  • Within the teams, discuss each person’s audio quality and what kind +of setup they have.

  • +
  • Be respectful and constructive (and realize that people came +prepared to listen, not teach).

  • +
  • Consider, for example

    +
      +
    • Volume

    • +
    • Clarity

    • +
    • Background noise

    • +
    • Noise cancellation artifacts

    • +
    • “Ducking”: first words at lower volume or missing

    • +
    +
  • +
  • Discuss how to bring this up during other courses and meetings.

  • +
+
+
+

Sound-2: Adjust volume up and down

+

In addition to individual quality, it is important that sound is +balanced among all instructors. Have you ever been to a event when +one person is too quiet and they can’t make themselves any louder? +And they can’t adjust it?

+

You should ensure that you have a range of volumes available to you. +You might have to look into several different locations in order to +make the full adjustment ().

+
    +
  • Go to your sound settings

  • +
  • One by one, each person

    +
      +
    • Adjusts their microphone volume so quiet that they can’t be heard.

    • +
    • Adjusts their microphone volume so that it is extremely loud (this +may require going beyond 100% if possible).

    • +
    +
  • +
  • Basically, make sure you aren’t so close to either end that you have +no potential to make an adjustment in that direction.

  • +
  • Everyone tries to set the volume to something reasonable, in +preparation for the next exercise.

  • +
+

Once you know where these settings are , you won’t be panicked when the +volume is too low or high during a course.

+
+
+

Sound-3: Do a balance check

+

It’s important that instructor audio is balanced (the same volume). +But how can you do this?

+
    +
  • Pick a leader.

  • +
  • The leader decides the order (“I am first, then [name-1] and +[name-2]”)

  • +
  • The leader says “one”. Everyone else says “one” in the order +specified.

  • +
  • The leader says “two”. Everyone else says “two” in the order.

  • +
  • The leader asks for opinions on who they think is louder or softer. +If there are more than three people, you can figure it out +yourselves. With less than two, you have to ask someone in the +audience.

  • +
+

Example:

+
    +
  • Leader: Let’s do a sound check. I am first, then AAA and BBB.

  • +
  • Leader: One

  • +
  • AAA: One

  • +
  • BBB: One

  • +
  • Leader: Two

  • +
  • AAA: Two

  • +
  • BBB: Two

  • +
  • Leader: Three

  • +
  • AAA: Three

  • +
  • BBB: Three

  • +
  • Leader: How did that sound to everyone?

  • +
  • [Someone else]: Leader and BBB were pretty similar but AAA is a bit +lower.

  • +
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Audio quality is important and one of the most notable parts of the +workshop.

  • +
  • Improving audio isn’t hard or expensive, but does require preparation.

  • +
+
+
+
+
+

How to prepare a quality screen-share

+
+

Objectives

+
    +
  • Discuss the importance of a well planned screen-share.

  • +
  • Learn how to prepare and how to test your screen-share setup.

  • +
  • Know about typical pitfalls and habits to avoid.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 15 min

  • +
  • Exercises: 15 min

  • +
+
+
+

Share portrait layout instead of sharing entire screen when teaching online

+
    +
  • Many learners will have a smaller screen than you.

  • +
  • You should plan for learners with only one small screen.

  • +
  • A learner will need to focus on both your screen share and their +work.

  • +
  • Share a portrait/vertical half of your screen (840 × 1080 is our standard and your +maximum).

  • +
  • Zoom provides a “Share a part of screen” that is good for this.

    +
      +
    • Our latest streaming setup (day 4) can take the portrait part for +you so you can share landscape.

    • +
    • Zoom + Linux + Wayland display manager doesn’t have “Share a +portion of the screen”

      +
        +
      • You can share a single window portrait.

      • +
      • Or you can start your desktop session in “X11” or “Xorg” legacy +mode.

      • +
      • Or possibly other workarounds (does anyone know other solutions?)

      • +
      +
    • +
    +
  • +
+
+_images/landscape.png +
+

A FullHD 1920x1080 screen shared. Learners have to make this really small if +they want to have something else open.

+
+
+
+_images/portrait.png +
+

Portrait layout. Allows learners to have something else open in the other half.

+
+
+

Motivation for portrait layout:

+
    +
  • This makes it easier for you to look at some other notes or to coordinate +with other instructors at the same time +without distracting with too much information.

  • +
  • This makes it possible for participants to have something else open in the +other screen half: terminal or browser or notebook.

  • +
+
+

Instructor perspective

+
+_images/instructor.png +
+

I1: +This is how it can look for the instructor. Zoom is sharing a portion of the left +side, the right side is free for following notes, chat, etc.

+
+
+
+
+

Learner perspective

+

Here are three examples of how it can look for the learner.

+
+_images/learner-large.png +
+

L1: +Learner with a large screen, Zoom in dual-monitor mode so that the instructor +pictures are not shown. Screen-share is on the left side, collaborative notes +at bottom left, terminal and web browser on the right.

+
+
+
+_images/learner-normal.png +
+

L2: +A learner with a single large screen (Zoom in “single monitor mode”). +Instructor screen share at right, learner stuff at left.

+
+
+
+_images/learner-small.png +
+

L3: +A learner with a particularly small screen. Instructor screen-share at left, +your windows at right.

+
+
+
+
+
+

Share the history of your commands

+

Even if you type slowly it is almost impossible to follow every command. We +all get distracted or want to read up on something or while following a command +fails on the learner laptop while instructor gets no error.

+

Add pauses and share the commands that you have typed so that one can catch up.

+

Below are some examples (some more successful than others) of sharing history +of commands.

+
+_images/history-portrait.png +
+

H1: +A vertical screen layout shared. Note the extra shell history at the top. The +web browser is at the bottom, because the Zoom toolbar can cover the bottom +bit.

+
+
+
+_images/history-rsh.png +
+

H2: +This isn’t a screen-share from CodeRefinery, but may be instructive. Note the +horizontal layout and shell history at the bottom right.

+
+
+
+_images/history-landscape-dark.png +
+

H3: +Similar to above, but dark. Includes contents on the right.

+
+
+
+_images/history-portrait-light.png +
+

H4: +Jupyter + terminal, including the fish shell and the terminal history.

+
+
+
+_images/history-portrait-dark.png +
+

H5: +Lesson + terminal, tmux plus terminal history and dark background.

+
+
+
+_images/portrait.png +
+

H6: +HPC Kickstart course. Note the colors contrast of the windows and colors of +the prompt and text. The history is smaller and doesn’t take up primary +working space. The working directory is in the window title bar.

+
+
+
+https://raw.githubusercontent.com/bast/history-window/main/demo.gif +
+

H7: +Show command history “picture-in-picture”, in the same terminal window.

+
+
+
+
+

How to configure history sharing

+

You need to find a way to show the recent commands you have entered, so that +learners can see the recent commands. Below are many solutions. Try them out +and see what works for you.

+
    +
  • prompt-log: +It adds a interesting idea that the command you enter is in color and also +provides terminal history before the command returns.

  • +
  • Simple: The simple way is PROMPT_COMMAND="history -a" and then +tail -f -n0 ~/.bash_history, but this doesn’t capture ssh, +sub-shells, and only shows the command after it is completed.

  • +
  • Better yet still simple: Many Software Carpentry instructors use +this script, +which sets the prompt, splits the terminal window using tmux and displays command history +in the upper panel. Requirement: tmux

  • +
  • Better (bash): This prints the output before the command is run, +instead of after. Tail with tail -f ~/demos.out.

    +
    BASH_LOG=~/demos.out
    +bash_log_commands () {
    +    # https://superuser.com/questions/175799
    +    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    +    [[ "$PROMPT_COMMAND" =~ "$BASH_COMMAND" ]] && return # don't cause a preexec for $PROMPT_COMMAND
    +    local this_command=`HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"`;
    +    echo "$this_command" >> "$BASH_LOG"
    +}
    +trap 'bash_log_commands' DEBUG
    +
    +
    +
  • +
  • Better (zsh): This works like above, with zsh. Tail with tail -f ~/demos.out.

    +
    preexec() { echo $1 >> ~/demos.out }
    +
    +
    +
  • +
  • Better (fish): This works like above, but for fish. Tail with +tail -f ~/demos.out.

    +
    function cmd_log --on-event fish_preexec ; echo "$argv" >> ~/demos.out  ; end
    +
    +
    +
  • +
  • Better (tmuxp): This will save some typing. +TmuxP is a Python program (pip install tmuxp) that gives you programmable tmux sessions. One configuration that +works (in this case for fish shell):

    +
    session_name: demo
    +windows:
    +  - window_name: demo
    +    layout: main-horizontal
    +    options:
    +      main-pane-height: 7
    +    panes:
    +      - shell_command:
    +          - touch /tmp/demo.history
    +          - tail -f /tmp/demo.history
    +      - shell_command:
    +          - function cmd_log --on-event fish_preexec ; echo "$argv" >> /tmp/demo.history  ; end
    +
    +
    +
  • +
  • Windows PowerShell: In Windows Terminal, +a split can be made by pressing CTRL+SHIFT+=. Then, in one of the splits, the following +PowerShell command will start tracking the shell history:

    +
    Get-Content (Get-PSReadlineOption).HistorySavePath -Wait
    +
    +
    +

    Unfortunately, this only shows commands after they have been executed.

    +
  • +
  • Tavatar: shell history mirroring teaching tool can copy recent history to a remote server.

  • +
  • history-window: Show command +history “picture-in-picture” when teaching command line. Requires Bash.

  • +
+
+
+

Font, colors, and prompt

+
+

Terminal color schemes

+
    +
  • Dark text on light background, not dark theme. Research and our +experience says that dark-text-on-light is better in some cases and +similar in others.

  • +
  • You might want to make the background light grey, to avoid +over-saturating people’s eyes and provide some contrast to the pure +white web browser. (this was an accessibility recommendation when +looking for ideal color schemes)

  • +
  • Do you have any yellows or reds in your prompt or program outputs? +Adjust colors if possible.

  • +
+
+
+

Font size

+
    +
  • Font should be large (a separate history terminal can have a smaller +font).

  • +
  • Be prepared to resize the terminal and font as needed. Find out +the keyboard shortcuts to do this since you will need it.

  • +
+
+
+

Prompt

+

At the beginning of the workshop your goal is to have a shell +as easy to follow as possible and as close to what learners will +see on their screens:

+
    +
  • Your prompt should be minimal: few distractions, and not take up many +columns of text.

  • +
  • prompt-log does +this for you.

  • +
  • The minimum to do is is export PS1='\$ '.

  • +
  • Blank line between entries: export PS1='\n\$ '.

  • +
  • Have a space after the $ or % or whatever prompt character you +use.

  • +
  • Strongly consider the Bash shell. This is what most new people will +use, and Bash will be less confusing to them.

  • +
  • Eliminate menu bars and any other decoration that uses valuable +screen space.

  • +
  • Add colors only if it simplifies the reading of the prompt.

  • +
+

Later in the workshop or in more advanced lessons:

+
    +
  • Using other shells and being more adventurous is OK - learners will +know what is essential to the terminal and what is extra for your +environment.

  • +
+

Try to find a good balance between:

+
    +
  • Showing a simple setup and showing a more realistic setup.

  • +
  • Showing a consistent setup among all instructors and showing a +variety of setups.

  • +
+
+
+
+

Habits we need to un-learn

+
    +
  • Do not clear the terminal. Un-learn CTRL-L or clear if possible. +More people will wonder what +just got lost than are helped by seeing a blank screen. Push +ENTER a few times instead to add some white space.

  • +
  • Do not rapidly switch between windows or navigate quickly between multiple +terminals, browser tabs, etc. This is useful during your own work when nobody +is watching, but it is very hard to follow for learners.

  • +
  • Avoid using aliases or shortcuts that are not part of the +standard setup. Learners probably don’t have them, and they will fail +if they try to follow your typing. Consider even to rename corresponding +files (.bashrc, .gitconfig, .ssh/config, .ssh/authorized_keys, .conda/*).

  • +
  • Be careful about using tab completion or reverse history search if these +haven’t been introduced yet.

  • +
+
+
+

Desktop environment and browser

+
    +
  • Try to remove window title bars if they take up lots of space +without adding value to the learner.

  • +
  • Can you easily resize your windows for adjusting during teaching?

  • +
  • Does your web browser have a way to reduce its menu bars and other +decoration size?

    +
      +
    • Firefox-based browsers: go to about:config and set +layout.css.devPixelsPerPx to a value slightly smaller than one, +like 0.75. Be careful you don’t set it too small or large since +it might be hard to recover! When you set it to something smaller +than 1, all window decorations become smaller, and you compensate +by zooming in on the website more (you can set the default zoom to +be greater than 100% to compensate). Overall, you get more +information and less distraction.

    • +
    +
  • +
+
+
+

How to switch between teaching setup and work setup?

+
    +
  • Make a dedicated “demos” profile in your terminal emulator, if +relevant. Or use a different terminal emulator just for demos.

  • +
  • Same idea for the browser: Consider using a different browser profile for +teaching/demos.

  • +
  • Another idea is to containerize the setup for teaching. +We might demonstrate this during the Sharing teaching gems session later.

  • +
+
+
+

Keypoints

+
    +
  • Share portrait layout instead of sharing entire screen

  • +
  • Adjust your prompt to make commands easy to read

  • +
  • Readability and beauty is important: adjust your setup for your audience

  • +
  • Share the history of your commands

  • +
  • Get set up a few days in advance and get feedback from someone else. +Feedback and time to improve is very important to make things clear and accessible. +10 minutes before the session starts is typically too late.

  • +
+
+
+
+

Exercises

+
+

Evaluate screen captures (20 min)

+

Evaluate screenshots on this page. Discuss the trade-offs of each one. Which +one do you prefer? Which are useful in each situation?

+

Please take notes in the collaborative document.

+
+
+

Set up your own environment (20 min)

+

Set up your screen to teach something. Get some feedback from another learner +or your exercise group.

+
+
+
+

Other resources

+ +
+
+
+
+
+

Computational thinking

+
+

Objectives

+
    +
  • Explain what is computational thinking

  • +
  • Get to know how the theory of computational thinking can be used in teaching

  • +
  • Short exercise

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 10 min

  • +
+
+

Materials available as slides.

+
+

Keypoints

+
    +
  • Computational Thinking consists of 4 main parts: decomposition, pattern recognition, abstraction and algorithmic design.

  • +
  • How can this be a useful framework for solving problems?

  • +
  • How can this be used practically?

  • +
+
+
+
+

CodeRefinery teaching philosophies

+
+

Objectives

+
    +
  • Get to know the teaching philosophies of CodeRefinery instructors

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Discussion: 20 min

  • +
+
+
+

Introduction

+

During this episode we split into breakoutrooms and discuss own teaching philosophies. +Collect your teaching philosophies in the collaborative document. We will be going through +these and the end of the lesson.

+
+

Ice-breaker in groups (20 minutes)

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+
+

Instructor views

+

Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops.

+

It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us.

+
+

Video recordings

+

We have recorded some of the below as videos: https://www.youtube.com/playlist?list=PLpLblYHCzJAAHF89P-GCjEXWC8CF-7nhX

+
+
+

Bjørn Lindi

+

My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this “BLOB” (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the “BLOB”, to be able to share it with others.

+

In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic.

+

When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson.

+

Tools that I find useful in preparing a lesson is concept maps and Learner Personas (though I have developed too few of them):

+ +
+
+

Radovan Bast

+

My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos.

+

My goal for a lesson is to spark curiosity to try things after the lesson, both +for the novices (“This looks like a useful tool, I want to try using it after +the workshop.”) and the more experienced participants (“Aha - I did not know +you could do this. I wonder whether I can make it work with X.”). I like to +start lessons with a question because this makes participants look up from +their browsers.

+

Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise.

+

For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate the +answer.

+

I try to avoid jargon and “war stories” from the professional developers’ +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid “customer”, +“production”, also a lot of Agile jargon is hard to relate to.

+

Less and clear is better than more and unclear. Simple examples are better than +complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +“simply”, “just”, “easy”. If participants take home one or two points from a +lesson, that’s for me success.

+

I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don’t want to be +surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or slide. +This allows me to skip and distill the essence and not read bullet point by +bullet point.

+

I try to never deviate from the script and if I do, be very explicit about it.

+

A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel listening to me.

+

I very much like the co-teaching approach where the other person helps +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson.

+
+
+

Sabry Razick

+

My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case.

+
+
+

Richard Darst

+

Like many people, I’ve often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I’ve realized long ago that my most important lessons weren’t +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I’ve realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds.

+

My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I’m often start at the +very basics, because this is what I see missing most often.

+

When teaching, I like lots of audience questions and don’t mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don’t have to know everything perfectly, just show how +you’d approach a problem.

+
+
+

Stepas Toliautas

+

I aim for my learners to understand things (concepts, techniques…), instead of just memorizing them. The phrase I use from time to time when teaching information technology topics (be it hardware or software) is “there is no magic”: everything can be explained if necessary. While CodeRefinery also emphasizes usefulness/ immediate applicability of the content, often having the correct notions actually helps to start using them sooner and with less mistakes.

+

I try to guide my audience through the presented material with occasional questions related to previous topics and common knowledge – to help them link the concepts already during the lesson. I’m also fully aware that waiting for someone to answer is quite uncomfortable in-person and doubly so in an online environment, especially if no one uses their cameras :)

+

And if I get the question I don’t have the answer for (or material to show it) at the moment, in university classes I prepare and come back to it next time. While with one-off workshops there might not be a “next time”, open-source material used by CodeRefinery allows to have the same outcome: the latest and greatest version stays available for self-study afterwards.

+
+
+
+

Summary

+
+

Keypoints

+
    +
  • People have different viewpoints on teaching.

  • +
+
+
+
+
+

Co-teaching

+
+

Objectives

+
    +
  • Get to know the principle of co-teaching: How we do it and how you can too.

  • +
  • Learn the team teaching concept and how to tailor it to your situation.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 15 min

  • +
  • Exercises: 10 min

  • +
  • Discussion: 5 min

  • +
+
+
+

Overview

+

CodeRefinery lessons benefit from the application of the concepts of co-teaching.

+
+

Co-teaching

+

Co-teaching can be defined as “the division of labor between educators to plan, organize, instruct and make assessments on the same group of students, generally in a common classroom, and often with a strong focus on those teaching as a team complementing one another’s particular skills or other strengths”.

+
+

Co-teaching can be used in various forms, some of which are present in our workshops:

+
    +
  • Teaching + support, e.g. one of the teachers leading instruction while the other watches over and maintains the collaborative document (HackMD/HedgeDoc/…).

  • +
  • Another similar example is remote learning groups that watch the streamed CodeRefinery lessons guided by the local instructors.

  • +
  • Having open-source material and planning jointly allows multiple instances of a lesson to be held by multiple teachers:

    +
      +
    • parallel teaching, to different audiences at the same time,

    • +
    • alternative teaching, to different audiences at the same or different time, with potential content adjustments (for example, different installation procedures).

    • +
    +
  • +
  • Team teaching, where the lesson is presented by multiple (in most cases, two) teachers who actively engage in conversation with each other. The team-teaching concept is explained in more detail in the CodeRefinery manual.

  • +
+

In reality, different forms are very often mixed or fused together, even within a single lesson.

+

Co-teaching is not an online-only concept. However, it is very practical in online teaching due to larger number of instructors and learners potentially available to join a teaching session.

+
+
+

Co-teaching and team teaching benefits

+
    +
  • It saves preparation time. Co-teachers can rely on each other’s strengths while creating/ revising the material as well as in unexpected situations during the lesson.

  • +
  • It helps with onboarding new instructors. One of the co-teachers can be learning at the same time, either the subtleties of the material taught (in this case literally being the “voice of the audience”) or the teaching process itself.

  • +
  • Team teaching looks more interactive and engaging to the audience in many cases, without forcing the learners to speak up if they can’t or don’t want to do so.

  • +
  • It also ensures responsive feedback and less workload by having more active minds.

  • +
+
+

Are there any downsides?

+

Not every learner and not every instructor might like the team-teaching approach.

+
    +
  • It might seem less structured, unprepared, and chaotic, even with preparation.

    +
      +
    • It might create situations where instructors accidentally talk over each other or “interrupt” and change the flow of the lesson.

    • +
    • For some instructors it can be stressful to not know in advance what questions they get asked from the co-instructor.

    • +
    • Sometimes when an unexpected question is asked that throws the other instructor off, it can add to the feeling of chaos and unpreparedness.

    • +
    +
  • +
  • It can be interactive and engaging but it can also end up awkward if the co-teachers don’t have a good synergy.

    +
      +
    • Can sound awkward: Main instructor talking all the time and at the end asking co-instructor whether everything is clear and co-instructor only saying “yes”.

    • +
    • Possibly more engaging: Co-instructor asking questions which help with the flow and a common understanding of the material.

    • +
    +
  • +
+
+
+
+

Team teaching specifics

+
    +
  • For successful team teaching, additional coordination is needed, first of all to agree on the teaching model (see below) and the person in control (the director) for the lesson or its parts.

  • +
  • It’s useful to keep track of the lecture plan. The discussion is a good way to make lesson more interactive and adjust to the audience, but deviating too much will become disorienting (for example, if someone dropped their attention for a minute and now is trying to catch-up by reading lecture notes).

  • +
  • Experienced solo teacher might have a habit to keep talking (lecturing), while the co-teacher might not want to “interrupt”. Therefore, it is important for the leading presenter to anticipate and allow for remarks/ questions, and this can be different from one’s previous teaching style at first.

  • +
+
+
+

Team teaching models

+

We propose two basic models, but of course there is a constant continuum.

+
+

Guide and demo-giver

+

One person serves the role of guide, explaining the big picture and context of the examples.

+

Another, the demo-giver,

+
    +
  • shows the typing and does the examples,

  • +
  • might take the role of a learner who is asking about what is going on, to actually explain the details, or to comment occasionally.

  • +
+

Hands-on demos and exercises work especially well like this.

+
+
+

Presenter and interviewer

+

In this case, one is the presenter who is mostly explaining (including demos or examples), and trying to move the forward through the material.

+

Another, the interviewer,

+
    +
  • serves as a learner or spotter,

  • +
  • fills in gaps by asking relevant questions,

  • +
  • tries to comment to the presenter when things are going off track.

  • +
+

This can be seen as closer to classical teaching, but with a dedicated and prepared “voice of the audience”.

+
+
+

Exercise

+
+

Discuss the models of team teaching (10 min)

+

While in breakout rooms, discuss one of the basic team-teaching models presented here:

+
    +
  • Have you already tried this or similar model in your teaching?

  • +
  • Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best?

  • +
+

Write your comments in the collaborative document.

+
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Co-teaching focuses on complementing individual skills and strengths in teaching process.

  • +
  • Co-teaching may save time, reduce teachers’ workload and make lessons more interactive/ engaging.

  • +
  • Team teaching requires some adjustments in lesson preparation and delivery.

  • +
+
+
+
+
+

Sharing teaching gems

+
+

Objectives

+
    +
  • Our goal is to share our teaching tricks and tools and demonstrate them in +very short presentations/discussions.

  • +
+
+
+

Instructor note

+
    +
  • Demonstrations: 35 min

  • +
+
+

Here we encourage participants to take the screen share for 3 minutes and +demonstrate either some tool or trick they found useful for their teaching or +something from a course you liked.

+
+
+
+
+

Session 4 intro

+

This session covers streaming and technical production. Some +introductory notes:

+
    +
  • (As of 2024) This is the first and only comprehensive introduction +to our online streaming.

  • +
  • These practices are new and well-refined internally, but a +different kind of refinement is needed to teach and reuse them.

  • +
  • The lessons have outlines of what to talk about, but it’s just an +outline. It is not refined, since thees things are new. Many +things will have to be figured out as we talk.

  • +
  • This session is a demo of lots of basics.

    +
      +
    • Ask questions - otherwise it will be boring

    • +
    • If you want to use this in real life: you will need mentoring +sessions and active help. Contact us to do that.

    • +
    +
  • +
+
+

Warning

+

Audio and video weirdness

+

We are setting up video and audio recording, but also capturing that +for re-sharing it. There may be anomalies as video or audio +feedback. Please be prepared.

+
+
+
+

Why we stream

+
+

Objectives

+
    +
  • Learn the general history of CodeRefinery streaming.

  • +
  • Discuss the benefits of streaming and recording

  • +
  • Discuss the downsides and difficulties

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 10 min

  • +
  • Q&A: 5 min

  • +
  • Exercises: 0 min

  • +
+
+

This is a general discussion of the topics of the day, focused on the +history of why we stream and record, how we got here, and how people +feel about it. We won’t focus on how anything is done.

+
+

Icebreaker questions

+
    +
  • What is the most people you have taught for?

  • +
  • What are the distinct parts of teaching, that can be +separated? (teaching, helping, etc)

  • +
+
+
+

What is streaming and recording?

+
    +
  • Streaming is mass communication: one to many

    +
      +
    • Interaction audience→presenters is more limited (but different)

    • +
    +
  • +
  • Using consumer-grade tools, normal people can reach huge audiences +by Twitch/YouTube/etc.

  • +
  • This isn’t actually that hard: people with much less training than +us do it all the time.

  • +
  • They reach huge audiences and maintain engagement for long events.

  • +
+

Recording and rapid video editing is useful even without +streaming.

+
+
+

History

+
    +
  • In-person workshops

    +
      +
    • 3 × full day, required travel, infrequent, one-shot

    • +
    +
  • +
  • Covid and remote teaching

    +
      +
    • Traditional “Zoom” teaching several times

    • +
    +
  • +
  • Mega-CodeRefinery workshop

    +
      +
    • 100-person Zoom teaching

    • +
    • Emphasis on teams

    • +
    +
  • +
  • Research Software Hour

    +
      +
    • Livestream free-form discussions on Twitch

    • +
    +
  • +
  • Streamed “HPC Kickstart” courses

  • +
+
+
+

Benefits and disadvantages

+

Benefits:

+
    +
  • Larger size gives more (but different) interaction possibility

    +
      +
    • “Notes” for async Q&A

    • +
    +
  • +
  • Recording (with no privacy risk) allows instant reviews

  • +
  • Stream-scale allows for many of the things you have learned about in +days 1-3.

  • +
+

Disadvantages:

+
    +
  • Requires training for using the tools

  • +
  • Requires a certain scale to be worth it

  • +
  • Coordination is much harder for big events

  • +
+

When would I recommend it?

+
    +
  • No: For small courses

  • +
  • Questionable: Medium sized courses with no videos

  • +
  • Yes: When you want the largest audience

  • +
  • Yes: When you want without registration required

  • +
  • Yes: When you want good reusability/fast videos

  • +
+
+
+

Future prospects (briefly)

+
    +
  • Streaming probably stays as a CodeRefinery tool

  • +
  • We can scale our courses much larger than they are now. Why don’t +we, together with others?

  • +
  • These tools are useful in other places too

    +
      +
    • I’ve used them to record my own talks to make videos of my +single-person presentations or record conference talks nicer than Zoom.

    • +
    +
  • +
+
+
+

Q&A

+

Q&A from audience

+
+

Keypoints

+
    +
  • Streaming optimizes a course for different things

  • +
  • The disadvantages can be compensated for

  • +
  • There are benefits and disadvantages

  • +
+
+
+
+
+

Behind the stream

+
+

Objectives

+
    +
  • Take a first look at the broadcaster’s view.

  • +
  • Get to know what happens “behind the stream” of a workshop

  • +
  • See what the “broadcaster” sees and what they need to do.

  • +
  • Not yet: learn details of how to do this.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Q&A 10 min

  • +
+
+

In this episode, you’ll see an end-to-end view of streaming from the +broadcaster’s point of view. It’s a tour but not an explanation or +tutorial.

+
+

Who does what

+

We have certain role definitions:

+
    +
  • Broadcaster: Our term for the person who manages the streaming.

  • +
  • Director: Person who is guiding the instructors to their +sessions, changing the scenes, calling the breaks, etc.

    +
      +
    • Could be the same as broadcaster.

    • +
    +
  • +
  • Instructor: One who is teaching. They don’t have to know +anything else about how streaming works.

  • +
+

This lesson describes what the Broadcaster/Director sees.

+
+
+

Window layouts

+

What does the broadcaster see on their screen?

+
    +
  • What are the main windows you see?

  • +
  • What do each of them do?

  • +
  • Which ones do you need to focus on?

  • +
  • How do you keep all this straight in your head?

  • +
+
+
+

CodeRefinery control panel

+
    +
  • A custom application that controls scenes

  • +
  • Based on OBS-websocket (remote control connection for OBS - we’ll +learn about this later)

  • +
  • Can also work remotely, so that you can have a remote director

  • +
+
+
+

How scenes are controlled

+

What has to be done during a course?

+
    +
  • How do you start the stream?

  • +
  • How do you change the view?

  • +
  • How do you adjust things based on what the instructors share?

  • +
  • How do you coordinate with the instructors?

  • +
  • How do you know when to change the view?

  • +
+
+
+

Getting it set up

+
    +
  • How hard was it to figure this out?

  • +
  • How hard is it to set it up for each new workshop?

  • +
+
+
+

What can go wrong

+
    +
  • What’s the worst that has happened?

  • +
  • What if you need to walk away for a bit?

  • +
  • Someone broadcasts something unexpectedly

  • +
+
+
+

Alternatives

+
    +
  • Youtube vs Twitch

  • +
  • Zoom stream directly to YouTube/Twitch

  • +
  • Direct streaming platform, e.g. streamyard

  • +
+
+
+

Q&A

+

Q&A from audience

+
+

Keypoints

+
    +
  • The broadcaster’s view shouldn’t be so scary.

  • +
  • There is a lot to manage, but each individual part isn’t that hard.

  • +
+
+
+
+
+

Video editing

+
+

Objectives

+
    +
  • Get to know ways of quick video editing to be able to provide +accessible videos

  • +
  • Learn how video editing can be distributed and done the same day.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 20 min

  • +
+
+

Video recordings could be useful for people watching later, +but also are (perhaps more) useful for immediate review and catching +up after missing a day in a workshop. For this, they need to be +released immediately, within a few hours of the workshop. +CodeRefinery does this, and you can too.

+

Hypothesis: videos must be processed the same evening as they were +recorded, otherwise (it may never happen) or (it’s too late to be +useful). To do that, we have to make processing good enough (not +perfect) and fast and the work distributeable.

+
+

Primary articles

+ +
+
+

How this relates to streaming

+
    +
  • If you stream, then the audience can not appear in the recorded +videos

  • +
  • This allows you to release videos very quickly if you have the +right tools.

  • +
  • When you have a large audience, the videos start helping more +(review a missed day, catch up later, review later)

  • +
  • Thus

    +
      +
    • If you would never want videos, there may never be a benefit to +streaming

    • +
    • If you want videos, it gives motivation to stream.

    • +
    +
  • +
+
+
+

Summary

+
    +
  • Basic principle: privacy is more important than any other factor. +If we can’t guarantee privacy, we can’t release videos at all.

    +
      +
    • Disclaimers such as “if you don’t want to appear in a recording, +leave your video off and don’t say anything”, since a) accidents +happen especially when coming back from breakout rooms. b) it +creates an incentive to not interact or participate in the course.

    • +
    +
  • +
  • Livestreaming is important here: by separating the instruction from +the audience audio/video, there is no privacy risk in the raw +recording. They could be released or shared unprocessed.

  • +
  • Our overall priorities

    +
      +
    1. No learner (or anyone not staff) video, audio, names, etc. are +present in the recordings.

    2. +
    3. Good descriptions.

    4. +
    5. Removing breaks and other dead time.

    6. +
    7. Splitting videos into useful chunks (e.g. per-episode), perhaps +equal with the next one:

    8. +
    9. Good Table of Contents information so learners can jump to the +right spots (this also helps with “good description”.)

    10. +
    +
  • +
  • ffmpeg-editlist +allows us to define an edit in a text file (crowdsourceable on +Github), and then generate videos very quickly.

  • +
+
+
+

How we do it

+

The full explanation is in the form of the exercises below. As a +summary:

+
    +
  • Record raw video (if from a stream, audience can’t possibly be in +it)

  • +
  • Run Whisper to get good-enough subtitles. Distribute to someone for +checking and improving.

  • +
  • Define the editing steps (which segments become which videos and +their descriptions) in a YAML file.

  • +
  • Run ffmpeg-editlist, which takes combines the previous three steps +into final videos.

  • +
+
+
+

Exercises

+
+

Exercise A

+

These exercises will take you through the whole sequence.

+
+

Editing-1: Get your sample video

+

Download a sample video:

+ +
+

Editing-2: Run Whisper to generate raw subtitles and test video.

+

First off, install Whisper and generate the base subtitles, based +on the. Since this is probably too much to expect for a short +lesson, they are provided for you (above), but if you want you can +try using Whisper, or generating the subtitles some other way.

+

You can start generating subtitles now, while you do the next +steps, so that they are ready by the time you are ready to apply +the editlist. ffmpeg-editlist can also slice up the subtitles from +the main video to make subtitles for each segment you cut out.

+

Whisper is left as an exercise to the reader.

+ +
+
+
+

Editing-3: Create the basic editlist.yaml file

+

Install +ffmpeg-editlist and +try to follow its instructions, to create an edit with these features:

+
    +
  • The input definition.

  • +
  • Two output sections: the “Intro to the course”, and “From data +storage to your science” talks (Remember it said the recording +started at 11:35… look at the schedule for hints on when it +might start!). This should have a start/end timestamp from the +original video.

  • +
+

A basic example:

+
- input: day1-raw.mkv
+
+# This is the output from one section.  Your result should have two of these sections.
+- output: part1.mkv
+  title: something
+  description: >-
+    some long
+    description of the
+    segment
+  editlist:
+    - start: 10:00    # start timestamp of the section, in *original* video
+    - end: 20:00      # end timestamp of the section, in the *original* video
+
+
+ +
+
+

Discussion: what makes a video easy to edit?

+
    +
  • Clear speaking and have high audio quality.

  • +
  • For subtitle generation: Separate sentences cleanly, otherwise it +gets in a “stream of words” instead of “punctuated sentences” +mode.

  • +
  • Clearly screen-sharing the place you are at, including section +name.

  • +
  • Clear transitions, “OK, now let’s move on to the next lesson, +LESSON-NAME. Going back to the main page, we see it here.”

  • +
  • Clearly indicate where the transitions are

  • +
  • Hover mouse cursor over the area you are currently talking about.

  • +
  • Scroll screen when you move on to a new topic.

  • +
  • Accurate course webpage and sticking to the schedule

  • +
+

All of these are also good for learners. By editing videos, you +become an advocate for good teaching overall.

+
+
+

Editing-4: Run ffmpeg-editlist

+

Install ffmpeg-editlist: pip install ffmpeg-editlist[srt] (you +may want to use a virtual environment, but these are very minimal +dependencies).

+

The ffmpeg command line tool must be available in your +PATH.

+ +
+
+

Editing-5: Add more features

+
    +
  • Several chapter definitions.(re-run and you should see a +.info.txt file also generated). Video chapter definitions +are timestamps of the original video, that get translated to +timestamps of the output video.

    +
    - output: part1.mkv
    +  editlist:
    +  - start: 10:00
    +  - -: Introduction    #  <-- New, `-` means "at start time"
    +  - 10:45: Part 1      #  <-- New
    +  - 15:00: Part 2      #  <-- New
    +  - end: 20:00
    +
    +
    +

    Look at the .info.txt files that come out now. What is new in it?

    +
  • +
  • Add in “workshop title”, “workshop description”, and see the +.info.txt files that come out now. This is ready for +copy-pasting into a YouTube description (first line is the title, +rest is the description).

    +

    Look at the new .info.txt files. What is new?

    +
  • +
+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+
+
+

Editing-7: Generate the final output file.

+
    +
  • Run ffmpeg-editlist with the --reencode option: this +re-encodes the video and makes sure that there is no black point +at the start.

  • +
  • If you re-run with --check, it won’t output a new video file, +but it will re-output the .info.txt and .srt files. +This is useful when you adjust descriptions or chapters.

  • +
+
+
+

Discussion: how to distribute this?

+

Create a flowchat of all the parts that need to be done, and which +parts can be done in parallel. Don’t forget things that you might +need to do before the workshop starts.

+

How hard was this editing? Was it worth it?

+
+
+
+

Exercise B

+

This is a more limited (and older) version of the above exercise, +using an synthetic example video.

+
+

Use ffmpeg-editlist to edit this sample video

+

Prerequisites: ffmpeg must be installed on your computer +outside of Python. Be able to install ffmpeg-editlist. This is +simple in a Python virtual environment, but if not the only +dependency is PyYAML.

+ + +
+
+
+
+

See also

+ +
+

Keypoints

+
    +
  • Video editing is very useful for learning

  • +
  • Set your time budget and make it good enough in that time

  • +
  • Reviewing videos improves your teaching, too.

  • +
+
+
+
+
+

Open Broadcaster Software (OBS) introduction

+
+

Objectives

+
    +
  • Understand that OBS is a video mixer.

  • +
  • Understand the basic controls and features of OBS.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 15 min

  • +
  • Q&A 5 min

  • +
+
+ +

In this episode, you’ll get more familiar with the OBS portion of the +streaming setup. You’ll see how it’s used, but not yet how to +configure it from scratch. You’ll learn how to be a “director”.

+
+

What is OBS?

+
    +
  • Formally “OBS Studio”

  • +
  • Most commonly known as a livestreaming application.

  • +
  • Open source, free.

  • +
  • Cross-platform, easy to use screencasting and streaming application.

  • +
  • Real-time video mixer.

  • +
+
+
+

OBS user interface

+
    +
  • We’ll click through each view.

  • +
  • What does each view do?

  • +
  • Let’s click through the buttons.

  • +
  • Let’s see the important config options.

  • +
+
+
+

OBS during a course

+
    +
  • What management is needed.

  • +
  • The control panel.

  • +
  • Audio.

  • +
  • Adjusting windows and so on.

  • +
+
+
+

Hardware requirements

+
    +
  • Reasonably powerful broadcast computer

    +
      +
    • CodeRefinerys streaming computer is 8 CPU AMD, 64GB memory

    • +
    • That is way overkill: a powerful laptop can probably do this.

    • +
    +
  • +
  • Large second monitor for laying out the windows you capture

  • +
  • Stable internet connection (wired preferable)

    +
      +
    • CodeRefinery’s broadcast is the slowest purchasable: 100 Mbit down / +25Mbit up

    • +
    +
  • +
+
+
+

Q&A

+

We’ll answer audience questions.

+
+
+

See also

+ +
+

Keypoints

+
    +
  • OBS may seem complicated, but it’s a graphical application and most +pieces make sense once you know how it works.

  • +
+
+
+
+
+

Open Broadcaster Software (OBS) setup

+
+

Objectives

+
    +
  • See how to configure OBS using the pre-made CodeRefinery scene +collections

  • +
  • Modify the collections to suit your needs.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: ?? min

  • +
  • Hands-on: ?? min

  • +
  • Q&A: ?? min

  • +
+
+ +

In this lesson, we’ll see how to configure OBS from scratch for your +purposes. We’ll do this by deleting the instructor’s configuration +and trying to recreate it

+

This section is short, since it has never been done before: we’ll just +give it a short and update the lesson later.

+
+

CodeRefinery OBS configs

+
    +
  • CodeRefinery configs are shared in a repository: +https://github.com/coderefinery/obs-config

  • +
  • These can be imported to pre-configure some things

  • +
  • There are two types of configs:

    +
      +
    • Profiles

      +
        +
      • Servers, resolutions, audio, video, etc.

      • +
      +
    • +
    • Scene collections

      +
        +
      • The graphical layouts.

      • +
      +
    • +
    +
  • +
+
+
+

Installing the OBS config

+
    +
  • Clone the git repository.

  • +
  • Import the profile and scene collections under their respective +menus.

  • +
+
+
+

Initial setup

+
    +
  • Click through each menu and change anything that is needed

  • +
  • Set the streaming server

  • +
+
+

The instructor will go through the setup.

+
    +
  • Reset configuration: mv .config/obs-studio/ .config/obs-studio-old/

  • +
  • Import profiles/TeachingStreamingv3/

  • +
  • Import scenes/TeachingStreamingZoomv3.json

  • +
+
+
+
+

Set up the remote control

+
    +
  • Create a Python environment and install it: pip install https://github.com/coderefinery/obs-cr/archive/refs/heads/master.zip

  • +
  • Run it: python obs_cr/control.py localhost:4445 TOKEN --broadcaster

  • +
  • There are more options but let’s not cover them yet… and leave +this for a hands-on session.

  • +
+
+
+

Setup before each course

+
    +
  • Re-confirm audio

  • +
  • Re-confirm each scene

  • +
  • Test everything

  • +
  • rkdarst has a rather long +checklist, +but each individual step is short.

  • +
+
+
+

Q&A

+

We’ll answer audience questions.

+
+

Keypoints

+
    +
  • Most of our configuration has been OBS may seem complicated, but it’s a graphical application and most +pieces make sense once you know how it works.

  • +
+
+
+
+
+

What’s next?

+
+

Objectives

+
    +
  • Know next steps if you want to do streaming

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 5 min

  • +
  • Q&A 5 min

  • +
+
+

What comes next?

+
    +
  • We talked a lot about theory, and gave demonstrations.

  • +
  • Hands-on is very different. We recommend working with someone to +put it in practice.

  • +
  • +
+
    +
  • Work with someone who can show you the way

  • +
  • Use it for smaller courses with a backup plan

  • +
+
+

See also

+
+

Keypoints

+
    +
  • These lessons about streaming have been the theoretical part of +streaming training.

  • +
+
+
+
+
+
+
+

Collaborative notes archives from workshops

+
+

August/September 2024

+
+

Day1: Session 1 (13.08.24) - About lesson design, deployment and iterative improvement

+
+
:calendar: Schedule
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 10.00

Lesson design and development

10.15 - 11.00

8.15 - 9.00

10.00 - 10.15

Break

11.00 - 11.15

9.00 - 9.15

10.15 - 11.00

Lessons with version control

11.15 - 12.00

9.15 - 10.00

11.00 - 11.15

Break

12.00 - 12.15

10.00 - 10.15

11.15 - 12.00

How we collect feedback and measure impact

12.15 - 13.00

10.15 - 11.00

+
+
+
:icecream: Icebreaker
+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :Decaffed … and going strong …

  • +
  • :coffee: 🤔

  • +
  • :100: (ironically!) :coffee: intake happening

  • +
  • :smile:

  • +
  • :tired_face:

  • +
  • :coffee: :party:

  • +
  • :coffee: :happy:

  • +
  • 😪

  • +
  • just got zoom installed / before my coffee

  • +
  • :smil-

  • +
  • :sweat_smile: (+)

  • +
  • :yawning_face:

  • +
  • :is it morning already?

  • +
  • :smile:

  • +
  • :yawning_face:

  • +
  • :nerded_face:

  • +
  • 🥵

  • +
  • :smile:

  • +
  • :sleeping:

  • +
  • :sleepy: :coffee: :smiley_cat:

  • +
  • 🥳

  • +
  • :coffee:

  • +
  • :coffee:

  • +
+
+
+
Introduction in breakoutrooms.
+
    +
  • Name / Affiliation / Location

  • +
+
+
+
About teaching
+

What is the hardest thing about teaching for you?

+
    +
  • Knowing how “it’s going”, whether learners are happy or not (especially when teaching online) :+1:

  • +
  • The preparation the night before. It is always much more that I would hope, no matter how prepared I want it to be :+1: :+1:

  • +
  • Managing groups with vastly different academic backgrounds

  • +
  • Teaching wide spectrum of skill level at the same time. :+1: :+1: :+1: :+1:

  • +
  • Time management! (Knowing how much can fit in a sessions) :+1: :+1:

  • +
  • General preparation time, how to fit it into the regular work schedule, and estimate how much time is needed for prep.

  • +
  • How to reduce too much text into just the right amount

  • +
  • Preparation of the session material and estimating the right amount of time for each section

  • +
  • Getting learners to take the first step: sign up for and attend a workshop, when they don’t think programming is a skill they can learn

  • +
  • Getting learners to take the second step: translating what they’ve learned in a workshop into something they can apply

  • +
  • preparation and time management

  • +
  • Engaging with the students which was much easier for me when I used to coach

  • +
  • Finding the right depth for an unknown audience for “my topic”

  • +
  • education background of participants and their learning objectives

  • +
+

What is the best thing about teaching for you?

+
    +
  • Seeing when learner gets interested/curious about something and takes inspiration from the course. :+1:

  • +
  • Seeing it works and someone can do something new.

  • +
  • Motivated students grasping new stuff

  • +
  • Students picking up and running with the matertial and skills I give them and using it for their own work. :+1:

  • +
  • The “ah-ha!” moment when a student gets it! :+1::100: :+1:

  • +
  • Learning from students who know about some topic more than you do. :+1:

  • +
  • Being able to help people reach their goals, by showing them something new.

  • +
  • Teaching is optimism acted out in the hope of making a difference both ways I suppose.

  • +
  • The feeling of accomplishment when you see learning grow and implement the learnings :book:

  • +
  • mutual learning and impact on learners :+1:

  • +
  • Results and feedbacks / Mutual interests and interesting discussions

  • +
  • mutual learning and I can also learn lots of things and new ideas from participants

  • +
+
+
+
+
:question: Questions
+
+
General / Practicalities
+
    +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms? I’m not in a place where I can talk, so if we’re going to talk a lot I’ll need to move offices

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    +
  • +
  • +
+
+
+
Episode 1: Lesson design and development
+

Materials: https://coderefinery.github.io/train-the-trainer/lesson-development/ +Discussion:

+
    +
  • When you start preparing a new lesson or training material, where do you start?

    +
      +
    • I look at existing materials on the same topic, but chose/refine topics based on the perceived needs/interests of the presumed audience

    • +
    • Outline of structure and Material collection for a new lesson :+1:

    • +
    • What material I have already? (what other material is already out there?)

    • +
    • Start by looking for related resources (documents, videos, courses, etc) to have a base data and better understanding of what have been done around the topic

    • +
    • Know your audience

    • +
    • Review existing material

    • +
    • Think about learning objectives (to keep focus on essential things)

    • +
    • Think of three things simple enough that they will be remembered the next day. Design around that.

    • +
    • I write down the thoughts that I have and then go back and structure it.

    • +
    +
  • +
  • What tricks help you with “writer’s block” or the empty page problem?

    +
      +
    • Write anything down that comes to mind, sometimes draw something, looking out the window :)

    • +
    • Do a mind map - what concepts do I want to get across?

    • +
    • Starting small, for example a list of headings and then building around it. :+1:

    • +
    • What does one know about the target audience and why should they be spending longer than 1 minute listening to what they will eventually get to hear?

    • +
    • Get some inspiration from another source.

    • +
    • Start with the three things above

    • +
    • Start with the plan and the overview design

    • +
    • Some kind of outline / main message(s)

    • +
    • Start with three things. Three supporting points for each of these.

    • +
    +
  • +
  • Maybe you haven’t designed training material yet. But how do you start when creating a new presentation?

    +
      +
    • Think about the learning objectives and try to break them down into steps

    • +
    • Title, Objectives, target audience and Plan

    • +
    • Some kind of outline / main message(s). Get as many images as I can, instead of words

    • +
    • Draft an outline and use chatgpt to fill in details

    • +
    • Example of how the teaching content is applied in a real-world context

    • +
    +
  • +
  • If your design process has changed over time, please describe what you used to do and what you do now instead.

    +
      +
    • I look more at existing materials and try to get more information about the audience. Unfortunately getting information about the audience before the event is hard

    • +
    • I used to start from the begginning and get from there but that often meant a very polished start and a rushed end. Now I try an overview first, then fil out sparsed details at every section

    • +
    • Updating the data and tweak the presentation

    • +
    • If I am teaching a small group (or one to one) talk to them before hand - find out what they know already, what they want to learn.

    • +
    +
  • +
  • What do you know now about preparing lessons/training/presentations that you wish you knew earlier?

    +
      +
    • less is more. It’s better to have 2-3 main messages rather than trying to show everything in one go :+1: :+1: :+1: :+1:

    • +
    • how much practice time the learners need to master what’s taught

    • +
    • Don’t worry about something going wrong. It often makes the lesson (and thus the material) more presistent in memory. :+1:

    • +
    • Try and remove everything except what you want the person to learn

      +
        +
      • That’s a very tough part for me in the sense that I never know how much of an underlying “black box” is still ok….

      • +
      +
    • +
    • Designing intermediate materials is hard, and requires putting some “gatekeeping” making sure that learners are directed to appropriate courses

    • +
    • When I see a cool graphic, concept, slide, etc., download it and save it in my ‘new-materials’ folder to use later on!

    • +
    • I have come to the conclusion that perhaps a more “agile” approach to developing materials (try to do design/teaching iterations quickly) might be the best way to go, but there are risks with this approach too

    • +
    +
  • +
+

Questions

+
    +
  • From zoom chat: Can you expand on what a learner persona is?

    +
      +
    • A defined example person described in terms of the materials you are preparing, making up a story about the background and interest of t

    • +
    • Answer from chat: A learner persona is a blackbox which has a very simple algorithm inside: GIGO.

    • +
    • Answer from chat: I think it’s the same as ICP (Ideal customer persona) where you describe the learner as a customer

    • +
    • Answer from chat: I’m a big fan of “How Learning Works” by Ambrose et al https://bookshop.org/p/books/how-learning-works-eight-research-based-principles-for-smart-teaching-michele-dipietro/18640868?ean=9781119861690

    • +
    • See also book: Teaching tech together

    • +
    +
  • +
+
+

CodeRefinery lessons: https://coderefinery.org/lessons/

+
+
    +
  • From chat: Do you have an example of an instructor guide?

    + +
  • +
  • From zoom chat: Do you have a “measure” of how better are the new lesson compared to the old ones? Does it make sense to talk about measurements here?

    +
      +
    • So far we only have daily feedback that we collect at the end of the day and we can compare that to earlier daily feedbacks. More about that in the last episode of today. But measuring this is indeed not easy and it also takes time to capture the effect during longer-term surveys. Some of the changes were more leap-of-faith than based on data.

    • +
    • I guess that sometimes one can use “compelling arguments” instead of data to justify a decision

    • +
    +
  • +
  • Software Carpentry does teach using the command line, and gives a session on the command line before. What do you think about this approach? Are you stating that a 3-hour lesson about CLI is not sufficient to make people comfortable enough to use that for version control?

    +
      +
    • Yes, good question. For CR we consider it a more advanced step: we do think people should learn command line, but it’s for a different course. We accept some people might not know it or want to know it so adapt to that.

    • +
    • In general, we’ve found the “you need X, but have to learn A, B, and C first” approach should be avoided if possible: people are busy, try to reach people where they are.

    • +
    +
  • +
+
+

Exercise in breakoutrooms

+
+
    +
  • Room 1

    +
      +
    • Research data management

    • +
    • Objectives

      +
        +
      • Research life cycle

      • +
      • FAIR principles (Findable, Accessible, Interoperable, Reusable)

      • +
      +
    • +
    • Exercise

      +
        +
      • develop a data management plan (DMP) that outlines how their research data will be handled throughout its lifecycle.

      • +
      +
    • +
    +
  • +
  • Room 2: What is the difference between eating breakfast and sitting through a lecture? (Tip: Start by listing the similarities …)

  • +
  • Room2 : Making papers in LaTeX +- What is LaTex and how is it different from editors like Word +- Basic Structures +- How to find and use a template +- Including figure & table +- How to use references and labels +- Exercise: to create a new LaTeX document & edit it +- Excercise: common error messages: can you find the error in this code? +- Exce

  • +
  • Room 3

    +
      +
    • GPU Programming (1 hour intro)

    • +
    • Learning objectives:

      +
        +
      • What is GPU programming.

      • +
      • When is it usable, beneficial to use GPU programming?

      • +
      • What are technologies to do GPU programming?

      • +
      • [What are and how to manage typical issues]

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • Git / Figures / Project management / data cleaning

    • +
    • Chose data cleaning

    • +
    • Three learning objectives:

      +
        +
      1. What do we mean by “clean”? How to identify it?

      2. +
      3. Identify some common problems in a dataset

      4. +
      5. Identifying and handling missing values/fields

      6. +
      +
    • +
    • Exercise

      +
        +
      1. Discuss problems, find the most common ones

        +
          +
        • In small groups

        • +
        • What problems have you run into with datasets you’ve worked with?

        • +
        • What problems can you imagine, or have you heard about from colleagues/news/social media?

        • +
        • Report back, instructor collects all problems into a list

        • +
        +
      2. +
      3. Have a dataset to clean; a clean and a messy example

        +
          +
        • (identifying) Using a visualisation or overviewing tool?

        • +
        +
      4. +
      +
    • +
    +
  • +
  • Room 5

    +
      +
    • Jupyter Notebooks

    • +
    • Learning Objectives

      +
        +
      • Can setup an enviroment you can reuse / can share with others / a project.

      • +
      • The order you run the commands in needs to match the order of the code in the Notebook - otherwise you end up in a pickle.

      • +
      • Why use a Jupyter Notebook? What are the advantages? Easy to use environment.

      • +
      +
    • +
    • Exercise

      +
        +
      • Print variable assignments from different cells - show that the order you run the code is important.

      • +
      • hand out a domain specific notebook that does some calculations and visualization to run and modify, to show that you can share easily

      • +
      • show !pip install to add dependencies/features

      • +
      +
    • +
    +
  • +
  • Room 6

    +
      +
    • Using GitHub without the command line

    • +
    • Learning Outcomes:

      +
        +
      • Be able to discuss changes before merging changes into the main repository.

      • +
      • Publish a personal repository page ( I think its called intro repository)

      • +
      • Share their script/notebook/code/small data on GitHub

      • +
      • Homepage using GitHub pages or the README that becomes the “index page” of the GitHub user account page

      • +
      +
    • +
    • Learner personas:

      +
        +
      • Check the Personas of the learners

        +
          +
        • Somebody who has seen/heard of GitHub but hasn’t used it yet

        • +
        • Someone using it for their own work but struggling with collaboration

        • +
        +
      • +
      +
    • +
    • Exercises:

      +
        +
      • Upload/share an example dataset or script

      • +
      • Review another collaborators pull request.

      • +
      • Take part in the discussion on a pull request.

      • +
      +
    • +
    +
  • +
  • Room 7 +Linux shell basics: why do we want to teach them? +(this took most of the time for the discussion)

    +
      +
    • Learning objectives:

      +
        +
      1. Filesystem: Directory (CLI) - Folder (GUI) analogy

      2. +
      3. Basic commands (which commands are basic? make a survey of shell histories and get the most common ones)

      4. +
      5. Basic constructs (e.g., for loops, pipes, while loops… which ones are basic? See above)

      6. +
      +
    • +
    +
  • +
+
+

Note from chat: Zoom timer: https://support.zoom.com/hc/en/article?id=zm_kb&sysparm_article=KB0068677

+
+
+
+
Episode 2: Lessons with version control
+

Materials: https://coderefinery.github.io/train-the-trainer/lessons-with-git/

+

Poll options: I want to hear about:

+
    +
  • A: Why use version control for teaching materials

  • +
  • B: Different template options

  • +
  • C: How CodeRefinery does it; CodeRefinerys lesson template

  • +
+

Poll vote (multi-select): add a o to your answer +- A: ooo +- B: oooooo +- C: oooooooo :ghost:

+

Question to audience: if someone wants to make a tiny fix to your material, how hard is it?

+
    +
  • If my material is only in pdf format which is not online, then it is hard.

  • +
  • I hope it is easy - my material is in GitHub. Nobody has ever done that though!

  • +
  • Slides: hard to find, easy to edit; Git repos somewhat easy, unless they have to be built locally or with an action; HackMD easiest to edit.

    +
      +
    • if you use something like google slides they are not that difficult to find

    • +
    • known permanent address. Google docs et al fail on that/same for many pads.

    • +
    +
  • +
  • For this material today - very easy! e.g. https://github.com/coderefinery/train-the-trainer/pull/128

  • +
  • Template with an edit button in the HTML pointing to the source-code in the repo.

  • +
+

Questions/Discussion topics

+
+

Upcoming CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/ +Please share with your networks, and let us know if you would like to co-teach a lesson (to support@coderefinery.org or in our Zulip chat)

+
+
    +
  • Changes to the material are sometimes not just tiny fixes. For example, one wants to present a slightly different selection of topics, but maybe some topics are “coupled” (perhaps naturally or perhaps just because of how they are presented), or change the general “theme” (e.g., life sciences vs theoretical physics) while keeping the actual topics the same. How could a lesson be developed to avoid having to do a huge rewrite?

    +
      +
    • You can try to modularize your material and keep non topic specific parts non themed. E.g. where you explain the functionality, don’t make reference to the example (not simple), so the example can be changed depending on the audience.

    • +
    +
  • +
  • What are the pros/cons of renaming a course / changing a repo name in GitHub?

    +
      +
    • It should be relatively unproblematic since GitHub will forward to the new name.

      +
        +
      • How long does Github keep the “old” name linked? Is there a max time it’s blocked, or changed as soon as a new one appears with the name?

        +
          +
        • in my experience it forwards “forever” until I create a new repo with the old name which will break the forward

        • +
        +
      • +
      +
    • +
    +
  • +
  • what should be in the readme for the git repo? (canonical address? contact points? license!)

    +
      +
    • https://coderefinery.github.io/mini-workshop/2/documentation/#often-a-readme-is-enough-checklist

      +
        +
      • I miss the url to the (main) repo in the readme

        +
          +
        • Do you mean the link to the rendered (lesson) page?

        • +
        +
      • +
      +
    • +
    • Link to rendered page: We often have this in the “about” section of the readme (see up right: https://github.com/coderefinery/train-the-trainer)

    • +
    • this gets lost in a fork, doesn’t it? so 20 folks forking and or reuploading the repo somewhere means the url gets lost?

      +
        +
      • True, but they might want to have their own version rendered?

        +
          +
        • yes, I have had issues finding and contributing to the “master” repo so all benefit. Else it gets cluttered. Both is valid

          +
            +
          • Good point though, the link to rendered page should probably also be included in the readme for completeness; ah and the link to the repository too, yes

            +
              +
            • so realistically we need a content folder and some more next to the readme as a best practice. sounds good!

            • +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • Is myst (markdown renderer) enabled by default in sphinx now?

    +
      +
    • to my knowledge no. we add the “myst_parser” extension to conf.py.

    • +
    +
  • +
+
+

Cicero: https://cicero.readthedocs.io/ +Sphinx documentation: https://www.sphinx-doc.org/en/master/ +Carpentries workbench for creating Carpentries lessons: https://carpentries.github.io/workbench/ +This is the testing lesson Richard showed: https://coderefinery.github.io/testing/ +And the corresponding repository: https://github.com/coderefinery/testing +You can lean back and watch, exercise coming in a bit :) +Richard will now edit our train the trainer material repository: https://github.com/coderefinery/train-the-trainer +The Sphinx extension for CodeRefinery lessons: https://github.com/coderefinery/sphinx-lesson +Empty lesson template to build your own lesson: https://github.com/coderefinery/sphinx-lesson-template

+
+

More questions

+
    +
  • Does the coderefinery.org page built on sphinx?

    +
      +
    • It’s built also from markdown but it uses https://www.getzola.org/ (which is more optimized to render websites, but we could do teaching also with Zola or create the project page using Sphinx)

    • +
    +
  • +
  • Is there a way to build and preview CR lessons without the command line?

    +
      +
    • The GitHub workflow we use creates HTML from all branches. This means that one can push a branch to GitHub, preview it there, and then open a pull request. One thing that would be nice but we don’t have yet is if a bot automatically posts the link to the preview to a pull request.

    • +
    +
  • +
  • For VCS-2, for the Carpentries Linux shell example, Lesson, Github repo, to me it seemed as though the Sandpaper setup they have makes a very nice interface, complicates the relationship between source and output. E.g on the soucre page https://github.com/swcarpentry/shell-novice/blob/main/index.md I could only see to ‘Prerequisits’ and not ‘Download files’ on the page https://swcarpentry.github.io/shell-novice/. Perhaps I have missed something?

    +
      +
    • I am sorry I don’t know the new Sandpaper setup well enough to answer this question.

    • +
    +
  • +
  • Do we have the instructions to build the lessons available somewhere to try out later?

    +
      +
    • https://github.com/coderefinery/sphinx-lesson

    • +
    +
  • +
+
+

Exercise VCS-1 (and VCS-2 (if time)) (https://coderefinery.github.io/train-the-trainer/lessons-with-git/#exercises) in breakoutrooms until xx:05

+

then short summary in main room and then break.

+

Use the notes below. Collect a list of lesson formats and discuss what you like about each of them.

+
+
    +
  • PDF slides by a presentation program

  • +
  • pdf slides with beamer in latex under source control.

  • +
  • Markdown slides via Github

  • +
  • CodeRefinery template

  • +
  • Carpentries template

  • +
  • Google Slides

  • +
  • git-book

  • +
  • Jupyter Book - allows creating a structured reference website using RST/Markdown, including Jupyter Notebooks to show result of running code

  • +
  • mdbook - create simple/minimal website using Markdown

  • +
  • Binder - allows learners to run their own live version of a github repository with Jupyter Notebooks, with only a web browser

  • +
  • Jupyter notebooks and jupyterhub platform

  • +
  • Jupyter + Nbviewer and custom css (read only) + Binder link (hands on)

  • +
  • RMarkdown

  • +
  • Quarto Slides

  • +
  • Reveal.js - write slides in HTML (also supports markdown)

    +
      +
    • Example: https://bl-presentations.erambler.co.uk/2024-02-21-idcc24/

    • +
    +
  • +
  • Remark.js - write slides in markdown

    +
      +
    • Example: https://bl-presentations.erambler.co.uk/2024-02-19-idcc-pids-workshop/

    • +
    +
  • +
+

Room discussions:

+
    +
  • Room 1

    +
      +
    • (https://smc-aau-cph.github.io/SPIS/README.html)

    • +
    • CodeRefinery template

    • +
    • Shared notes & blogs

    • +
    +
  • +
  • Room 2

    +
      +
    • demo the exercise

    • +
    +
  • +
  • Room 3

    +
      +
    • Mix of JupyterLab, Terminal within that, and traditional slides

    • +
    • Jupyter + RISE (benefit: slides that are editable and executable live)

    • +
    • Challenges

      +
        +
      • present code in an interactive way

      • +
      • handle lots of images/ figures without too much additional overhead when setting up the material

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • Material and tools depend on instructors

    • +
    • Some slide building tools

      +
        +
      • https://revealjs.com/

      • +
      • https://remarkjs.com/

      • +
      • https://github.com/rust-lang/mdBook

      • +
      +
    • +
    • Using flat git repos without fancy styling to make it easier to edit but still version controlled

    • +
    +
  • +
  • Room 5

    +
      +
    • Using R as a GIS: https://github.com/nickbearman/intro-r-spatial-analysis

      +
        +
      • Workbook: RMarkdown, Slides: Quarto

      • +
      • No continuous intergration

      • +
      +
    • +
    • Having a jupyter nbinder link to test the notebook

    • +
    • repo lives on codeberg in this example

    • +
    +
  • +
  • Room 7

    +
      +
    • Ex 1:

      +
        +
      • Sphinx, similar to CR

      • +
      • Sometimes pdfs generated with beamer package (or from pptx and odt), but blows up repository size if in version control

      • +
      +
    • +
    • Ex 2:

      +
        +
      • Content

        +
          +
        • CR: Content commonly found int the content folder

        • +
        • SC: Mostly under episodes

        • +
        +
      • +
      +
    • +
    • Question that came up:

      +
        +
      • is CR/Sphinx approach mostly for technical topics? What about language.

      • +
      • I guess by our nature it’s focused there. But probably could be used for others (I guess it it’s much easier to use git in a technical audience.)

      • +
      +
    • +
    +
  • +
+
+
+
Episode 3: How we collect feedback and measure impact
+

Materials: https://coderefinery.github.io/train-the-trainer/feedback-and-impact/

+

Questions to audience

+
    +
  • What tricks/techniques have you tried in your teaching or seen in someone else’s teaching that you think have been particularly effective in collecting feedback from learners?

    +
      +
    • preparing a survey and emailing it to participants as soon as the event ends (usually get <50% of answers but it’s a representative enough sample)

    • +
    • do engage with the audience, give them the time to get the courage to speak up

    • +
    • Be the audience yourself

      +
        +
      • yes! some problems/issues I don’t notice as instructor, only as listener

      • +
      +
    • +
    • Have time (e.g. 5 min) in the session to fill out the feedback form

    • +
    • If the course/workshop has several days/sections do a couple questions every change, then a full one afterwards

    • +
    • “Traffic light” feedback (e.g. for pacing or progress on exercises): give each learner two different coloured post-it notes for in-person, or use emoji for online, to indicate a current status

    • +
    +
  • +
  • Can you give tips or share your experiences about how to convert feedback into changes or actionable items?

    +
      +
    • ask questions about things you know you don’t know

    • +
    • “Don’t let the noise of others’ opinions drown out your own inner voice.” — Steve Jobs

    • +
    +
  • +
  • When people ask questions / get stuck with a specific step. Is there a typo I can change there and then in the workbook?

    +
      +
    • Being able to fix small things on the fly helps sometimes, otherwise open issues if working on github

    • +
    • If multiple people have the same question, then this is an indication that I should look at this in more detail

    • +
    +
  • +
  • How do you measure the impact of your teaching? Any tips or experiences about what you have tried or seen other courses do?

    +
      +
    • “How likely are you to recommend this workshop to others? (0/5)”

    • +
    • Check the ‘Garbage Out’ bin, what you find there will be what went across. The rest will be history…

    • +
    +
  • +
  • Anybody knows of good resources on survey design? Please link them here.

    +
      +
    • “Our job is to figure out what they’re going to want before they do… Our task is to read things that are not yet on the page.” - Steve Jobs

    • +
    +
  • +
+

Questions/Discussion points

+
    +
  • Feedback is necessary to design good lessons. Improvement can only be done iteratively. So the faster the iteration (design/teach), the better. But on the other hand, I cannot constantly bomb our community with training event emails. So I would like to try proposing a course many times a year, but I don’t want to spam everybody many times a year.

    +
      +
    • :+1:

    • +
    • With CR we also have a calendar that can be imported to different calendar applications, where we add all workshops: https://github.com/coderefinery/calendar/

    • +
    +
  • +
  • Does an even split of too fast / too slow mean speed is about right?!

    +
      +
    • I take it to mean “it’s roughly where it should be”. Would be better to accomdate the sides better though… (we do try to design for a broad audience: some easy stuff, some advanced stuff, so people can make their own path)

    • +
    • It could also indicate that the prerequisites/scope are not well defined :+1:

      +
        +
      • Based on long term surveys we also know though that even though the workshop might have been to fast, people appreciate having “heard things before and know where to find them later”

      • +
      +
    • +
    • perhaps the even split between too fast/too slow is ok only if the majority of votes goes for “just right” :+1:

    • +
    +
  • +
  • One of the most important disciplines in journalism is to challenge your working premises. (Bill Keller) This applies equally to learning as well.

    +
      +
    • Participants can be encouraged to write some posts on LinkedIn. If it is helpful some blurbs can be created for pre and post-workshop to generate more traction for Code Refinery and future participation.

    • +
    • Ask participants if they use Dev.to, hashnode etc to blog their work or use twitter etc to have a memory of their work.

    • +
    +
  • +
  • Do you have any suggestions for prerequisites? I try to make them clear, but occasionally people attend who clearly do not meet them. :+1:

    +
      +
    • I guess it depends how much it matters for the workshop itself. If you have group exercises etc, it probably matters? , lecture style maybe not so much?; important is that the participants themselves know that prerequisites exist and if they meet them

    • +
    • Sometimese people that do not meet the prerequisites join to get to “know what they don’t know”, find out where to find information on topics they might get interested in future etc

    • +
    • Other suggestions? Viewpoints? :)

    • +
    • Thank you - things for me to think about there :-)

    • +
    • With CR’s latest ideas, we try to make the prerequisites clear, but there is no capicity limit: it’s OK if people drop by and are less than prepared: it’s livestream, anyone can come. We try to have something for these people, too: learn what you are missing, why you might want to study more in the future.

    • +
    • Any thoughts on applying this to a more practical focused course, with a total capacity limit (i.e. not like CodeRefinery).

    • +
    +
  • +
  • Everytime you do a course on CodeRefinery, think of it as trying to bake a new cake with an old recipe with no idea about the individual taste preferences of the one you bake the cake for. Then, you will not experience too many surprises. Fine-tuning the recipe for one cohort still remains the ‘old recipe’ as far as the next ‘new cohort’ will be concerned. C’est la vie.

    +
      +
    • nice analogy!

    • +
    +
  • +
  • Question from chat: For examples 2 & 4, would you also consider using something like a Likert scale? E.g. Rate how well you agree with the statement “My code is more reusable as a result of attending a CodeRefinery workshop” (from 1 Strongly disagree to 5 Strongly agree)

    +
      +
    • Thanks! I am new to Likert scale and will read up on it. In my experience numbered answers can be useful for reporting. But I also like questions where we ask for what actually to change.

    • +
    +
  • +
  • Comment from chat: Richard, your point crowns the point of having CodeRefinery, With Radovan’s and Samantha’s acquiescence assured, I would like to suggest you wear a crown going forward, especially for the CodeRefinery session. Do we have a deal ?

    +
      +
    • I don’t quite understand this

    • +
    • I think it’s a tongue-in-cheek-comment (joke) but I am not sure…..

    • +
    +
  • +
  • What is the ideal way to allow people to interact while course is going on in the main online session, i.e. without a breakout room? Taking a pause or discussion in the background?

    +
      +
    • I’ve had some success with WhatsApp groups for a course - particually ones that run over 4 (or 2) sessions.

    • +
    • A quick survey/quiz

    • +
    • Question to the audience that we take time to answer but it helps to show the answers

    • +
    +
  • +
+
+
+
+
+
+

Wrapup

+
    +
  • Thank you for active participation :)

    +
      +
    • We’ll continue answering questions after the workshop and make the cleaned up (no names etc) available from the materials

    • +
    +
  • +
  • Next session Tuesday August 20, 9 CEST: Tools and techniques adopted in CodeRefinery workshops

    +
      +
    • we will talk about on-boarding, install help, roles, screensharing, sound, collaborative notes

    • +
    +
  • +
  • All workshop materials will stay available (after the full workshop also on Zenodo :tools:)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • If you want to co-teach with us in the upcoming (or next) CodeRefinery workshop (https://coderefinery.github.io/2024-09-10-workshop/); or just want to learn more about this opportunity: Send your name and e-mail address to support@coderefinery.org; we will contact you!

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • Lesson design approach

  • +
  • I liked the backwards lesson design, gives a name to a practice I’ve already been doing :+1: :+1:

  • +
  • Lessons from code refinery on lesson design. Learning about Sphinx.

  • +
  • Collaborative notes and anonymized archive of notes.

  • +
  • it’s nice to have a community to discuss these kinds of problems

  • +
  • Hearing the variety of tools people use for slides (PDF, Quarto, Beamer etc.)

  • +
  • Good intro of the tools, the jargon and the pedagogical philosophy of teaching tech.

  • +
  • The absolute openess in having everything publicly available - materials ofc but also questions, discussions, feedback, …

  • +
  • Thinking about all content being available publicly and as a git repo

  • +
  • Thanks for explaining the HedgeDoc interface, with view and edit options

    +
      +
    • Is there anyway to come back to this document later (e.g. tomorrow) and see what has changed since now? So I can see if any other questions have been asked/answered?

      +
        +
      • There is a “revision” point under “Menu” up right, which shows you different versions of this document

      • +
      +
    • +
    +
  • +
  • Modesty: the gentle art of enhancing your charm by pretending not to be aware of it. - Oliver Herford

  • +
  • +
+

What one thing would you improve about this session?

+
    +
  • Perhaps some more interactivity but can be hard to plan and time

    +
      +
    • We’ll see what we can do.

    • +
    +
  • +
  • Maybe mix the breakout groups up for each breakout session (although there are advantages to consistency too) :+1:

    +
      +
    • yes, pros and cons! For me, having consistency worked well this time.

    • +
    • Likely we will have different participants next week, and a bit of mixing will happen naturally.

    • +
    +
  • +
  • The pace of the presentations could be a little tighter (the pace is good for a discussion though)

  • +
  • Richard’s voice was only 80% audible

    +
      +
    • Sorry to hear that. It seemed fine on my end. Will check better for next session.

    • +
    +
  • +
  • Hands on simulation and collaborative notes

  • +
  • I found it difficult to follow the presentation and the collaborative notes at the same time

    +
      +
    • We will highlight the collaborative notes more in the next session. Our strategy usually is to say to focus on the “teaching part” and use the notes only when needed. Since you can go back and also check the notes later.

      +
        +
      • My problem is that I want to follow both since I don’t want to miss out on anything. As such, I have both windows (zoom and the notes) open side-by-side. Since there is near-constant real-time typing in the editor, and as such visible movement on screen, I get constantly distracted. This makes following the event quite exhausting.

      • +
      +
    • +
    +
  • +
  • Heads up to participants on using the break out rooms on voice interaction and screen sharing.

    +
      +
    • Do you mean that we should have mentioned it more clearly in the pre workshop email?

    • +
    +
  • +
  • I found it hard to follow with so many things going on at once…

    +
      +
    • A collaborative document being changed at the same time as…

    • +
    • Someone speaking and explaining content at the same time as…

    • +
    • Chat in a different application at the same time as…

    • +
    • Content changing in a termin application.

      +
        +
      • Thank you for the feedback. We will remove the Zoom chat out for the next session and explain the use of the collaborative notes more.

      • +
      +
    • +
    +
  • +
  • Make more use of defining and then making sure the learning objectives are met

    +
      +
    • True we did not talk about them much, will pick that up better for next session.

    • +
    +
  • +
  • UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. - Dennis Ritchie. You need to do a lot to prove that to be wrong, simply put.

  • +
  • Allocate some time for learners to type in the answers so that we don’t have to listen and type at the same time.

  • +
+

Any other comments?

+
    +
  • It’s great to hear other people’s experience

    +
      +
    • Good to hear :)

    • +
    +
  • +
  • Looking to meet you onsite if there are any events and get more emails from you :)

    +
      +
    • We will keep you informed :)

    • +
    +
  • +
  • Thanks for putting this together, I got a lot of inspiration for my own courses

    +
      +
    • Good to hear :)

    • +
    +
  • +
  • I didn’t know where to ask questions. It would work best for me to do it in zoom chat as that’s the application that I’m watching in..

    +
      +
    • Sorry for that, just to figure out why: Did you join a bit late?

      +
        +
      • No. Perhaps I just missed that or it was too quick for me or something?

        +
          +
        • Ok, sorry. Will try to make this more clear in next session.

        • +
        +
      • +
      • Perhaps also because there were so many things going on and jumping around. For me, the zoom chat is the constant (and obvious) place to ask questions while watching a shared screen, trying to find the right place in a moving collaborative document is difficult. It tears my attention into too many pieces. :+1:

      • +
      +
    • +
    +
  • +
  • Had a lot of content that assumed extant knowledge that I didn’t have. This wasn’t in the pre-requisites.

    +
      +
    • Do you have examples?

      +
        +
      • Yes! The code refinery templates and even just the way of doing that. I was expecting more on “when designing a lesson you should think about these steps” rather than this is how we do it and this is our tool for doing it. I guess I should have read the pre-workshop content better?

      • +
      • Ok, thank you for your feedback. You are right that we actually had some content that for sure would have been easier to follow for people with background knowledge about a certain topic.

      • +
      • “If you are in CodeRefinery TTT, you probably know what version control is and why it is important.” - extant knowledge, why not just add a sentence or two?

        +
          +
        • Please can you update in preparation for the next workshops so that I can decide whether or not they will be right for me?

          +
            +
          • Yes, we will think more thoroughly about this and send the info in the next email going out Wed/Thu

            +
              +
            • Thank you!

            • +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • Lots of the content was relevant to code refinery but not the wider topic (e.g. it was how to design a code refinery lesson and not how to design a lesson as stated in the session title)

    +
      +
    • We thought of the content of showing one way of doing things, ie “what we have learned”, if you have suggestions on how we could make that more clear on the event page, please let us know :)

      +
        +
      • “in a code refinery lesson” in the lesson/workshop description?

      • +
      +
    • +
    +
  • +
  • When you have pre-written “thank you for your active participation” it feels fake!

    +
      +
    • He, that is true, did not think about that. Thank you for the feedback. I would not have added it if Radovan and Richard would not have provided good feedback from circling the rooms.

    • +
    +
  • +
  • I found it vague and disorganised and difficult to follow. It felt like the instructors were presenting the content for the first time and didn’t know what to do next.

    +
      +
    • Thank you for your feedback. This is not the first time we have this training, but it is the first time in this constellation/way. The way of teaching may also sometimes make it seem new to instructors.

    • +
    +
  • +
  • I really liked the active exchange with other participants, but I also would have enjoyed a bit more technical content in the presentations. In a sense it felt less like a ‘training’ and more like a get-together :+1:.

    +
      +
    • Thank you for your feedback. We thought the name “workshop” would combine the training and exchange nature of this event. But maybe it didn’t do so enough? Do you have suggestions on how to clarify it on the event page?

      +
        +
      • Well, the ‘train the trainer’ title created the anticipation of being trained ;) don’t get me wrong, I liked the exchange, but I felt that the training aspect fell a little short. imho the workshop would benefit from a little more (instructional) content that is presented in a more structured way by the instructors (as opposed to ‘crowd-sourced knowledge’ that is collated in a loose collection of questions, notes and links)

      • +
      • Other than that, you could add another section on the main page, sth like ‘Workshop structure: we aim for a mix of modular presentations and work in small groups. The latter will be done in breakout rooms - be prepared to switch on your camera and have a fruitful exchange with fellow participants!’

        +
          +
        • Thank you for the suggestions, will add something like this :tools:

          +
            +
          • +

            Added : https://github.com/coderefinery/train-the-trainer/commit/03308595436e636b3bb37ed9d1f0dee39eeccd0f

            +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • My understanding (so far) of what (unlike the competition) CodeRefinery DOES NOT seek to exemplify - +https://images.ctfassets.net/rxqefefl3t5b/2k45BFtw4sBMlBfjr1OZ90/5c6ecd3628a43b0cdc79815f665e224a/Screenshot_2023-05-02_at_09.35.23.png?fl=progressive&q=80

  • +
  • My understanding of what (unlike the competition) today’s session of CodeRefinery DID exemplify - Definition of ‘Workshop’ from the Oxford dictionary of the English language “a period of discussion and practical work on a particular subject, in which a group of people share their knowledge and experience”

  • +
  • In my experience, even for the most seasoned Programmer coding, by its very nature, is nothing trivial, this being a simple straightforward fact just like there is no such thing as an egg which is a cube. I mean there is a reason why not just about everybody is a poet either. But, other minds have pointed this out without having to first explain why the universe is what it is in a way that could be understood without effort … https://i.pinimg.com/originals/7b/7e/c4/7b7ec4b91d2cf9d8e1b064678d205467.jpg

  • +
  • The inclusive environment feels very welcoming. Keep up the good work!

  • +
+

Thank you all for your feedback! Highly appreciated!

+
+
+
+

Day 2 : Session 2 (20.08.24)- Tools and techniques adopted in CodeRefinery workshops

+
+
:calendar: Schedule
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 9.25

About CodeRefinery workshops

10.15 - 10.25

8.15 - 8.25

9.25 - 9.55

Collaborative notes and interaction

10.25 - 10.55

8.25 - 8.55

9.55 - 10.10

Break

10.55 - 11.10

8.55 - 9.10

10.10 - 10.45

Workshop overview, roles, onboarding

11.10 - 11.45

9.10 - 9.45

10.45 - 11.05

Sound

11.45 - 12.05

9.45 - 10.05

11.05 - 11.20

Break

12.05 - 12.20

10.05 - 10.20

11.20 - 11.50

How to prepare a quality screen-share

12.20 - 12.50

10.20 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+
:icecream: Icebreaker
+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :-)

  • +
  • https://media.istockphoto.com/id/148421550/vector/bored-emoticon.jpg?s=612x612&w=0&k=20&c=uo5KBTqdJZbBQb_Xldhzuovx5t08fHfGR7dw7TCk90I=

  • +
  • :saluting_face:

  • +
  • :sleepy:

  • +
  • :coffee:

  • +
  • :umbrella:

  • +
  • :cocktail: :coffee:

  • +
  • :seedling:

  • +
  • :tired_face:

  • +
  • :sun_with_face:

  • +
  • 🥴 (:woozy_face: not converted?)

  • +
  • :coffee:

  • +
  • :sunflower: :book:

  • +
  • :satisfied:

  • +
  • :coffee:

  • +
  • :coffee:

  • +
  • 🥱:tired_face:

  • +
  • :bread: - I am baking bread today so I have been kneading dough while listening!

  • +
+
+
+
Introduction in breakoutrooms
+

Name / Affiliation / Location

+
+
+
Teaching
+
    +
  • Do you teach and organize teaching alone or with others? What would you prefer and why?

    +
      +
    • Coming together is a beginning; keeping together is progress; working together is success. – Edward Everett Hale

    • +
    • These days always with others. Alone is easier to prepare but almost always is harder during it.

    • +
    • Teaching with very diverse partners, it can be challenging to find a common language with people very different than you.

    • +
    • I teach alone, in the future there will be more collaboration with multiple team members. Both approaches have their pros and cons.

    • +
    • Both has its own distinct advantages

    • +
    • Most of my teaching is on my own, as a freelancer its more expensive to work with colleagues than to deliever a course on my own.

    • +
    • Teaching together, learns from each other, feedbacks to improve

    • +
    • Not formally taught yet, only given presentations actually .

    • +
    • collective teaching would benefit the teachers with collaborative curriculumn and experiences sharing.

    • +
    +
  • +
  • If applicable, have you seen any challenges when teaching together and how to overcome them?

    +
      +
    • It actually requires preparation,

    • +
    • Is it about teaching or about inspiring ? Discover the answer and get inspired …

    • +
    • It’s like being in a band: you might be great at improvising and your band-partners might be great at improvising too, but a bit of rehearsing makes even the impro gig much better

    • +
    • Need to plan before session, difficult if people don’t ‘plan’ in the same way, e.g. with the same time frame.

    • +
    • Heterogeneity in learners make it impossible to get the same result from everyone.

      +
        +
      • In fact, the same applies to teachers :D

      • +
      +
    • +
    • Teaching together requires to have similar opinions on how to teach. I share vews only with ~40% of my colleagues I think.

    • +
    +
  • +
  • No Teaching experience but it is good to give the outline of the lessons beforehand and learning goals.

  • +
+
+
+
+
+
:question: Questions
+
+
General / Practicalities
+
    +
  • What is this document for?

    +
      +
    • Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts)

    • +
    +
  • +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms?

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    • BR 1 : The Zoom chat does not work for the breakout room so we should take note of that. No webcam/mic = expect silence.

      +
        +
      • Thanks for notifying! This was not intended. Turned the chat back on.

      • +
      +
    • +
    +
  • +
+
+
+
+
+
Episode 1: CodeRefinery
+

Materials: https://coderefinery.github.io/train-the-trainer/coderefinery-intro/

+
    +
  • (questions continue here)

  • +
  • Is there the plan to build capacity / be paid to deliever courses?

    +
      +
    • We’ve discussed it but right now we don’t have many people who could accept money to do this (and maybe shouldn’t, because of their jobs). But, we would encourage others to use our materials as “independents” to deliver paid courses

    • +
    • One idea we have had is that paid courses could be delivered through the DRA (link below), who we know. Basically, DRA could find instructors and handle the money transfers (If someone wanted a paid course, we could help find someone to do it through DRA or independently)

    • +
    • :smile:

    • +
    +
  • +
  • Have you come across DRA, https://digital-research.academy/, Heidi Seibold, Joyce Kao who are doing similar work? I can connect you if you like.

    +
      +
    • Yes we have been discussing about possible future collaborations and are already sending possible clients their way (we, as a project cannot take money) :+1:

      +
        +
      • Excellent! :-D :smile:

      • +
      +
    • +
    +
  • +
  • .

  • +
+
+
+
Episode 2: Collaborative Notes
+

Materials: https://coderefinery.github.io/train-the-trainer/collaborative-notes/

+
    +
  • So anyone can type anonymously?

    +
      +
    • Yes, as long as you do not log in, you are Guest XXX

    • +
    • And at least in our hedgedoc case you cannot log in so you will always be anonymous. You can do [name=xxx], to add your name to a comment

    • +
    +
  • +
  • Test of +1

    +
      +
    • +1 :+1: :+1:

    • +
    • :-1: a test

    • +
    +
  • +
  • You are hosting your own version of HedgeDoc, and Hackmd.io is a similar (free) option. What are the limitations of the free hackmd.io? Should each center install their own HedgeDoc instance?

    +
      +
    • It seems the free version of HackMD has gotten worse lately. It works still well enough with a few people editing at the same time.

    • +
    +
  • +
  • Have there every been problems with the anonymity and CoC?

    +
      +
    • We haven’t had any issues so far.

    • +
    • With a different anonymous tool in a bachelor course, we had issues with anonymous participants (participants were posting slurs and unsafe links). The course organiser decided to stop allowing anonymous tools.

    • +
    +
  • +
  • Why not google documents?

    +
      +
    • Google documents are actually setting a hard limit for simultaneous writing, no more than 100 concucurrent editors. I am unsure if microsoft onedrive word documents would allow more users writing at the same time.

    • +
    +
  • +
  • What’s the most people you have every had on HackMD / Hedgedoc?

    +
      +
    • I believe about 200 active participants?

    • +
    +
  • +
  • What are your thoughts on using the build-in Zoom Q&A?

    +
      +
    • We haven’t tried this, in part because the way we do streaming now (you’ll see in session 4), participants aren’t in Zoom so don’t have access to that. The doc-format works pretty well though, when we keep it in this limited “write at end” format.

    • +
    +
  • +
  • How do you see what has changed? e.g. if leave the session at the end, can I come back tomorrow and see X has been added? e.g. a diff for this maybe?

    +
      +
    • In the menu up right there is revision, it does show the document and changes at different time step :+1: Thanks!

    • +
    • We recommend people only write at the bottom (and since we answer things live), so as a first level approximation you find where you were and read below that. Think of it more like chat than a full document. (Yes, we do revise questions at the end)

    • +
    +
  • +
  • How about flinga boards or similar tools?

    +
      +
    • My take is that the simplicity of a simple text document wins over free-form in-person-workshop-like tools.

    • +
    • There’s miro, can be a bit confusing though

    • +
    +
  • +
  • How does this work with small groups, e.g. 10-15 people?

    +
      +
    • Good question: it can be hard if people aren’t rigorous about it, people start only using chat/voice. So there seems to be some lower bound in size but we haven’t tested this much

    • +
    • And if the instructors never screenshare it to show what goes on it, then seems to be less used.

    • +
    • And if there aren’t other people to read/answer it during the session (perhaps less likely in a small course), it seems to be less used.

    • +
    +
  • +
+
+

Breakoutrooms until xx:55

+

Exercise/discussion: https://coderefinery.github.io/train-the-trainer/collaborative-notes/#exercise

+
+
    +
  • Breakout room 1:

    +
      +
    • Use of etherpad for collaborative discussion.

    • +
    • Use of slido for polling and quizzing.

    • +
    • Presemo as a slido alternative (https://www.aalto.fi/en/services/presemo-a-fully-web-based-classroom-participation-system)

    • +
    • Use of text based approach for questions rather than live can be helpful if there is a language barrier issue.

    • +
    +
      +
    • A good teaching session which had many questions coming spontaneously to the teacher is a non-entity of sorts. If the overall flow of feedback / questions increases it could indicate that the session will not prove to be a helpful experience. A signal that generates noise is, well, noise, if calling a spade a spade signals anything. Note that the ‘overall’ bit and the ‘to the teacher’ aspect are important. Both the best and the worst teaching session have two things in common: a teacher, and the fact that NO Materials of any kind are used, ie speech is the only channel of communication via a common language. The only difference is that it is not the same teacher, at least not in the same session at the same time.

    • +
    +

    Another less mentioned, but perhaps more relevant indicator of a great session is the simple fact that at the end of the session EVERYONE feels empowered, NOT tired. This is not an easy to quantify thing, but screams out the quality of the experience loud. More often then not, such sessions differ little from each other, apart from in terms of the theme / topic and the participant mix. It ends up being the ‘keep your cake and eat it too,’ of sorts, not quite the far less amusing post-bombardment devastation scenario in the wake of a take it or leave it go at anything.

    +
      +
    • profanity in collaborative documents where people can add content anonymously could be a problem (happens very rarely, fortunately and somewhat surprisingly)

    • +
    +
  • +
  • Breakout Room 2:

    +
      +
    • Good experiences with Zoom polls

    • +
    • Handling questions in hybrid setups: all participants (on-site and online) ask questions in written form

    • +
    • Collaborative notes can be challenging when conducting a course alone (without teaching assistants) :+1:

    • +
    • Providing a method to ask questions anonymously can make asking easier for shy participants

    • +
    • Questions can give valuable feedback on how the course is going

    • +
    • Online collaborative whiteboarding platforms such as Miro

      +
        +
      • Large monitors are useful for this not to have to drag a “periscope” around

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • good experience with whatsapp chat for questions. since most learners have the app already and one thing less to install and set up

      +
        +
      • reply to question is a way to handle multiple questions at the same time but it works well for smaller groups

      • +
      +
    • +
    • experience with collaborative docs in in-person workshops: voice questions might “win” over the document

    • +
    • “seeding” questions may help to not have an empty document

    • +
    • it can help somebody to start and create a structure which helps others to see and follow

    • +
    • we discussed the Carpentries sticky notes system (red sticky note: signal tech issues and use for feedback, green sticky note: signal that exercise worked and for positive feedback)

      +
        +
      • Nice summary of sticky notes system: https://teachtogether.tech/en/#s:classroom-sticky-notes :+1:

      • +
      +
    • +
    • What is the success rate of in-person workshops after COVID? Discussion: Teachers prefer in person and learners prefer remote or recorded to spool back and relearn.

    • +
    +
  • +
  • Room 5

    +
      +
    • Good experience with Collaborative tools as HackMD and HedgeDoc while teaching with no bad feedback

      +
        +
      • When used with smaller groups works best as one-way, like sharing links with students and so on

      • +
      • Needs to be done as a team, quite difficult if teaching alone

      • +
      • Most useful when online/hybrid

      • +
      +
    • +
    • Anonymisity is important for transparent feedback and no biasis in classrooms

    • +
    • Not very collaborative but useful to share history or jupyter notebooks live https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush

    • +
    • Used Flinga before that seems like Figma and also onsite teaching using sticky notes

      +
        +
      • There’s miro.com but can be a bit confusing, more for brainstorming than for teaching

      • +
      +
    • +
    • Using quizzes apps like Kahoot is beneficial while teaching to have more engaging students

    • +
    • +
    +
  • +
  • Room 6

    +
      +
    • teaching teenagers (in presence) but using shared pad becomes quickly very chaotic, so only usable for short moments when answering very precise questions

      +
        +
      • Yeah, I can imagine. For CR we try to keep it in this very limited format (all questions bullet points, only add to the end) and I think that helps.

      • +
      +
    • +
    • using shared notepad for small workshop (5-10 people) to explore common thematic (mainly technical) to keep a shared notes and condense aftwerward (and publish on wiki to archive)

    • +
    • Difference between teaching in person and online. Some people prefer in-person and sometimes you have no option but to organise it online.

    • +
    • There are sometimes cultural differences and learners feel shy to ask / question the knowledge of the Teacher, so shared notes are a good way to safely ask questions.

    • +
    +
  • +
+

Questions continue:

+
    +
  • Have we demonstrated how we do polls in HedgeDoc? Add your vote by adding an o

    +
      +
    • yes: oooo (in session 1)

    • +
    • no:

    • +
    • :smile:

    • +
    • not sure: o

    • +
    +
  • +
+
+
+
Episode 3: One workshop, many perspectives
+

Materials: https://coderefinery.github.io/train-the-trainer/overview/ +Next CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/

+
+

Exercise until xx:39

+

https://coderefinery.github.io/train-the-trainer/overview/#discussion

+
+
    +
  • Room 1

    +
      +
    • Send pre-workshop email with pre-requisite instructions on what should be set-up beforehand.

      +
        +
      • But, also mention that if help is needed for set-up, we will be ready before the session officially starts.

      • +
      +
    • +
    • Discussion on whether we push to work in a pre-ready environment (e.g. Binder, Colab) or in their own environment.

    • +
    • Lots of help needed both before and after.

    • +
    • Installations: as much as we can provide ready made environments for the learners, maybe installations will be something that the learners will face sooner or later. Maybe one should teach more about installations?

    • +
    • My only cherished role in a teaching-learning session is the that of one who is living the moment as if there were no tomorrow. What cuts all ways really is that “By failing to prepare, you are preparing to fail.” ― Benjamin Franklin. A helpful motto: “When one teaches, two learn.” — Robert Heinlein. The best experience cannot be given, it can only be allowed to flow its way, so get out of its way.

    • +
    +
  • +
  • Room 2

    +
      +
    • Frequently, a single person fills all the roles for a single or multi-day workshop

    • +
    • Collaboration with different centers/ universities can be challenging

    • +
    • Preparing participants: it’s essential for the instructor to go through the demos and be sure that they will work (no unpleasant surprises live). This can be extended to advance-prep for participants.

    • +
    • Best experience is to hear (live or in feedback notes) some positive things directed at you :)

    • +
    • Fully prepared environments (eg self-hosted JupyterHub) can make preparation for participants easy

    • +
    +
  • +
  • Room 3

    +
      +
    • Some students have problems with setuping the environment. Maybe having a step by step instructions could help. But some students don’t want to “start” the course before hand.

    • +
    • Preparing the environemnt before hand ensures everyone is onboard from day 1. The same thing happend in CSC training sessions and another session Peng attended.

    • +
    • Had experience in attending as teacher and student in previous workshops

    • +
    +
  • +
  • Room 4

    +
      +
    • knowing the background of the audience is helpful

      +
        +
      • Try and ask in advance of the background of the audience. Do a poll at the start of the workshop. In person one can do it interactive.

      • +
      +
    • +
    • among co-instructors: discuss topics and flow

    • +
    • if more people are involved, it can help changing roles from time to time to see different perspectives

    • +
    • preparation is key

    • +
    • Circulate instructions beforehand

      +
        +
      • Do a poll before session: Have you installed (QGIS) successfully?

      • +
      • Push hard to do this in the welcome email

      • +
      +
    • +
    • communicate clearly to the participants

    • +
    • +
    +
  • +
  • Room 5

    +
      +
    • We’ve all taken most roles

    • +
    • How to prepare in advance?

      +
        +
      • Meet and discuss once or twice

      • +
      • Make a pre-survey to check for interest and background

      • +
      • Going through the materials

      • +
      • Checking the toolkit (zoom)

      • +
      • Agree on the reponsibilities and back-up plans (bit of scenarios planning)

      • +
      +
    • +
    • How to prepare trainings in advance?

      +
        +
      • Collect resources and prepare the workshop plan

      • +
      • Having the material readily available online ans sharing it

      • +
      • Making a pre-survey

      • +
      +
    • +
    • What was the best workshop experience for you as learner, helper or instructor? What made it great?

      +
        +
      • learner

        +
          +
        • Engaging and practical workshop with more exercices and follow-up theoretical part explanations

        • +
        +
      • +
      • helper

        +
          +
        • When the instructor is well prepared and as helper ther’s only typos to fix and interesting questions to answer

        • +
        • Assist the instructor, coordinate the collaborative notes, and make sure that the time is respected

        • +
        +
      • +
      • instructor

        +
          +
        • I have a colleague whom I’ve ran the same workshop a few times already, goes quite smoothly now and we’ve made a few changes. Hard to reach that point with new colleagues but getting there

        • +
        • Students/participants were engaging with the material and many good feedback collected even some of them asked for the next workshop

        • +
        +
      • +
      +
    • +
    +
  • +
  • Room 6

    +
      +
    • What has made a great experience for you as a learner/helper/instructor?

    • +
    • Common ground between learners & teachers

      +
    • +
    • Motivation

      +
        +
      • Teaching is much more enjoyable when the learners want to be there

      • +
      • I spend a lot of time at the start of a workshop making sure learners feel that the content is possible for them to understand and master

      • +
      +
    • +
    +
  • +
+

Poll: I have joined a CodeRefinery workshop before: (add an o for your answer)

+
    +
  • yes (within last 2 years): ooooooo

  • +
  • yes (longer time ago): oo

  • +
  • no: oooooooo

  • +
  • +
+

(questions would continue below:)

+
    +
  • What is the motivation / advantages of streaming workshop versus using zoom?

    +
      +
    • We’ll cover this more in week 4, but roughly: zoom became unmanageable and essentially quiet once things got big. Streaming allowed “one to many” communication with no limit, and collab notes allowed better interaction anyway. By separating the rooms, it was more pleasant to teach. Videos could be released immediately since there was no risk of privacy of participants. There could still be in-person/online small groups who have “watching parties.”

    • +
    +
  • +
  • What are the blue red and green font colors here, does it symbolify anything or just a convention HedgeDoc uses?

    +
      +
    • Visual separation of formatting, mostly. (It helps to quickly realize you’ve missed/ mistyped a control Markdown symbol etc.)

    • +
    • Yeah, it’s bascically “code highlighting” for markdown. No special meaning but quite convenient for us.

    • +
    +
  • +
  • Is this next workshop only for team leads or also open for helpers and coordinators?

    +
      +
    • You mean the next session of this workshop or the upcoming “CodeRefinery workshop”(this one: https://coderefinery.github.io/2024-09-10-workshop/)?

      +
        +
      • The upcoming workshop coordinators are alredy working, but can be joined if you are interested

      • +
      • As helper roles we currently only have “collaborative notes helper”, which is all about helping to answer questions in the collaborative notes

      • +
      • We do have some co-teaching slots open :)

      • +
      • If interested: join the discussion in our chat: https://coderefinery.zulipchat.com/#narrow/stream/316508-coderefinery-tools-workshop/topic/Fall.202024.20CodeRefinery.20workshop

      • +
      +
    • +
    +
  • +
  • Can a person have multiple roles in a workshop as a helper and a teacher?

    +
      +
    • Yes, many teachers also contribute to the rest of the workshop by answering questions in collaborative notes. :+1:

    • +
    • Some teachers also host a local classroom in week one and do their teaching in week two of the workshop

    • +
    • Roles that do not go well together are broadcaster/director/host and instructor (goes well until there is a problem; co-teaching solves that partly)

    • +
    +
  • +
+
+
+
Episode 4: Sound
+

https://coderefinery.github.io/train-the-trainer/sound/

+
    +
  • To me, Richard is a bit quieter than the other two :+1: :+1: :+1:

    +
      +
    • to elaborate: I think that the audio coming from him is missing some mids

    • +
    • Do you have any links about this kind of evaluation and adjustment?

    • +
    +
  • +
  • Do you suggest / recommend a specific headset(s) with mounted microphone?

    +
      +
    • in our experience headsets with a microphone will almost always be better than a separate microphone sitting on the desk or in the monitor

    • +
    • +
    +
  • +
  • Speakers have different tones of voice and speaking styles, is there a recommendation or experience from CR workshops for how this is adjusted and catered to environemnts for listeners?

    +
      +
    • Yeah, people’s voices are different and we haven’t gone as far as voice training or improving.

    • +
    +
  • +
  • How to change the volume for speakers? Tried Zoom settings and system settings and didn’t help.

    +
      +
    • From linux I can use different pulsemixers pavucontrol, pulsemixer to set the gain to above 100%. I’m not sure the equivalent on other OSs but

    • +
    +
  • +
+
+
+

Exercise until xx:10 +https://coderefinery.github.io/train-the-trainer/sound/#exercises

+
+
    +
  • room 1

    +
      +
    • Practically, no typical headset is designed or can capture the technical purity of human voice within its natural environment. But one needs to understand the polar pattern of the (specific) microphone or how much of the signal will be picked up by the microphone from different directions, a sine qua non when it comes to mitigating unwanted sound sources to bleed into the signal.

    • +
    +
  • +
+

For best results, keep the right direction & distance to your (directional) mic. Usually, that’s between 15-30 cm to get get a natural sound. A microphone records everything it can, also silence, so check the headphone output BEFORE adjusting the gain, in some specific cases aim for a dry sound, ie the influence of the room or how audible the room is on the recording ! Finally, adjust the mix between dry and room sound, or change the frequency response in tandem using a compressor to reduce the dynamic range of a signal for a more consistent listening experience = the quietest parts of your signal will appear louder by reducing the loudest parts.

+

It is all about one thing and one thing only - love your voice, let people fall in love with the acoustic quality of your charm. So remember: GIGO, it matters!

+
    +
  • Room 3

    +
      +
    • Had different headsets and we could see the difference (bluetooth low quality)

    • +
    • How to change the volume?

      +
        +
      • It’s surprisingly hard to get more control than the basic slider you see in the apps! You need to look.

      • +
      +
    • +
    +
  • +
  • room 4

    +
      +
    • headset is probably better listening experience but they can be uncomfortable to wear during long meeting days :+1:

      +
        +
      • Yeah. Luckily only instructors

      • +
      • Therefore breaks are non-negotiable

      • +
      +
    • +
    • loud keyboard can be an issue

    • +
    • if one has a silent room that does not echo, it can be ok to teach without headset

    • +
    • on Linux I am using pulsemixer to adjust levels and pavucontrol to change outputs/sources

    • +
    • mic modes on mac

    • +
    • check default microphone for zoom.

    • +
    +
  • +
  • room 5

    +
      +
    • Most tricks help tuning yourself but hard to do it as a group. Perhaps doing a short recording.

      +
        +
      • Yeah. Some independent recording/playing aronud, but also asking for advice. I would do small group/one-on-one things.

      • +
      +
    • +
    • Background noises cancellation tools or wise choice of quiet environments

    • +
    • Audio check with colleagues or through the app with the audience saying numbers for example

    • +
    • Zoom or Teams have sound checks but work different in the app than the browser. They also work different across Operating systems

    • +
    • Some sound issues might be related to network speed or stability, also to RAM available. Worthwhile to try and control those as well

    • +
    • Make it welcoming for the audience to give you feedback on the audio and other settings, give reminders

    • +
    +
  • +
+
+
+
Episode 5: How to prepare a quality screen-share
+

Materials: https://coderefinery.github.io/train-the-trainer/screenshare/

+
    +
  • If your Zoom does not support “share portion of screen”, sharing a tab and resizing it to portrait for yourself is a possible workaround (this at least works when joining the call from Chromium browser)

    +
      +
    • Another workaround is to use an editor/IDE that displays multiple panels in one window and can show a web page, code files and terminal session +10

    • +
    +
  • +
  • Is ‘share a portion of your screen’ where you draw a box in Zoom to share a section?

    +
      +
    • yes :+1:

    • +
    +
  • +
  • When using zsh, one can run something like this in a terminal

    +
    tail -n $NLASTCOMMANDS -f ~/.zsh_history | sed 's/^.............../LAST COMMAND:/g'
    +
    +
    +

    (I place this in a window under the main terminal, I use i3)

    +
  • +
  • I am a bit confused on what platform you are putting this code?

    +
      +
    • Radovan is using Linux with (I think) the “i3 window manager”. It can be quite involved and there is lots of personal customization here.

    • +
    +
  • +
  • When teaching with a custom prompt, is it worth starting with the default (that your learners will see) and explicitly mentioning “I change these things to make it clearer when teaching”

    +
      +
    • One should always comment on what may be different. Thing is “default” may look different for many people :+1:

    • +
    • “I am not going to teach you how to customise your prompt, but here’s an online tutorial, be prepared to lose several days of your life…” :laughing:

    • +
    +
  • +
  • Now I can’t see the last line in the terminal

    +
      +
    • Yep, that’s a problem. It can be good to keep a buffer on the bottom of the screen.

    • +
    • If you move your mouse outside the Zoom window, the controls should go away. But still a good note.

      +
        +
      • My mouse was on another screen.

      • +
      • Ok, thanks.

      • +
      +
    • +
    • I think one can also make the zoom bars not auto-hide (then it won’t display under), but that is annoying also since it wastes space.

    • +
    +
  • +
  • Does anybody still use shellshare? Does it work?

    +
      +
    • We in CR haven’t used it much but we have seen it.

    • +
    +
  • +
  • Does the stacking of the screens work on windows?

    +
      +
    • Don’t know unfortunately

    • +
    +
  • +
+
+

Exercises (done together) +https://coderefinery.github.io/train-the-trainer/screenshare/#exercises

+

Write your cool tips and ideas below. +Stay after xx:00, to

+
+
    +
  • To be safe, I have created on my computer an account that I use only for teaching, so I do not need to do any manual set up

  • +
  • share history or jupyter notebooks live (5-10 secs refresh rate) into a git repo. Share the link with the learners so they can catch up https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush

  • +
+
+
+
+
+

Wrapup

+
    +
  • Next session Tuesday August 27 9 CEST: About teaching & cool things we all would like to share

  • +
  • All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • Cool gems session: If you want to share something, please edit your registration and fill it in there (link to modify in registration confirmation); or e-mail to support@coderefinery.org

  • +
  • If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14:00 (Europe/Stockholm time)

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • Sound and screen share optimization as well as relevant tools and good practices for online instruction. “While you may be unable to control your users’ mindset, you can anticipate it, and make sure that your user experience caters to it.” - Jonathan Cherki

  • +
  • Nice opportunity to (re)think about my online teaching setup :+1: :+1: :+1:

  • +
  • Other ways to display command history :+1:

  • +
  • Did not know that bluetooth gear had so much latency! :+1:

  • +
  • A good reminder about headsets with microphones

  • +
  • Nice and friendly teaching. Thank you!

  • +
  • Screen share with command history and terminal customisation

  • +
  • Really useful tips on sound and screen sharing :+1:

  • +
  • Nice experience share

  • +
  • very useful and practical tips!

  • +
  • Easy to follow along and filled with useful tips on sound, video etc.

  • +
  • +
+

What one thing would you improve about this session?

+
    +
  • Just digging to find something: I have read some of the things you have talked about here already in some blog posts, so perhaps these sessions are not as shokingly full of new content as I imagined (but actually sharing experiences is something I can’t do by reading a blog post)

    +
      +
    • Perhaps: could you link some blog posts or other sources for what you have discussed so far? If it makes sense. Not sure.

    • +
    +
  • +
  • Talking about interface optimization approaches, which applies to sound as much as to visuals or any other aspect either for that matter, it might offer a perspective to bear in mind the concept of introducing asymptotic complexity increment. The latter would mean the goal is measuring how fast the effort of engaging, on one or more of the three parallel levels of interaction, must change to reach higher levels of partial certainty on the correctness of the implementation of the method in question, in this case the pedagogical paradigm. For the former, lower is better I guess, or in this case, in the intended sense, slower is faster. Let us consider an abstract example: People liked using the search engine Google (a Google session to put it in a fancy way) in the early days because it was as simple as it could get, a literally featureless entry point with no bells and whistles. That was the level of its visible complexity, or rather Google set a bar as low as it one could have, and then any higher point of VISIBLE complexity that was to be introduced, such a move would only be on the path of an asymptotic curve curving towards the set bar, never reaching it, as far as the entry point is concerned. We still see the same level of complexity when we fire up google and we never feel distracted to start with, except for the rather forgivable nuisance of the GDPR conformity pop-up notice which appears only AFTER the first move has been made, and thankfully it works plain and simple from there on (unless one starts feeling lucky, pun intended). Now, think about Youtube … the user experience complexity is a totally different matter, the same company today (unfortunately) yet one now has a steadily worsening engagement experience. Good learning sessions tend to be more of the Google search engine experience and a far cry from the current Youtube trend I would opine. Or, to sum it up and keep it sweet and simple, it helps to identify the limits of human-human and human-technology interaction, within the framework of any applicable technology-technology interaction and joy is the result of respecting those limits. Wishful thinking ?

  • +
  • Bring the cat back!

    +
      +
    • I wish it came, but it’s been resting all morning! I don’t bother it or stage apperances…

    • +
    +
  • +
  • Maybe having a digest/ summary of previous iterations of this session might be interesting. I feel a lot of experiences have been exchanged and a lot of techniques/ tools have been mentioned. Spending some time in compiling this into a selected list and adding it as content to the course itself might be worthwhile.

    +
      +
    • Good idea! We will write a blog post about this workshop and will include a summary of all discussions there :)

    • +
    +
  • +
  • Possibly have some command line examples from Windows rather than (just) *nix? I will look at the screenshots after the session. :+1: :+1:

    +
      +
    • Also, a thought if you do do breakout sessions with this work, do one for Unix, one for Windows, one for Mac as an option.

    • +
    +
  • +
  • I could not follow the part Radovan showed codes (Radovan is using Linux with (I think) the “i3 window manager”.)

  • +
  • ..

  • +
+

Any other comments?

+
    +
  • Looking forward to the topics of following sessions.

  • +
  • Looking forward to the next sessions!

  • +
  • Thank you!

  • +
  • Relax, nothing else matters, live a life and have fun ! If you obey all the rules you may end up missing all the fun. ‘The best way to predict your future is to create it.’ - Abraham Lincoln :+1:

  • +
+
+
+

Day 3 : sessiion 3 (27.08.24) - “About teaching and cool things we all would like to share”

+
+
:calendar: Schedule
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 9.45

Computational thinking

10.15 - 10.45

8.15 - 8.45

9.45 - 10.00

Break

10.25 - 11.00

8.25 - 9.00

10.00 - 10.30

Teaching philosophies

11.00 - 11.30

9.00 - 9.30

10.30 - 11.00

Co-teaching

11.30 - 12.00

9.30 - 10.00

11.00 - 11.15

Break

12.00 - 12.15

10.00 - 10.15

11.15 - 11.50

Sharing teaching gems (voluntary)

12.15 - 12.50

10.15 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+
:icecream: Icebreaker
+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • +
  • :sleeping:

  • +
  • :coffee:+2

  • +
  • :robot:

  • +
  • Still little sleeppy :)

  • +
  • 🥴 (:woozy_face: still not converted 🤷‍♂️)

  • +
  • Our planet could be a cube. It has six sides to it. It must be a cube. A cube it is, this Blue Planet … just wondering …

  • +
  • 🦾

  • +
  • :sweat_smile:

  • +
  • computer says no :-) some network trouble

  • +
  • running late, and participating from a :train2:

  • +
+
+
+
Introduction in breakoutrooms
+

Name / Affiliation / Location

+
+
+
Best classroom experiences
+

As a learner or teacher; what was the best workshop/lesson/seminar you have attended? What made the experience great?

+
    +
  • Room 1

    +
      +
    • First summer HPC streamed workshop (as a teacher). Somehow the first felt the best

    • +
    • CSC HPC summer workshop

    • +
    • story telling teaching approach

    • +
    +
  • +
  • Room 2

    +
      +
    • NVIDIA DLI Course on Deep Learning

      +
        +
      • very enthusiastic instructor

      • +
      • intuitive and very accessible way of showing technical details and fostering deeper understanding

      • +
      • a lot of hands-on material and smaller coding exercises

      • +
      +
    • +
    • Anything as long as its interactive and somehow enjoyable from both teacher and learner sides

    • +
    +
  • +
  • Room 4:

    +
      +
    • EPCC MPI Distributed training workshop.

      +
        +
      • Lots of hand on coding / experience gained.

      • +
      • Very interactive instructor who also discussed ideas for more personalised cases of distributed computing.

      • +
      +
    • +
    • Coderefinery RSE course

      +
        +
      • relevance of topic to my current work.

      • +
      • Dynamic / friendly / positive teaching style.

      • +
      • Modular Code Development; very instructive

      • +
      +
    • +
    • Some CSC courses / LinkedIn learning courses

      +
        +
      • up to date materials and topics.

      • +
      • Good way to merge theory with practicalities without making learner feel bored (Example: Jonathan Reichental)

      • +
      • Challenging information to learn more and research about the topic

      • +
      • Trainers are the experts in the field

      • +
      +
    • +
    +
  • +
+
+

Episode on teaching gems

+

If you want to share or demo something about tools and techniques you have found helpful in your teaching, please add your name/initials and rough topic below for smooth transition.

+
+

Note: It does not have to be your tool or your idea, this episode is meant to share experiences and discover new things. You also do not need any slides or materials, a story will do fine :) +Length of the stories will be depending on interest, but be prepared to fit it into 3 min (shortest possible).

+
+ +
+
+
+
+
+
+

:question: Questions

+
+
General / Practicalities
+
    +
  • What is this document for?

    +
      +
    • Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts)

    • +
    +
  • +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms?

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    +
  • +
+
+
+
+
Episode 1 : Computational thinking
+

Materials: https://coderefinery.github.io/train-the-trainer/computational-thinking/ (Link to slides in the middle of material)

+
+
Questions to audience
+

How might breaking down a complex problem into smaller parts change your approach to problem-solving in your current projects?

+
    +
  • Avoids cognitive overload

  • +
  • I used to give an example about this in workshops of cutting long tree into pieces from top to avoid that it falls and destroy a house bloc.

  • +
  • Easier to start on something small

  • +
  • Each individual part is familiar and can take existing solutions.

  • +
  • Only focus on the new things

  • +
  • One can lose oversight of where is supposed to be getting to due to problems with summation of biases introduced during the solving of the parts.

  • +
  • .

  • +
+

Can you think of a research project where identifying patterns in your data led to new insights or breakthroughs?

+
    +
  • Multi-targeted drug design where you need to identify both chemical and biological pathways/patterns

  • +
  • Distilling complex physics problems into simpler 1D statistics is very often done.

  • +
  • I used to do bioinformatics, pretty much everything in biology is about patterns in strings of charachters (DNA, proteins). Finding those patterns and using them is the way to go

  • +
  • Pattern recognition DOES NOT lead to new insight, it is new insight which allows for the recognition of a ‘pattern’, the latter being an allocation of possible bias.

  • +
  • +
  • ..

  • +
+

What challenges do you face when trying to simplify complex concepts in your field, and how do you decide which details to focus on?

+
    +
  • Absence of a terminology / jargon to describe a new idea. :+1:

  • +
  • Similar to above, when teaching often students know what they want to achive, but don’t have the termonology to express it, so working through what they want is helpful, after teaching them some termonology.

  • +
  • Whatever is most useful to the learner first?

  • +
  • I work with researchers in different fields. I don’t always fully understand their domain knowledge but I can take the basiscs or generalities and get code that works for them

  • +
  • A very practical problem is trying to resist going for a coffee in the midst of taking a shot at a complex concept, in the hope that the true details are to be found in the coffee.

  • +
  • not all information is easy to find or a lot of conflicting information or even sometimes imformation explosion

  • +
+

How do you determine the priority of tasks when designing algorithms for your academic projects, and what criteria do you use to ensure that the most critical tasks are addressed first?

+
    +
  • Working chronologically when going through a problem - start at the beginning.

  • +
  • What gives the more insight with the least effort can be a nice start

  • +
  • Talk to colleagues and Subject matter experts to understand various perspective to decide and prioritize.

  • +
  • Logic will get you from A to B. Imagination will take you everywhere. - Albert Einstein.

  • +
  • ..

  • +
+
+
+
Questions from the audience
+
    +
  • About the 4 core concepts, is this based on the model of how human brain works and perceives vision / abstract ideas?

  • +
  • I don’t know if it’s based on how the brain works, but it’s related to creating a framework for solving programming programs that has been extrapolated to solve any other problem as well.

  • +
  • Devil’s advocate question: cooking (by recipe) actually employs all four principles outlined here and has done so since before the advent of computers. Why then is this concept presented as “computational”?

    +
      +
    • Random aside, this is an interesting connection to our “cooking metaphor to HPC”

    • +
    +
  • +
  • Devil’s answer to the Devil’s advocate: Great question, cooking, as far as the act happens in the Devil’s kitchen, does not employ numerical algorithms. The Devil introduced the computer precisely to make man lose apetite for that what is cooked in the Devil’s kitchen to be served to all. Only then can the Devil eat the cake and keep it too …

    +
      +
    • Well, an algorithm without numbers is still an algorithm, i.e. a set of rules :)

    • +
    +
  • +
  • Are there other names for this technique? I may have missed something crucial, but it strikes me as ‘logical thinking’ in a way.

    +
      +
    • Yes, you could also just see it as problem solving. Most people know how to do it and if you’ve worked with programming, you’ve probably applied it. It can be the case that it’s very obvious to some, but not to others.

    • +
    +
  • +
  • Any chance we can ge a link to the slides?

    +
      +
    • They are in the course material: https://coderefinery.github.io/train-the-trainer/computational-thinking/ :thumbs_up:

    • +
    +
  • +
+
+
+
Exercise questions to discuss
+
    +
  1. Conceptually would the strategies provided by computational thinking help you in completing tasks more efficiently?

  2. +
+
    +
  • Room 1:

    +
      +
    • divide and conquer technique

    • +
    • We discussed what happens if you don’t use these, since they are so natural

    • +
    +
  • +
  • Room 2:

    +
      +
    • in some cases yes, if the task is not too small

    • +
    • not sure if more efficiently but it does help at least getting strted

    • +
    • Computational thinking is an extension of what others have called solutionism: the belief that any given problem can be solved by the application of computation. Whatever the practical or social problem we face, there is an app for it. - James Bridle

    • +
    +
  • +
  • Room 3:

    +
      +
    • Helps in starting the task.

    • +
    • For many it is the normal way to do problem solving. Also in Agile & Scrum methodlogies.

    • +
    +
  • +
  • Room 4:

    +
      +
    • Yes, it helped me during my scientific research to manage multiple projects and research publications simultaneously.

    • +
    • +
    +
  • +
+
    +
  1. Do you think that the effectiveness of computational thinking depends on the person’s personality type?

  2. +
+
    +
  • Room 1:

    +
      +
    • yes, we agree it’s quite different. But good vision and motivation this can be effective

    • +
    +
  • +
  • Room 2:

    +
      +
    • yes, laying out all the steps necessary to achieve an overall goal can be very daunting; some people are not good at/ comfortable with following fine-grained instructions

    • +
    • once the problem is broken down, different personalities might choose different ways to tackle the parts

    • +
    • The degree to which something, that is a result of what one means by ‘Computational Thinking,’ is successful in producing a desired result, that is success, cannot be a function of personality.

    • +
    +
  • +
  • Room 3:

    +
      +
    • Yes. Different people have different ways to communicate.

    • +
    • Online tools vs pen and paper

    • +
    +
  • +
  • Room 4:

    +
      +
    • We are all agree that it depends on the personality type but it could be learned and trained

    • +
    +
  • +
+
    +
  1. Would this type of thinking be an option for you to integrate into your current workflow?

  2. +
+
    +
  • Room 1:

    +
      +
    • Yes; we didn’t know the name explicitly; but we use it

    • +
    • It’s quite important for

    • +
    +
  • +
  • Room 2:

    +
      +
    • I’m already doing it implicitly :smile: :+1: :+1:

    • +
    • Writing a program is like writing a song, its all about the tune, lyrics are merely the necessary nuisance a coder needs to put up with. The latter can, if so written, result in a lot of noise.

    • +
    +
  • +
  • Room 3:

    +
      +
    • Easy if you are working alone. But different team may have their own ways of working (inertia). One way would be then to gradually show the rest of the team its effectiveness.

    • +
    • https://teamtopologies.com/key-concepts

    • +
    +
  • +
  • Room 4:

    +
      +
    • We are using it in our daily life so it’s already an option for us, only the terminologies are a bit new.

    • +
    +
  • +
+
+
+
+
Episode 2 : Teaching philosophies
+

Materials: https://coderefinery.github.io/train-the-trainer/teaching-philosophies/

+

Questions to discuss:

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+
Breakout Room exercise
+
    +
  • Room1

    +
      +
    • Motivation

      +
        +
      • For best practices in teaching, learning from each other, collaboration

      • +
      +
    • +
    • Learning applied tech is like an apprecentiship: there is theory, but real learning happens by co-working with others.

    • +
    • Worse is better: teach what can be used more quickly and it can be improved later

    • +
    • +
    • I think there are two bits of teaching - teach the basics and terminology so people know what they want to know, and then teaching how to find out how to do things like Richard said - how to find answers yourself.

    • +
    • Using Jupyter notebooks - good for learning a technique, but not for learning the basics.

    • +
    • Possibly command line usage has a branding problem - “programming other programs”?

    • +
    • the skills we learn in CR training are expected to stay , it is not exam oriented

    • +
    +
  • +
  • Room 2

    +
      +
    • State objectives clearly and repeat them a few times

    • +
    • Try to keep it informal, interactive, flexible

    • +
    • Helps when having practical tasks in mind for the materials taught

    • +
    • Leave some reasoning to the learner, not always giving full answers

      +
        +
      • How to deal with frustration though: try some personal approaches, more clues…

      • +
      +
    • +
    • The mediocre teacher tells. The good teacher explains. The superior teacher demonstrates. The great teacher inspires. — William Arthur Ward

    • +
    • Teaching kids to count is fine, but teaching them what counts is best. –Bob Talbert

    • +
    +
  • +
  • Room 4

    +
      +
    • Question 1: What is your motivation for taking this training?

      +
        +
      • Currently do instruction, wanting to improve as an instructor and helper when conducting software carpentries.

      • +
      • Planning to start some side hustles providing online courses and why not joining the CR in the near future

      • +
      +
    • +
    • Question 2: How structured or informal are your own teaching needs?

      +
        +
      • More recently, follow software carpentries, but look into what aspects can be tailored to keep to different time slots.

      • +
      • I used to be more informal in the past, repetetive practice sessions. Would like to be more structured given the teaching tools.

      • +
      • I’ve done life-coaching and some teaching but I feel i’m both of them

      • +
      +
    • +
    • Question 3: What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

      +
        +
      • Smaller size, and more targetted.

      • +
      • Collaborative tools and targeted audience working with small groups

      • +
      • Academic probably focuses on an audience with a more focused/narrow background, while this style encompasses a wider audience.

      • +
      • Academic teaching keeps theory and practical lab sessions very separate, whereas carpentries combine both.

      • +
      +
    • +
    • Question 4: What other skills need to be taught, but academic teaching isn’t the right setting?

      +
        +
      • Public speaking, collaborative meeting skills

      • +
      • Industrial cases and related work skills

      • +
      +
    • +
    +
  • +
+
+
+
Episode 3: Co-teaching
+

Materials: https://coderefinery.github.io/train-the-trainer/co-teaching/

+
    +
  • In general: Co-teaching is a beast with at least two personalities each of which

    +
      +
    • demand higher preparation requirements

    • +
    • face remarkable complexity in terms of coteacher coordination

    • +
    • in the virtual component face shortcomings related to the technical equipment and the failure of the human factor

    • +
    +
  • +
+
    +
  • Co-teaching requires the framework of co-operative learning. Team teaching does not by default translate into parallel learning, and vice versa.

  • +
+
    +
  • Re: CodeRefinery in-person beginnings – I agree with the “didn’t work so well in-person”, I’m not sure if it’s that we weren’t as ready for it, or that the different characteristics made it not work so much

  • +
  • How do the downsides compare to a single instructor monologuing?

    +
      +
    • That’s a great question! The main difference is that a single instructor can teach himself to be good (i.e. not just boring monologuing) alone, while for teams of 2+ to work well, everyone needs to be baseline-competent. So the effort to avoid downsides gets reduced if (and only if) all team members share it.

    • +
    +
  • +
+
+

Exercise/Discussion: https://coderefinery.github.io/train-the-trainer/co-teaching/#exercise

+

Questions:

+
    +
  • Have you already tried this or similar model in your teaching?

  • +
  • Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best?

  • +
  • Have you tried or seen a different model for two instructors to present? Please share with us how it works.

  • +
+
+
    +
  • room 1

    +
      +
    • We have tendend to do presenter/interviewer more

    • +
    • challenges are co-teaching with different personalities

    • +
    +
  • +
  • room 2

    +
      +
    • Main challenge: finding enough personell :smile:

    • +
    • It’s not always possible/feasible to have colleagues co-teaching

    • +
    • A combination of both, but presenter and interviewer could be difficult to plan an to follow

    • +
    • Guide and demo-giver with technical / non-technical roles could be nice

      +
        +
      • How to plan the guide and demo-giver

        +
          +
        • First guide, then demo

        • +
        • Demo, then guide describes

        • +
        +
      • +
      +
    • +
    • Alternative model: main presenter + ‘technical expert’

      +
        +
      • main presenter introduces concepts from a birdseye view and passes on to the technical expert for additional details, experiences and answers to questions from the audience

      • +
      +
    • +
    • We frequently do a classical division: on person in presenting, one or more are answering questions in the chat; there is rarely any interaction between them however

    • +
    +
  • +
+
    +
  • As has been pointed out by Paolo Freire, in general, ‘education is suffering from narration sickness’ … ‘The outstanding characteristic of this narrative education, then, is the sonority of words, not their transforming power’. Perhaps one approach could be to rephrase the question after having the answer: It is not apriori about the model implemented, it is about whether that what was implemented was judged aposteriori to have succeeded in becoming, or at least could pretend to have done so, the intended context matched model implementation it probably was computed to be.

  • +
+
    +
  • room 4

    +
      +
    • the co-teaching approach does not seem to be widely practiced

    • +
    • it can be interesting to see “mistakes” which are less likely to happen in solo-teaching?

    • +
    • co-teaching can be nicer for audience but maybe more stress/anxiety for instructors to prepare? more stress in terms of not knowing all the questions in advance. less stress worrying about forgetting something.

    • +
    +
  • +
+
+
+
Teaching gems
+

(scroll up to find the green box “Episode on teaching gems”)

+

What’s your favorite way of teaching? Any nice tools you use?

+

Has anyone found a nice online tool to draw?

+
    +
  • I love this tool suite https://excalideck.com/

    +
      +
    • For drawing https://excalidraw.com/

    • +
    +
  • +
  • I have seen Miro …

  • +
  • I think the Code Refineries use something for their graphics that looks a bit ‘cartoony’ - but I cannot remember what it is called!

    +
      +
    • Drawn on remarkable and then coloured and tidied up in Inkscape. :+1:

    • +
    +
  • +
  • I am a big fan of remarkable. I think sharing option is fairly good. Unfortunately bit expensive tool.

    +
      +
    • true, for me it was worth it already for the pdf annotation for research papers, cannot read on computer screen

    • +
    +
  • +
  • https://webwhiteboard.com/

  • +
  • https://www.youtube.com/watch?v=4-l8MY5kYGc

  • +
  • Figma and Kahoot are useful as well

  • +
+

Screenkey: Screenkey for showing keyboard shortcuts

+
    +
  • Is there a Windows version people can recommend?

    +
      +
    • I found this list of alternative for windows users like me: https://alternativeto.net/software/screenkey/ :+1:

    • +
    +
  • +
  • I sometimes use the on-screen keyboard already provided by the OS :+1:

  • +
+
+
+
+

Wrapup

+
    +
  • Next session Tuesday September 3rd 9 CEST: About teaching & cool things we all would like to share

  • +
  • All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14 CEST

  • +
  • Preparations for next week will be sent out by e-mail

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • The co-teaching lesson and experiences from others

  • +
  • Discussions were quite good, had a nice group

  • +
  • Breakout rooms and collaborative tools

  • +
  • Computational thinking and co-teaching are interesting ideas! I have seen it before, but never knew or even recognized it was a method.

  • +
  • Thanks for group discussions working with my chat only interaction! :smile:

  • +
  • ..

  • +
+

What one thing would you improve about this session?

+
    +
  • Minor point - it would be useful to have the teaching gmes box at the bottom of the document rather than the top - tricky to scroll between! In the end I opened two windows which was easier.

    +
      +
    • Thanks, yes agree. Also had that problem, but did not want to move it in between.

    • +
    +
  • +
  • The meaning of teaching “philosophy” wasn’t very clear, felt more like teaching “styles”

    +
      +
    • Thank you, we will take that into consideration

    • +
    +
  • +
  • Some prepared slides to present for an intro about the topics

    +
      +
    • You mean in addition to the materials? To use in the beginning of each session?

    • +
    +
  • +
  • The instructor views segment could be named as additional material, if it was not meant to be discussed within the course.

    +
      +
    • Thank you, we will take that into consideration

    • +
    +
  • +
+

Any other comments?

+
    +
  • Keeping it short and sweet: If at first you don’t succeed in teaching, try to explain it like you’re talking to a room full of cats. Caveat: In a room full of computational thinkers maybe if you tell students that the brain is a computational device that is forbidden, they might get excited and start using it.

  • +
+
+
+

Day4: Session 4 (3.09.24) - Streaming and video editing

+
+
:calendar: Schedule
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 10.00

Why we stream & Behind the scenes

10.15 - 11.00

8.15 - 9.00

10.00 - 10.15

Break

11.00 - 11.15

9.00 - 9.15

10.15 - 10.35

Video Editing

11.15 - 11.35

9.15 - 9.35

10.35 - 10.55

Exercise: Video Editing

11.35 - 11.55

9.35 - 9.55

10.55 - 11.10

Break

11.55 - 12.10

9.55 - 10.10

11.10 - 11.30

Open Broadcaster Software(OBS) introduction

12.10 - 12.30

10.10 - 10.30

11:30 - 11:50

OBS setup & what next

12.30 - 12.50

10.30 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+
:icecream: Icebreaker
+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :coffee: +

  • +
  • :runner:

  • +
  • :tired_face: Tired!

  • +
  • :nerd_face:

  • +
  • +
  • :cloud: :tea:

  • +
+
+
+
Introduction in breakoutrooms
+
    +
  • Name / Affiliation / Location

  • +
+

What’s the most number of people you have taught to?

+
    +
  • 20 at a time, with 1 asleep, 2 fidgiting with some silly device and the rest were… well… staring at their good luck… straight ahead it was of course, right before them.

  • +
  • ~35

  • +
  • ~80 in a lecture in a previous (lecturer) role, 26 in a training course setting

  • +
  • ~30

  • +
  • ~50 in training spaces and more than 100 for public audience talk

  • +
  • 35 (software carpentry)

  • +
  • CodeRefinery answer: The biggest ones are maybe 200-300 people. “small” for a stream is ~100 people.

  • +
+

What’s the most number of people you have taught with?

+
    +
  • 5 or so

  • +
  • 2 or 3 in total

  • +
  • 3, as in three, none of them smiling. I wish I could figure out why… it was such fun really…

  • +
  • 7

  • +
  • 2 or 3

  • +
  • 3 (helpers, not really co-teaching)

  • +
  • CodeRefinery answer: our biggest workshops are something like 10-20 people helping out in many different roles.

  • +
+

How can you divide teaching into separate independent tasks?

+
    +
  • By content blocks, having roles like main and assistant…

  • +
  • Having responsibility for different sections of the course.

  • +
  • Wow, now thats what we call a question… bravo… indeed, how does one separate sleeping and snoring into separate independent tasks…

  • +
  • Course, exercices, resources, tools and forms.

  • +
  • Different people teach different topics

  • +
  • CodeRefinery answer: the big logical blocks are instructors, in-person and breakout room helpers, and Notes-questions answers.

  • +
+

What’s the most interesting or useful thing you’ve learned from an online workshop, and how have you applied it/planning to apply in your life or work

+
    +
  • Having breaks every hour or so

  • +
  • New approach to screensharing, using the ‘portrait’ approach

  • +
  • Manage breathing: reduce stress and use silence to let the audience grasp what you’re saying

  • +
  • Well, the most interesting or useful thing I’ve learned from online workshops is how not to conduct a workshop, or at least some elements of the same, and I have applied this understanding by engaging in the global effort to discover more about how not to conduct a workshop, or at least some elements of the same, with the motto: That’s one small step for a man, one giant leap for mankind..

  • +
+
+
+
+
:question: Questions
+
+
+
Why we stream
+
    +
  • If during streaming there is no interaction between the teacher and the audience, why don’t we just record the lectures and stream them? So one can do a better job, perhaps?

    +
      +
    • Streaming it making it a “thing” that’s a group experience. It feels good to be a part of it, so we hope that encourages people to actually attend. All the mass Q&A is fun, and the audience helps to make it easier to present. Still, this is a good question.

    • +
    • I really appriciate it being “a thing”. If it was just recorded, I would say I would watch it tomorrow, and then I never would.

      +
        +
      • But then you can just fake it, and still have all the breakout rooms and collaborative document and so on. I appreciate the value of having a proper “event”.

        +
          +
        • I think I follow you, but if you pre-recorded the talking bits, then the presentors couldn’t change what they do based on the feedback in the shared document.

          +
            +
          • true, but I assumed that the teachers were too busy to actually do that. The more (less )division of labor between the teachers and the helpers (or collaborative document editors), the more (less) sense it makes to pre-record - IMHO

          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • What interaction options do ‘streamers’ use, e.g. on Twitch/YouTube (not Code Refinary)?

    +
      +
    • I’m besides chat and things that happen in chat, I’m not sure. The Notes-doc is definitely unique to us.

    • +
    +
  • +
  • Streaming is a kind of exercise for the movie star type. If you cannot be one, act like one, pretend, fool the listener into thinking you are one, take their brains and emotions under control. And if they don’t leave the session with tears of love for learning running down their chubby cheeks you know who to kick for doing a job just that bit worse than it should have been necessary.

  • +
  • Have you kept track of streming stats? like how many people logged in and stayed troughout, how many interacted?

    +
      +
    • Yes please, it would be good to see the stats

    • +
    • Here is stats repo

    • +
    • Thanks, I get a 404 error, is it private?

    • +
    • No, I don’t think so. https://github.com/coderefinery/workshop-stats

    • +
    • Still get 404. Does it work for anyone else?

      +
        +
      • Yeah I think it’s private. We need to fix this…

      • +
      +
    • +
    +
  • +
  • How big is small (10-15), medium (~30-40)?

    +
      +
    • I would say below 50 is small.

    • +
    +
  • +
  • Have you considered scaling to more events instead of to a larger audience? I mean, this seems the opposite of scaling, but this kind of content would be more useful the more often is it taught (“I need to learn GIT/Python/* in December!”)

    +
      +
    • We would, but right now we simply don’t have enough time and people to do more small events. But yes, “scheduling conflict” is a big problem - the best we can do right now is written material+videos to follow up on (and hope it’s interesting enough)

    • +
    • Python for Scientific Computing 5-7/November/2024

      +
        +
      • This was just an example. I mean, if I am a PHD student that needs to start working on a topic on Month X which happens to be inconveniently placed in the year, I will not benefit as much from having a workshop at Month X+3

        +
          +
        • The materials are open and the videos are publically available on YouTube channel

          +
            +
          • What’s the ratio of people watching videos afterwards vs people attending the event? That ratio can give an idea of the popularity of the two possible approaches.

          • +
          +
        • +
        +
      • +
      +
    • +
    • The more you scale up the less interactive the course / workshop will need to be. It then becomes a question of priorities, and if teaching is a lower priority then learning than I guess there really should be no prizes for guessing which approach should reign the airwaves.

    • +
    +
  • +
  • I guess outside Europe / Africa, time zones could be a problem?

    +
      +
    • yes, that is true

    • +
    • +
    +
  • +
  • Sorry, I might have missed this: have you been rehearsing and/or doing dry runs?

    +
      +
    • With instructors I like to try to do a dry run. I often don’t do a live broadcast dry run these days since I’m confidente enough, but when you are just starting, it’s a good idea.

    • +
    +
  • +
  • Do you always use Zoom for the ‘presenter end’ or have you tried other things? Teams? Jitsi? etc.?

    +
      +
    • we use mostly zoom

    • +
    • It was first pioneered using Jitsi. You can probably use others, too.

    • +
    +
  • +
  • A comment: for deRSE24 we have been using the GWDG streaming service and OBS, it worked quite well (with a 20s delay or so)

    +
      +
    • Cool! Yes, there is plenty of livestreaming options. Twitch+our OBS config gives us 2-3s of latency (which is low enough for live Notes interaction). You might be able to tune this if needed.

    • +
    +
  • +
+
+
+
Behind the stream
+
    +
  • Does OBS take a lot of RAM or CPU? what are the specs on your machine?

    +
      +
    • Richard have a relatively powerful computer with 8 AMD CPUs.

    • +
    • 4 CPUs are relatively enough for a good OBS setup, most important is a stable internet connection (ideally wired).

    • +
    • An extra monitor is recommended for the setup

    • +
    • See the hardware notesrecommendation here

    • +
    +
  • +
  • Do you do a screenshare from Zoom -> OBS or OBS -> Zoom?

    +
      +
    • Instructors share to Zoom, OBS captures Zoom, OBS sends to the world.

    • +
    • When I am using OBS sfor a single-person presentation recording, I go the other way: OBS captures my desktop/camera, OBS generates the preview window, and then Zoom captures and broadcasts the preview window.

    • +
    +
  • +
+
+
+
Video editing
+
+
Poll
+
    +
  • Have you tried video editing? Add ano as answer below

    +
      +
    • yes: ooooo

    • +
    • no :

    • +
    • Video editing makes all the difference. I have never known a way to avoid this sacred of steps, so to speak. In short, no recording can ever be production ready by default in the books of the wiser among the streamers. In fact, during the editing one can considerably refine and improve the learning experience in great ways. But then one would need to invest both time and effort.

    • +
    +
  • +
  • If yes Which are the tools you use?

    +
      +
    • Windows Movie Maker / ClipChamp

    • +
    • (raw stream from Zoom)

    • +
    • I think it was shotcut - I did only basic trimming

    • +
    • Kdenlive

    • +
    • Clipchamp, OpenShot, Sony Vegas

    • +
    • also ffmpeg from command line to cut beginning and end

    • +
    +
  • +
+
+
+
Questions
+
    +
  • What is Whisper?

    +
      +
    • Open-source model from OpenAI that converts speech to text transcripts.

    • +
    • this one? https://openai.com/index/whisper/

    • +
    • curious if anyone has tried it with languages other than english

    • +
    • I heard that one of my spanish colleague try it with another software. I don’t remember the tool. But with AI bloom there are many licensed tools that can do it with fifferent language

    • +
    +
  • +
  • What do you use to crop the videos?

    +
      +
    • I see now, ffmpeg

    • +
    +
  • +
  • how to merge multiple parts in one? I asked because you edited only the icebreaker part?

    +
      +
    • you can manage it in input part, see ffmpeg-editlist readme.

    • +
    +
  • +
  • Do you generate custom thumbnails for the video?

    +
      +
    • no, because of the time, but its good to have. If we had a volunteer to manage that, then we should!

    • +
    +
  • +
  • Does anyone recommend any other (GUI) tools that work well? ffmpeg is very new to me!

    +
      +
    • if you want a basic trimming and editing , you can use Quicktime player/imovies on mac

    • +
    • Clipchamp as the Microsoft video editor

    • +
    • Thanks :smile:

    • +
    +
  • +
  • How do subtitles get uploaded to YouTube?

    +
      +
    • You upload the video and subtitles as part of upload.

    • +
    • :+1:

    • +
    +
  • +
  • How does codewhisperer compare against youtube’s automatically generated subtitles?

    +
      +
    • by experience, whisper was better couple of years ago. We haven’t compared it recently

    • +
    • I guess and advantage is that you can edit whisper subtitles in case something is odd or whatever, probs cannot do that in YouTube

    • +
    +
  • +
+
+
+
+
Open Broadcaster Software (OBS) introduction & setup
+
    +
  • Are the profiles public?

    +
      +
    • Yes, you can see it here

    • +
    +
  • +
  • Does it work in Linux+Wayland?

    +
      +
    • I think everything we do with OBS would.

    • +
    +
  • +
+
+
+
+

Wrapup

+ +
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • ffmpeg seems great, will give a try for fun!

  • +
  • great to see everything in practice!

  • +
  • Very insightful to see what happens behind the scenes.

  • +
+

What one thing would you improve about this session?

+
    +
  • Some more interactivity would’ve been nice but since most the group preferred demo instead of exercise perhaps it’s only a personal opinion

  • +
  • It would have been good to share the OBS profiles repo beforehand in the setup email - so I could have had it to hand. (https://github.com/coderefinery/obs-config)

    +
      +
    • +1 good idea, we should do this next time

    • +
    +
  • +
  • Perhaps a simpler starter OBS setup?

    +
      +
    • Good idea… I should have, but basically ran out of time to prepare.

    • +
    +
  • +
+

Any other comments?

+
    +
  • Cool to see the switch from RSE to trainer to AV guy, impressive!

  • +
+
+
+
+
+

Instructor guide

+
+

Target audience

+
    +
  • Everyone teaching online workshops about computational topics or interested in teaching.

  • +
  • Previous and future instructors and helpers of CodeRefinery workshops.

  • +
+
+
+

Timing

+

Session 1

+
    +
  • 15 min: Intro

  • +
  • 45 min: Lesson design and development

  • +
  • 15 min: Break

  • +
  • 45 min: Lesson template

  • +
  • 15 min: Break

  • +
  • 30 min: How we collect feedback and measure impact

  • +
  • 10 min: Outro and feedback

  • +
+

Session 2

+
    +
  • 15 min: Intro

  • +
  • 10 min: About the CodeRefinery project and CodeRefinery workshops in general

  • +
  • 30 min: Collaborative notes and interaction

  • +
  • 15 min: Break

  • +
  • 35 min: Workshop overview, roles, onboarding/installation, helpers

  • +
  • 20 min: Sound

  • +
  • 15 min: Break

  • +
  • 30 min: Screenshare

  • +
  • 10 min: Outro and feedback

  • +
+

Session 3

+
    +
  • 15 min: Intro

  • +
  • 30 min: Computational thinking

  • +
  • 15 min: Break

  • +
  • 30 min: Teaching philosohies

  • +
  • 30 min: Co-teaching

  • +
  • 15 min: Break

  • +
  • 35 min: Sharing teaching tips, tricks, tools etc

  • +
  • 10 min: Outro and feedback

  • +
+

Session 4

+
    +
  • 15 min: Intro

  • +
  • 10 min: Why we stream

  • +
  • 20 min: Behind the stream

  • +
  • 15 min: Video editing (part 1)

  • +
  • 15 min: Break

  • +
  • 25 min: Video editing (part 2, exercise)

  • +
  • 20 min: OBS introduction

  • +
  • 15 min: Break

  • +
  • 30 min: OBS setup

  • +
  • 15 min: What’s next?

  • +
+
+
+

Talking points for each sessions intro

+
    +
  • Brief CodeRefinery intro

  • +
  • Instructors intros

  • +
  • Notes intro

    +
      +
    • Check-in

    • +
    • Icebreaker

    • +
    • Participant intros in breakoutrooms (Random assign first, then same for whole session)

    • +
    +
  • +
  • Daily schedule, learning objectives

  • +
  • Code of conduct

  • +
  • Chat (please use collaborative notes)

  • +
+
+
+

Participant preparations for each session

+

Copied from e-mail communication with participants before each session.

+

Session 1: +In general you will only need your brain for the exercises and discussions, but some will have the option to go deeper, which may require some accounts or tools to be set-up. We will inform about these things the week before each session.

+

For Session 1 we recommend to have a GitHub account (https://coderefinery.github.io/installation/github/#github). There will be an optional exercise where you can build a lesson locally. This requires a basic Python environment (https://github.com/coderefinery/sphinx-lesson-template/blob/main/requirements.txt), but do not worry if you cannot or do not want to set up these, there will be plenty of other exercises.

+

Session 2: +In general you will only need your brain for the exercises and discussions. To get the most out of this workshop day we recommend that you join the session with the same computer, display and microphone setup as you would usually use for teaching/ presenting. It may also help to get familar with the different options your computer and Zoom setup provides for screenshare and audio adjustments. +But it is not a must.

+

Session 3: +In general you will only need your brain for the exercises and discussions. If you want to share some “cool gem” in the last episode of this workshop day, please update your registration (link to edit can be found in the registration confirmation e-mail sent by support@coderefinery.org or noreply@neic.org). This is very low barrier, you do not have to be the developer of a tool or technique to share with the group what makes it useful for you; and it does not even have to be cool, sometimes the small “normal” things are the best. You can check out some topics that have been proposed so far in this GitHub issue (#90), you can also comment there if you want to add or change your topic. These will be lightning talk length, so something between 2-5 min depending on how many are interested to share something, but we can collect them all in the collaborative notes for further exploration/reading. +But it is not a must.

+

Session 4: +This upcoming session (session number 4) will cover the technical aspects of CodeRefinery-style online teaching. These topics have never before been covered in this much detail, so if it’s interesting to you, don’t miss it. (You might also want to pass this on to others who are interested in technical production of online events; registration is still open!).

+

First, we talk about why we stream (how we got here, advantages, disadvantages, how to be an instructor in a livestreamed workshop, and what it looks like from a broad level from the production side)

+

Then, we show how we are able to release videos so quickly. This is useful far beyond CodeRefinery, and there are also some hands-on exercises. Come prepared to set up a Python environment and the ffmpeg command line tool if you want to try these.

+

Finally, we see details about how to set up Zoom→Livestream environment for yourself. There isn’t time to do this as a proper exercise, but it’s the starting point and the instructor will offer help after the course for those interested. If you want to try this out during the session, install OBS Studio in advance.

+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright CodeRefinery project.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/singlehtml/objects.inv b/branch/comms/singlehtml/objects.inv new file mode 100644 index 0000000..1f4c690 Binary files /dev/null and b/branch/comms/singlehtml/objects.inv differ diff --git a/branch/comms/sound/index.html b/branch/comms/sound/index.html new file mode 100644 index 0000000..040b61f --- /dev/null +++ b/branch/comms/sound/index.html @@ -0,0 +1,366 @@ + + + + + + + Sound — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Sound

+
+

Objectives

+
    +
  • Understand that sound quality is very important

  • +
  • Evaluate your and others sound quality and know how to improve it

  • +
  • Test tips and tricks for achieving good sound quality

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Exercises: 10 min

  • +
+
+
+

The importance of audio

+
    +
  • Pleasing audio quality makes events much more enjoyable

  • +
  • Audio is one of the most important things you can control

  • +
  • Things that can go wrong:

    +
      +
    • Too quiet

    • +
    • Too loud

    • +
    • Instructors’ volumes imbalanced

    • +
    • Background noise

    • +
    • Low-quality/breaking up audio hard to hear.

    • +
    • “Ducking” (first words lower volume, or lower volume other times)

    • +
    +
  • +
+
+
+

Tips for good sound quality

+
    +
  • Have a headset with mounted microphone

    +
      +
    • Even if you have a professional external microphone, it doesn’t +matter if your room has bad acoustics.

    • +
    • The close pickup can’t be beat with normal tools.

    • +
    • As long as it’s headset mounted, price doesn’t seem to matter +that much.

    • +
    +
  • +
  • Don’t use Bluetooth

    +
      +
    • Bluetooth can have too much latency (300-500ms)

    • +
    • This may seem small but for interactive work, it’s a lot

    • +
    • Use a wired headset, or wireless with a non-Bluetooth USB plug +(like gaming headsets have). These have much lower latency.

    • +
    • Bluetooth 5 can have much lower latency, but you probably +shouldn’t count on that without testing.

    • +
    • It can also have lower sound quality on some devices due to +bandwidth limitations.

    • +
    +
  • +
  • Once you have a headset, turn input noise cancellation to low +(wherever it might be: headphone, meeting software, etc.).

  • +
+
+
+

Balancing and dynamic adjustment

+
    +
  • It’s important that instructors volumes match.

  • +
  • An exercise will go over a systematic procedure for matching +volumes.

    +
      +
    • Practice so that you can do this quickly.

    • +
    +
  • +
  • May need re-adjusting when instructors swap out or start getting +excited.

  • +
  • An exercise below will demonstrate our procedure.

  • +
+
+
+

Speak up when there are problems

+
    +
  • If you notice someone with audio issues, let them know right away +(voice if bad, or chat/notes if less urgent).

  • +
  • Take the time to fix it as soon as practical.

  • +
  • Make a culture of speaking up, helping, and not suffering.

  • +
+
+
+

Recommendations

+
    +
  • Procure some reasonable headset.

  • +
  • Low/medium-priced gaming-type headsets have worked well for us.

    +
      +
    • (gaming headsets usually aren’t Bluetooth, because gaming needs +low latency.)

    • +
    +
  • +
  • Show this page to your workplace (if you have one) and call a good +headset work equipment.

  • +
+
+
+

Exercises

+
+

Sound-1: Evaluate sound quality

+

It’s important to be able to discuss with others the quality of their +audio. They can’t hear themselves, after all.

+
    +
  • Within the teams, discuss each person’s audio quality and what kind +of setup they have.

  • +
  • Be respectful and constructive (and realize that people came +prepared to listen, not teach).

  • +
  • Consider, for example

    +
      +
    • Volume

    • +
    • Clarity

    • +
    • Background noise

    • +
    • Noise cancellation artifacts

    • +
    • “Ducking”: first words at lower volume or missing

    • +
    +
  • +
  • Discuss how to bring this up during other courses and meetings.

  • +
+
+
+

Sound-2: Adjust volume up and down

+

In addition to individual quality, it is important that sound is +balanced among all instructors. Have you ever been to a event when +one person is too quiet and they can’t make themselves any louder? +And they can’t adjust it?

+

You should ensure that you have a range of volumes available to you. +You might have to look into several different locations in order to +make the full adjustment ().

+
    +
  • Go to your sound settings

  • +
  • One by one, each person

    +
      +
    • Adjusts their microphone volume so quiet that they can’t be heard.

    • +
    • Adjusts their microphone volume so that it is extremely loud (this +may require going beyond 100% if possible).

    • +
    +
  • +
  • Basically, make sure you aren’t so close to either end that you have +no potential to make an adjustment in that direction.

  • +
  • Everyone tries to set the volume to something reasonable, in +preparation for the next exercise.

  • +
+

Once you know where these settings are , you won’t be panicked when the +volume is too low or high during a course.

+
+
+

Sound-3: Do a balance check

+

It’s important that instructor audio is balanced (the same volume). +But how can you do this?

+
    +
  • Pick a leader.

  • +
  • The leader decides the order (“I am first, then [name-1] and +[name-2]”)

  • +
  • The leader says “one”. Everyone else says “one” in the order +specified.

  • +
  • The leader says “two”. Everyone else says “two” in the order.

  • +
  • The leader asks for opinions on who they think is louder or softer. +If there are more than three people, you can figure it out +yourselves. With less than two, you have to ask someone in the +audience.

  • +
+

Example:

+
    +
  • Leader: Let’s do a sound check. I am first, then AAA and BBB.

  • +
  • Leader: One

  • +
  • AAA: One

  • +
  • BBB: One

  • +
  • Leader: Two

  • +
  • AAA: Two

  • +
  • BBB: Two

  • +
  • Leader: Three

  • +
  • AAA: Three

  • +
  • BBB: Three

  • +
  • Leader: How did that sound to everyone?

  • +
  • [Someone else]: Leader and BBB were pretty similar but AAA is a bit +lower.

  • +
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Audio quality is important and one of the most notable parts of the +workshop.

  • +
  • Improving audio isn’t hard or expensive, but does require preparation.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/streaming-whats-next/index.html b/branch/comms/streaming-whats-next/index.html new file mode 100644 index 0000000..916e18c --- /dev/null +++ b/branch/comms/streaming-whats-next/index.html @@ -0,0 +1,202 @@ + + + + + + + What’s next? — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

What’s next?

+
+

Objectives

+
    +
  • Know next steps if you want to do streaming

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 5 min

  • +
  • Q&A 5 min

  • +
+
+

What comes next?

+
    +
  • We talked a lot about theory, and gave demonstrations.

  • +
  • Hands-on is very different. We recommend working with someone to +put it in practice.

  • +
  • +
+
    +
  • Work with someone who can show you the way

  • +
  • Use it for smaller courses with a backup plan

  • +
+
+

See also

+
+

Keypoints

+
    +
  • These lessons about streaming have been the theoretical part of +streaming training.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/streaming/index.html b/branch/comms/streaming/index.html new file mode 100644 index 0000000..54c786f --- /dev/null +++ b/branch/comms/streaming/index.html @@ -0,0 +1,274 @@ + + + + + + + Behind the stream — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Behind the stream

+
+

Objectives

+
    +
  • Take a first look at the broadcaster’s view.

  • +
  • Get to know what happens “behind the stream” of a workshop

  • +
  • See what the “broadcaster” sees and what they need to do.

  • +
  • Not yet: learn details of how to do this.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Q&A 10 min

  • +
+
+

In this episode, you’ll see an end-to-end view of streaming from the +broadcaster’s point of view. It’s a tour but not an explanation or +tutorial.

+
+

Who does what

+

We have certain role definitions:

+
    +
  • Broadcaster: Our term for the person who manages the streaming.

  • +
  • Director: Person who is guiding the instructors to their +sessions, changing the scenes, calling the breaks, etc.

    +
      +
    • Could be the same as broadcaster.

    • +
    +
  • +
  • Instructor: One who is teaching. They don’t have to know +anything else about how streaming works.

  • +
+

This lesson describes what the Broadcaster/Director sees.

+
+
+

Window layouts

+

What does the broadcaster see on their screen?

+
    +
  • What are the main windows you see?

  • +
  • What do each of them do?

  • +
  • Which ones do you need to focus on?

  • +
  • How do you keep all this straight in your head?

  • +
+
+
+

CodeRefinery control panel

+
    +
  • A custom application that controls scenes

  • +
  • Based on OBS-websocket (remote control connection for OBS - we’ll +learn about this later)

  • +
  • Can also work remotely, so that you can have a remote director

  • +
+
+
+

How scenes are controlled

+

What has to be done during a course?

+
    +
  • How do you start the stream?

  • +
  • How do you change the view?

  • +
  • How do you adjust things based on what the instructors share?

  • +
  • How do you coordinate with the instructors?

  • +
  • How do you know when to change the view?

  • +
+
+
+

Getting it set up

+
    +
  • How hard was it to figure this out?

  • +
  • How hard is it to set it up for each new workshop?

  • +
+
+
+

What can go wrong

+
    +
  • What’s the worst that has happened?

  • +
  • What if you need to walk away for a bit?

  • +
  • Someone broadcasts something unexpectedly

  • +
+
+
+

Alternatives

+
    +
  • Youtube vs Twitch

  • +
  • Zoom stream directly to YouTube/Twitch

  • +
  • Direct streaming platform, e.g. streamyard

  • +
+
+
+

Q&A

+

Q&A from audience

+
+

Keypoints

+
    +
  • The broadcaster’s view shouldn’t be so scary.

  • +
  • There is a lot to manage, but each individual part isn’t that hard.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/teaching-philosophies/index.html b/branch/comms/teaching-philosophies/index.html new file mode 100644 index 0000000..155b81a --- /dev/null +++ b/branch/comms/teaching-philosophies/index.html @@ -0,0 +1,314 @@ + + + + + + + CodeRefinery teaching philosophies — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CodeRefinery teaching philosophies

+
+

Objectives

+
    +
  • Get to know the teaching philosophies of CodeRefinery instructors

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Discussion: 20 min

  • +
+
+
+

Introduction

+

During this episode we split into breakoutrooms and discuss own teaching philosophies. +Collect your teaching philosophies in the collaborative document. We will be going through +these and the end of the lesson.

+
+

Ice-breaker in groups (20 minutes)

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+
+

Instructor views

+

Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops.

+

It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us.

+
+

Video recordings

+

We have recorded some of the below as videos: https://www.youtube.com/playlist?list=PLpLblYHCzJAAHF89P-GCjEXWC8CF-7nhX

+
+
+

Bjørn Lindi

+

My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this “BLOB” (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the “BLOB”, to be able to share it with others.

+

In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic.

+

When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson.

+

Tools that I find useful in preparing a lesson is concept maps and Learner Personas (though I have developed too few of them):

+ +
+
+

Radovan Bast

+

My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos.

+

My goal for a lesson is to spark curiosity to try things after the lesson, both +for the novices (“This looks like a useful tool, I want to try using it after +the workshop.”) and the more experienced participants (“Aha - I did not know +you could do this. I wonder whether I can make it work with X.”). I like to +start lessons with a question because this makes participants look up from +their browsers.

+

Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise.

+

For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate the +answer.

+

I try to avoid jargon and “war stories” from the professional developers’ +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid “customer”, +“production”, also a lot of Agile jargon is hard to relate to.

+

Less and clear is better than more and unclear. Simple examples are better than +complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +“simply”, “just”, “easy”. If participants take home one or two points from a +lesson, that’s for me success.

+

I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don’t want to be +surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or slide. +This allows me to skip and distill the essence and not read bullet point by +bullet point.

+

I try to never deviate from the script and if I do, be very explicit about it.

+

A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel listening to me.

+

I very much like the co-teaching approach where the other person helps +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson.

+
+
+

Sabry Razick

+

My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case.

+
+
+

Richard Darst

+

Like many people, I’ve often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I’ve realized long ago that my most important lessons weren’t +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I’ve realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds.

+

My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I’m often start at the +very basics, because this is what I see missing most often.

+

When teaching, I like lots of audience questions and don’t mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don’t have to know everything perfectly, just show how +you’d approach a problem.

+
+
+

Stepas Toliautas

+

I aim for my learners to understand things (concepts, techniques…), instead of just memorizing them. The phrase I use from time to time when teaching information technology topics (be it hardware or software) is “there is no magic”: everything can be explained if necessary. While CodeRefinery also emphasizes usefulness/ immediate applicability of the content, often having the correct notions actually helps to start using them sooner and with less mistakes.

+

I try to guide my audience through the presented material with occasional questions related to previous topics and common knowledge – to help them link the concepts already during the lesson. I’m also fully aware that waiting for someone to answer is quite uncomfortable in-person and doubly so in an online environment, especially if no one uses their cameras :)

+

And if I get the question I don’t have the answer for (or material to show it) at the moment, in university classes I prepare and come back to it next time. While with one-off workshops there might not be a “next time”, open-source material used by CodeRefinery allows to have the same outcome: the latest and greatest version stays available for self-study afterwards.

+
+
+
+

Summary

+
+

Keypoints

+
    +
  • People have different viewpoints on teaching.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/video-editing/index.html b/branch/comms/video-editing/index.html new file mode 100644 index 0000000..bdf96d4 --- /dev/null +++ b/branch/comms/video-editing/index.html @@ -0,0 +1,606 @@ + + + + + + + Video editing — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Video editing

+
+

Objectives

+
    +
  • Get to know ways of quick video editing to be able to provide +accessible videos

  • +
  • Learn how video editing can be distributed and done the same day.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 20 min

  • +
+
+

Video recordings could be useful for people watching later, +but also are (perhaps more) useful for immediate review and catching +up after missing a day in a workshop. For this, they need to be +released immediately, within a few hours of the workshop. +CodeRefinery does this, and you can too.

+

Hypothesis: videos must be processed the same evening as they were +recorded, otherwise (it may never happen) or (it’s too late to be +useful). To do that, we have to make processing good enough (not +perfect) and fast and the work distributeable.

+
+

Primary articles

+ +
+
+

How this relates to streaming

+
    +
  • If you stream, then the audience can not appear in the recorded +videos

  • +
  • This allows you to release videos very quickly if you have the +right tools.

  • +
  • When you have a large audience, the videos start helping more +(review a missed day, catch up later, review later)

  • +
  • Thus

    +
      +
    • If you would never want videos, there may never be a benefit to +streaming

    • +
    • If you want videos, it gives motivation to stream.

    • +
    +
  • +
+
+
+

Summary

+
    +
  • Basic principle: privacy is more important than any other factor. +If we can’t guarantee privacy, we can’t release videos at all.

    +
      +
    • Disclaimers such as “if you don’t want to appear in a recording, +leave your video off and don’t say anything”, since a) accidents +happen especially when coming back from breakout rooms. b) it +creates an incentive to not interact or participate in the course.

    • +
    +
  • +
  • Livestreaming is important here: by separating the instruction from +the audience audio/video, there is no privacy risk in the raw +recording. They could be released or shared unprocessed.

  • +
  • Our overall priorities

    +
      +
    1. No learner (or anyone not staff) video, audio, names, etc. are +present in the recordings.

    2. +
    3. Good descriptions.

    4. +
    5. Removing breaks and other dead time.

    6. +
    7. Splitting videos into useful chunks (e.g. per-episode), perhaps +equal with the next one:

    8. +
    9. Good Table of Contents information so learners can jump to the +right spots (this also helps with “good description”.)

    10. +
    +
  • +
  • ffmpeg-editlist +allows us to define an edit in a text file (crowdsourceable on +Github), and then generate videos very quickly.

  • +
+
+
+

How we do it

+

The full explanation is in the form of the exercises below. As a +summary:

+
    +
  • Record raw video (if from a stream, audience can’t possibly be in +it)

  • +
  • Run Whisper to get good-enough subtitles. Distribute to someone for +checking and improving.

  • +
  • Define the editing steps (which segments become which videos and +their descriptions) in a YAML file.

  • +
  • Run ffmpeg-editlist, which takes combines the previous three steps +into final videos.

  • +
+
+
+

Exercises

+
+

Exercise A

+

These exercises will take you through the whole sequence.

+
+

Editing-1: Get your sample video

+

Download a sample video:

+ +
+

Editing-2: Run Whisper to generate raw subtitles and test video.

+

First off, install Whisper and generate the base subtitles, based +on the. Since this is probably too much to expect for a short +lesson, they are provided for you (above), but if you want you can +try using Whisper, or generating the subtitles some other way.

+

You can start generating subtitles now, while you do the next +steps, so that they are ready by the time you are ready to apply +the editlist. ffmpeg-editlist can also slice up the subtitles from +the main video to make subtitles for each segment you cut out.

+

Whisper is left as an exercise to the reader.

+ +
+
+
+

Editing-3: Create the basic editlist.yaml file

+

Install +ffmpeg-editlist and +try to follow its instructions, to create an edit with these features:

+
    +
  • The input definition.

  • +
  • Two output sections: the “Intro to the course”, and “From data +storage to your science” talks (Remember it said the recording +started at 11:35… look at the schedule for hints on when it +might start!). This should have a start/end timestamp from the +original video.

  • +
+

A basic example:

+
- input: day1-raw.mkv
+
+# This is the output from one section.  Your result should have two of these sections.
+- output: part1.mkv
+  title: something
+  description: >-
+    some long
+    description of the
+    segment
+  editlist:
+    - start: 10:00    # start timestamp of the section, in *original* video
+    - end: 20:00      # end timestamp of the section, in the *original* video
+
+
+ +
+
+

Discussion: what makes a video easy to edit?

+
    +
  • Clear speaking and have high audio quality.

  • +
  • For subtitle generation: Separate sentences cleanly, otherwise it +gets in a “stream of words” instead of “punctuated sentences” +mode.

  • +
  • Clearly screen-sharing the place you are at, including section +name.

  • +
  • Clear transitions, “OK, now let’s move on to the next lesson, +LESSON-NAME. Going back to the main page, we see it here.”

  • +
  • Clearly indicate where the transitions are

  • +
  • Hover mouse cursor over the area you are currently talking about.

  • +
  • Scroll screen when you move on to a new topic.

  • +
  • Accurate course webpage and sticking to the schedule

  • +
+

All of these are also good for learners. By editing videos, you +become an advocate for good teaching overall.

+
+
+

Editing-4: Run ffmpeg-editlist

+

Install ffmpeg-editlist: pip install ffmpeg-editlist[srt] (you +may want to use a virtual environment, but these are very minimal +dependencies).

+

The ffmpeg command line tool must be available in your +PATH.

+ +
+
+

Editing-5: Add more features

+
    +
  • Several chapter definitions.(re-run and you should see a +.info.txt file also generated). Video chapter definitions +are timestamps of the original video, that get translated to +timestamps of the output video.

    +
    - output: part1.mkv
    +  editlist:
    +  - start: 10:00
    +  - -: Introduction    #  <-- New, `-` means "at start time"
    +  - 10:45: Part 1      #  <-- New
    +  - 15:00: Part 2      #  <-- New
    +  - end: 20:00
    +
    +
    +

    Look at the .info.txt files that come out now. What is new in it?

    +
  • +
  • Add in “workshop title”, “workshop description”, and see the +.info.txt files that come out now. This is ready for +copy-pasting into a YouTube description (first line is the title, +rest is the description).

    +

    Look at the new .info.txt files. What is new?

    +
  • +
+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+
+
+

Editing-7: Generate the final output file.

+
    +
  • Run ffmpeg-editlist with the --reencode option: this +re-encodes the video and makes sure that there is no black point +at the start.

  • +
  • If you re-run with --check, it won’t output a new video file, +but it will re-output the .info.txt and .srt files. +This is useful when you adjust descriptions or chapters.

  • +
+
+
+

Discussion: how to distribute this?

+

Create a flowchat of all the parts that need to be done, and which +parts can be done in parallel. Don’t forget things that you might +need to do before the workshop starts.

+

How hard was this editing? Was it worth it?

+
+
+
+

Exercise B

+

This is a more limited (and older) version of the above exercise, +using an synthetic example video.

+
+

Use ffmpeg-editlist to edit this sample video

+

Prerequisites: ffmpeg must be installed on your computer +outside of Python. Be able to install ffmpeg-editlist. This is +simple in a Python virtual environment, but if not the only +dependency is PyYAML.

+ + +
+
+
+
+

See also

+ +
+

Keypoints

+
    +
  • Video editing is very useful for learning

  • +
  • Set your time budget and make it good enough in that time

  • +
  • Reviewing videos improves your teaching, too.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/comms/why-we-stream/index.html b/branch/comms/why-we-stream/index.html new file mode 100644 index 0000000..666d0cf --- /dev/null +++ b/branch/comms/why-we-stream/index.html @@ -0,0 +1,298 @@ + + + + + + + Why we stream — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Why we stream

+
+

Objectives

+
    +
  • Learn the general history of CodeRefinery streaming.

  • +
  • Discuss the benefits of streaming and recording

  • +
  • Discuss the downsides and difficulties

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 10 min

  • +
  • Q&A: 5 min

  • +
  • Exercises: 0 min

  • +
+
+

This is a general discussion of the topics of the day, focused on the +history of why we stream and record, how we got here, and how people +feel about it. We won’t focus on how anything is done.

+
+

Icebreaker questions

+
    +
  • What is the most people you have taught for?

  • +
  • What are the distinct parts of teaching, that can be +separated? (teaching, helping, etc)

  • +
+
+
+

What is streaming and recording?

+
    +
  • Streaming is mass communication: one to many

    +
      +
    • Interaction audience→presenters is more limited (but different)

    • +
    +
  • +
  • Using consumer-grade tools, normal people can reach huge audiences +by Twitch/YouTube/etc.

  • +
  • This isn’t actually that hard: people with much less training than +us do it all the time.

  • +
  • They reach huge audiences and maintain engagement for long events.

  • +
+

Recording and rapid video editing is useful even without +streaming.

+
+
+

History

+
    +
  • In-person workshops

    +
      +
    • 3 × full day, required travel, infrequent, one-shot

    • +
    +
  • +
  • Covid and remote teaching

    +
      +
    • Traditional “Zoom” teaching several times

    • +
    +
  • +
  • Mega-CodeRefinery workshop

    +
      +
    • 100-person Zoom teaching

    • +
    • Emphasis on teams

    • +
    +
  • +
  • Research Software Hour

    +
      +
    • Livestream free-form discussions on Twitch

    • +
    +
  • +
  • Streamed “HPC Kickstart” courses

  • +
+
+
+

Benefits and disadvantages

+

Benefits:

+
    +
  • Larger size gives more (but different) interaction possibility

    +
      +
    • “Notes” for async Q&A

    • +
    +
  • +
  • Recording (with no privacy risk) allows instant reviews

  • +
  • Stream-scale allows for many of the things you have learned about in +days 1-3.

  • +
+

Disadvantages:

+
    +
  • Requires training for using the tools

  • +
  • Requires a certain scale to be worth it

  • +
  • Coordination is much harder for big events

  • +
+

When would I recommend it?

+
    +
  • No: For small courses

  • +
  • Questionable: Medium sized courses with no videos

  • +
  • Yes: When you want the largest audience

  • +
  • Yes: When you want without registration required

  • +
  • Yes: When you want good reusability/fast videos

  • +
+
+
+

Future prospects (briefly)

+
    +
  • Streaming probably stays as a CodeRefinery tool

  • +
  • We can scale our courses much larger than they are now. Why don’t +we, together with others?

  • +
  • These tools are useful in other places too

    +
      +
    • I’ve used them to record my own talks to make videos of my +single-person presentations or record conference talks nicer than Zoom.

    • +
    +
  • +
+
+
+

Q&A

+

Q&A from audience

+
+

Keypoints

+
    +
  • Streaming optimizes a course for different things

  • +
  • The disadvantages can be compensated for

  • +
  • There are benefits and disadvantages

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/02-teaching-philosophies/index.html b/branch/community-teaching/02-teaching-philosophies/index.html new file mode 100644 index 0000000..eaf7628 --- /dev/null +++ b/branch/community-teaching/02-teaching-philosophies/index.html @@ -0,0 +1,377 @@ + + + + + + + CodeRefinery teaching philosophies — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CodeRefinery teaching philosophies

+
+

Ice-breaker in groups (20 minutes)

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also +Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+

Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops.

+

It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us.

+
+

Video recordings

+

Recently we have recorded some of the below as videos: +https://www.youtube.com/playlist?list=PLpLblYHCzJAAHF89P-GCjEXWC8CF-7nhX

+
+
+

Anne Fouilloux

+

I regularly teach Carpentries workshops so I try to apply what I have learnt to CodeRefinery workshops. However, I know our target audience is very much different and that I need to adapt my teaching style. I am still trying to find what works best in which situations and this is why I like so much CodeRefinery workshops. We usually have a wider range of skills and very mixed backgrounds so we usually have to be more careful with the pace and time given for exercises.

+

Some considerations:

+
    +
  • I spend quite a lot of time reading the CodeRefinery material and practising myself exercises. I particularly like to read the instructor notes just before teaching: they usually highlight important aspects both for preparing and teaching.

  • +
  • I usually do not show too much in advance the material as I think it prevents asking questions. If you have less competent practitioners in the classroom, they can easily copy-paste to avoid slowing down the entire classroom.

  • +
  • Ideally, I’d like to give several exercises so anyone can work at its own pace. I find it is important that everybody gets something different from the workshop.

  • +
  • I love breaks as it gives us an opportunity to discuss with attendees on their research topics. I am especially interested to understand what software they write and how they plan to use what they learn during our workshops.

  • +
+
+
+

Bjørn Lindi

+

My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this “BLOB” (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the “BLOB”, to be able to share it with others.

+

In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic.

+

When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson.

+

Tools that I find useful in preparing a lesson is concept maps and Learner Personas, though I have develop to few them.

+ +
+
+

Thor Wikfeldt

+

I never want to leave any learner behind and I really don’t like seeing confused, blank faces in the classroom. +At the same time I sometimes worry about some participants getting bored if a lesson is progressing slowly. +This is always a difficult compromise and something I struggle with!

+

I try to focus on making concepts intuitive, to “make sense” to the learners. Of course this is usually +based on how I learned the topic myself and how it makes sense to me.

+

I try to establish connections between topics: “this thing here is similar to what we saw in the previous +lesson where we learned about X…”.

+

Before mastering a lesson by teaching in many times I try to “follow the script”. After becoming very +familiar with a lesson I start to improvise more and react more dynamically to questions, e.g. by taking a +detour to explain a confusing topic more clearly.

+

What I think I do too often: copy-paste code/text from lesson material. This can leave learners behind - +typing out the code and describing it is slower, but more learning takes place. More advanced learners +will hopefully “be compensated” by interesting advanced exercises which follow.

+
+
+

Stefan Negru

+

A lesson is a conversation, it is useful if both the trainer and the trainee are engaged. +For that reason I try to have, most of the time, a conversation with the classroom and +after we finish parts of a lesson, step back and see how we might use what we learned.

+

That brings me to another point I follow throughout the lessons, answering questions like:

+
    +
  • How can we apply in practice what we just learned?

  • +
  • Do you see yourself (the trainee) using that in practice, why or why not?

  • +
+

Most of the times those seem like open-ended questions to the trainees that just learned +something new, so I try to find examples, most of the times from personal experience.

+

Last thing is that analogies are important when I teach, I try to find analogies in order +to simplify a convoluted part of a lesson.

+
+
+

Radovan Bast

+

My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos.

+

My goal for a lesson is to spark curiosity to try things after the lesson, +both for the novices (“This looks like a useful tool, I want to try using it +after the workshop.”) and the more experienced participants (“Aha - I did not +know you could do this. I wonder whether I can make it work with X.”). I like +to start lessons with a question because this makes participants look up from +their browsers.

+

Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise.

+

For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate +the answer.

+

I try to avoid jargon and “war stories” from the professional developers’ +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid “customer”, +“production”, also a lot of Agile jargon is hard to relate to.

+

Less and clear is better than more and unclear. Simple examples are better +than complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +“simply”, “just”, “easy”. If participants take home one or two points from +a lesson, that’s for me success.

+

I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don’t want to +be surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or +slide. This allows me to skip and distill the essence and not read bullet +point by bullet point.

+

I try to never deviate from the script and if I do, be very explicit about +it.

+

A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel.

+

I find it very helpful if there is somebody else in the room who helps me +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson but when doing that to +others, I am often worried of interrupting their flow and timing too much.

+

A mistake I often do is to type too fast and in my mind I force myself +to slow down.

+
+
+

Sabry Razick

+

My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case.

+
+
+

Juho Lehtonen

+

I’m gradually realising the different ways to get a hint whether the workshop +participants are still following or perhaps bored. I assume it’s communicating +with the class, with exercises and simply by asking now and then. I also try +to remember to observe how people look like (puzzled, bored) while I teach, not +so obvious for me.

+

I believe that learners communicating with each other, in addition to with +instructors and helpers, really helps them to understand things faster. (At least +it helps me). So I try to make sure that no one sits or works alone at the workshops.

+
+
+

Richard Darst

+

Like many people, I’ve often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I’ve realized long ago that my most important lessons weren’t +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I’ve realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds.

+

My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I’m often start at the +very basics, because this is what I see missing most often.

+

When teaching, I like lots of audience questions and don’t mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don’t have to know everything perfectly, just show how +you’d approach a problem.

+
+
+

João M. da Silva

+

I started giving technical trainings twenty years ago, and hence my perspective +is perhaps more inclined towards the development of hands-on abilities and +capability to solve problems, independently or in a team.

+

But the development of hands-on practical skills, requires some essential +knowledge about the domain and some willingness to try different approaches +in case one gets stuck. Some call this the “KSA approach” +(“Knowledge-Skills-Attitude). Hence, I +try to impart the essential knowledge (and where to find out more) at my +trainings. And to encourage and challenge students in order to make them +overcome their self-perceived limits (e.g. “I’m a Humanist, I can’t use +Python virtualenv”).

+

I’ve been trying to study more about the Cognitive aspects of learning over the years, +and I should find out the time to return to that. There’s very interesting +research in Problem Solving, with Learning being a important component in that domain.

+

Storytelling: humans are neurologically made for paying attention to good +stories, and that’s something that I try to put into account: to give +a lesson like it would be a relevant narrative for the students, one that they +could relate to and help them in their work

+

I like to draw and be creative with that, but have to pay attention to +my handwriting during my trainings. I reckon that Architectural diagrams +help students to understand the big picture, so I should invest more on +those when development training material. I would also like to start looking into +Concept Maps and Semantic Trees in training.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/03-teaching-style/index.html b/branch/community-teaching/03-teaching-style/index.html new file mode 100644 index 0000000..896248e --- /dev/null +++ b/branch/community-teaching/03-teaching-style/index.html @@ -0,0 +1,508 @@ + + + + + + + Interactive teaching style — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Interactive teaching style

+
+

What are the top issues new instructors face?

+ +
+
+
+

The Carpentries and CodeRefinery approaches to teaching

+

Here we will give you a very short overview of the Carpentries approach to teaching and highlight +parts that are most important for teaching CodeRefinery style lessons.

+

Most CodeRefinery instructors have completed the +Carpentry instructor training workshop, which +anyone can apply for

+
+

This material

+

This section is derived from the +Carpentries instructor training material. +We encourage you to further study this material later, and to sign up for a 2-day Carpentry +intructor training workshop.

+
+
+
+

Key principles

+

The “Carpentries” approach to teaching is based on:

+
    +
  • Applying research-based teaching principles, especially as they apply to the +Carpentries audience.

  • +
  • Understanding the importance of a respectful and inclusive classroom environment.

  • +
+
+

Carpentries teaching principles

+
    +
  • Learners need to practice what they are learning in real time and get feedback on what they +are doing. That is why the teaching approach relies on live coding.

  • +
  • Learners best learn in a respectful classroom environment, so the Carpentries use a +Code of Conduct.

  • +
  • Learners are encouraged to help each other during workshops as this improves their confidence +and reinforces concepts taught.

  • +
  • Carpentry instructors try to have learners do something that they think is useful in their +daily work within 15 minutes of starting each lesson.

  • +
+

What to Teach

+

In CodeRefinery, we follow The Carpentries teaching principles but in addition to live coding +we often use group discussions to put in context the concepts we are teaching.

+

Applying these teaching principles are not sufficient and in addition we need to be able to check +the effectiveness of our methods.

+
+
+
+
+

On the importance of feedback

+

Feedback is an essential part of effective learning. Feedback is bi-directional:

+
    +
  • To be effective, instructors need feedback on their learners’ progress. Learners can also check their progress and ask relevant questions to get clarification.

  • +
  • Instructors also need feedback on their teaching. For instance, this can help them to adapt the pace, add/skip optional exercises and improve their teaching.

  • +
+
+

Getting/giving feedback on learners’ progress

+

This feedback comes through what is called formative assessments (in contrast +to summative assessment).

+
+

Summative Assessment

+

Summative assessment is used +to judge whether a learner has reached an acceptable level of competence. +Usually at the end of a course +Learners either “pass” or “fail” a summative assessment. +One example is a driving exam, +which tells the rest of society whether someone can safely be allowed on the road. Most assessment done in university +courses is summative, and is used to assign course grades.

+
+
+

Formative assessment

+

Formative assessment takes place during teaching and learning. It sounds like +a fancy term, but it can be used to describe any interaction or activity +that provides feedback to both instructors and learners about learners’ level of understanding of the +material. For learners, this feedback can help focus their study efforts. For instructors, it allows them to refocus +their instruction to respond to challenges that learners are facing. +Used continuously

+
+

Learners don’t “pass” or “fail” formative assessments; they are simply a feedback mechanism. +For example, a music teacher might ask a learner to play a scale very slowly +in order to see whether they are breathing correctly, +and if not, what they should change.

+

Formative assessment is most useful when it happens frequently (we’ll talk about how frequently later) +and when the results are easily interpretable by the learner and instructor.

+

CodeRefinery uses different instruments to get feedback from learners:

+
    +
  • Surveys: we will discuss about CodeRefinery pre/post-surveys in the episode +Running a workshop: online.

  • +
  • Exercises: we have many exercises during CodeRefinery workshops and use polls too but not necessarily many multiple-choice questions. +This is something that we may change in the future but the initial reason was that we build on existing knowledge +(see below section on our target audience) and give recommendations for best software practices: +there is no unique solution and you would like our learners to choose the approach that is most suitable for them. +For the same reasons, we have many optional exercises to accommodate the different levels. +We would like everyone to get something useful out of the CodeRefinery workshops.

  • +
+
+
+

Getting/giving feedback on teaching

+

Teaching is a skill. One of the objective of the CodeRefinery Instructor training is to give you +the confidence in teaching CodeRefinery lessons. Later we will have group work where we will +practice teaching some lessons.

+

Before doing so, we will learn here to give feedback on teaching using the same +positive-vs-negative and content-vs-presentation rubric.

+
+

Give feedback on teaching (optional, 10 mn)

+

This exercise aims at learning to give feedback. It is optional as we have +similar exercises when practising teaching). +As a group, we will watch this video of teaching and +give feedback on two axes: positive vs. negative and content vs. presentation. Have each person in +the class add one point to a 2x2 grid on a whiteboard or in the shared notes (hackMD, etherpad, google doc) without duplicating any points. +For online instructor training event, use breakout room (4-5 persons per group) to facilitate discussion. Then each group reports to the shared notes. +You can use a rubric (used during The Carpentries teaching demos) to help you take notes. +What did other people see that you missed? What did they think that you strongly agree or disagree with?

+
+
+
+
+
+

Who are the learners

+

The first task in teaching is to figure out who your learners are. The Carpentries approach is +based on the work of researchers like Patricia Benner, +who applied the +Dreyfus model of skill acquisition +in her studies of +how nurses progress from novice to expert +(see also books by Benner). +This work indicates that through practice and formal instruction, learners acquire skills and advance +through distinct stages. In simplified form, the three stages of this model are:

+
+

Novices, competent practitioners and experts

+

Novice, Competent Practitioner, Expert

+
    +
  • Novice: someone who doesn’t know what they don’t know, i.e., +they don’t yet know what the key ideas in the domain are or how they relate. +One sign that someone is a novice is that their questions “aren’t even wrong”.

    +
      +
    • Example: A novice learner in a Carpentries workshop might never have heard of the bash +shell, and therefore may have no understanding of how it relates to their file system or +other programs on their computer.

    • +
    • Example HPC: A learner who has never executed a program on remote computer in headless mode

    • +
    • Example HPC: A learner who has no understanding about using a queue system and having a +hard time why a program can not be run directly after login in.

    • +
    +
  • +
  • Competent practitioner: someone who has enough understanding for everyday purposes. +They won’t know all the details of how something works and their understanding may not +be entirely accurate, but it is sufficient for completing normal tasks with normal +effort under normal circumstances.

    +
      +
    • Example: A competent practitioner in a Carpentries workshop might have used the shell +before and understand how to move around directories and use individual programs, but +they might not understand how they can fit these programs together to build scripts +and automate large tasks.

    • +
    • Example: A competent practitioner in a CodeRefinery workshop is someone that understands +the concepts of best software practices and its importance. He/she clearly sees the +benefits of applying best software practices but he/she does not fully know yet how and +what to use for their own projects.

    • +
    • Example HPC: Knows how to establish a connection to a cluster and have submitted jobs. +But may not know how to request optimal amount of resources in a job and how to setup +parallel jobs

    • +
    +
  • +
  • Expert: someone who can easily handle situations that are out of the ordinary.

    +
      +
    • Example: An expert in a Carpentries workshop may have experience writing and running shell +scripts and, when presented with a problem, immediately sees how these skills can be used +to solve the problem.

    • +
    • Example HPC: A learner who has a good understanding of the queue system, parallel processing +and understand how to interpret error reports when something goes wrong and knows how to +get help.

    • +
    +
  • +
+
+
+

Cognitive Development and Mental Models

+

Effective learning is facilitated by the creation of a well-founded mental model. A mental model +is a collection of concepts and facts, along with the relationships between those concepts, which +a person has about a topic. For example, a long-time resident of the United States may have an +advanced understanding of the location of US states, major cities and landmarks, weather patterns, +regional economies and demographic patterns, as well as the relationships among these, compared +with their understanding of these relationships for other countries. In other words, their mental +model of the United States is more complex compared with their mental model of other countries.

+

We can distinguish between a novice and a competent practitioner for a given domain based +on the complexity of their mental models.

+
    +
  • A novice is someone who has not yet built a mental model of the domain. +They therefore reason by analogy and guesswork, borrowing bits and pieces +of their mental models of other domains which seem superficially similar.

  • +
  • A competent practitioner is someone who has a mental model that’s good enough +for everyday purposes. This model does not have to be completely accurate in order +to be useful: for example, the average driver’s mental model of how a car works +probably doesn’t include most of the complexities that a mechanical engineer +would be concerned with.

  • +
+

We could expect a mixture of learners from novice and competent practitioner groups +in HPC training events.

+

Mental Models

+
+
+
+

How “knowledge” gets in the way

+

Mental models are hardly ever built from scratch. Every learner comes to a topic with +some amount of information, ideas and opinions about the topic. This is true even in +the case where a learner can’t articulate their prior knowledge and beliefs.

+

In many cases, this prior knowledge is incomplete or inaccurate. Inaccurate beliefs +can be termed “misconceptions” and can impede learning by making it more difficult for +learners to incorporate new, correct information into their mental models. +Correcting learners’ misconceptions is at least as important as presenting them with +correct information. Broadly speaking, misconceptions fall into three categories:

+
    +
  • Simple factual errors, such as believing that Vancouver is the capital of +British Columbia. These are the easiest to correct.

  • +
  • Broken models, such as believing that motion and acceleration must be in the +same direction. We can address these by having learners reason through examples to +see contradictions.

  • +
  • Fundamental beliefs, such as “the world is only a few thousand years old” or +“human beings cannot affect the planet’s climate”. These beliefs are deeply connected +to the learner’s social identity and are the hardest to change.

  • +
+

The current HPC carpentry workshop material are aimed at Novice of HPC

+

Among Novice learners there might be learners who are experts in their domain and very +competent in the program they are executing, but may not have used a HPC system before. +Then among the competent practitioners There might be learners who repeat some procedures +they have inherited but lack a in-depth understanding of what’s going on. That is why it is +important to get accurate feedback, before and during the workshops to understand the learner profiles.

+
+

Exercise: How to identify learner profiles?

+
    +
  1. How to identify leaner profiles from surveys and during the class

  2. +
  3. Which types of learners should the leassons focus on

  4. +
+
+
+
+
+
+

CodeRefinery Curriculum and Reverse Instructional Design (with recommendations for HPC carpentries)

+

When writing a CodeRefinery lesson, we take a “reverse” approach to instruction, +as described in Wiggins and McTighe’s +Understanding by Design, +that keeps the focus firmly on learning outcomes. The order of preparation in this case becomes

+
    +
  • Determine your learning objectives

  • +
  • Decide what constitutes evidence that objectives have been met, and design assessments +to target that evidence

  • +
  • Design instruction: Sort assessments in order of increasing complexity, +and write content that connects everything together

  • +
+
+

Working with learning objectives

+

Each CodeRefinery lesson (also the HPC capentries lessons) usually has a learning objectives section. +Good learning objectives are quite specific about the intended effect of a lesson on its learners. +We aim to create learning objectives that are specific, accurate, and informative for +both learners and instructors.

+
+
+

Using Bloom’s Taxonomy to write effective learning objectives

+

Bloom’s Taxonomy is a framework for thinking about learning that breaks progress down into discrete, hierarchical steps. +While many ideas have come and gone in education, Bloom’s has remained a useful tool for educators, in particular because the +hierarchy seems to be reasonably valid: outcomes at the top of the hierarchy cannot be achieved without mastery of outcomes at +the bottom. In the long term, everybody wants to be at the top. However, in aiming to meet learners where they are, we also +need to be mindful about helping them to “grow a level,” helping them to recognize when they have achieved that growth, and +guiding them to look ahead to where we might not be able to take them.

+

Bloom's Taxonomy

+

Image credit: Vanderbilt University Center for Teaching

+
+
+

Revisiting Learning objectives

+

When using existing teaching material, reverse instructional design principles might be applied as +follows:

+
    +
  1. Review the lesson’s learning objectives carefully, thinking about how they will work for your audience

  2. +
  3. Scan the lesson to identify promising points to check in with your learners, using formative assessment to verify that objectives have been met

  4. +
  5. Review the connecting content in detail to be sure everything works and you have anticipated likely problems and questions.

  6. +
+

We strongly encourage you to read them before teaching a lesson and to review whether they still match the content of the lesson:

+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/_sources/02-teaching-philosophies.md.txt b/branch/community-teaching/_sources/02-teaching-philosophies.md.txt new file mode 100644 index 0000000..66bae95 --- /dev/null +++ b/branch/community-teaching/_sources/02-teaching-philosophies.md.txt @@ -0,0 +1,237 @@ +--- +layout: episode +title: "Our teaching philosophies" +teaching: 0 +exercises: 30 +questions: + - "What are our teaching philosophies?" +--- + +# CodeRefinery teaching philosophies + +> ## Ice-breaker in groups (20 minutes) +> +> - Share your approach to teaching and your teaching philosophy with your group. +> - Please share your tricks and solutions in the live document for others. +> +> Additional ice-breaker questions: +> - What is your motivation for taking this training? +> - How structured or informal are your own teaching needs? +> - What difference do you notice between the teaching what we (also +> Carpentries) do and traditional academic teaching? +> - What other skills need to be taught, but academic teaching isn't the right setting? +{: .challenge} + +--- + +Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops. + +It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us. + +> ## Video recordings +> +> Recently we have recorded some of the below as videos: +> +{: .prereq} + +> ## Anne Fouilloux +> +> I regularly teach Carpentries workshops so I try to apply what I have learnt to CodeRefinery workshops. However, I know our target audience is very much different and that I need to adapt my teaching style. I am still trying to find what works best in which situations and this is why I like so much CodeRefinery workshops. We usually have a wider range of skills and very mixed backgrounds so we usually have to be more careful with the pace and time given for exercises. +> +> Some considerations: +> - I spend quite a lot of time reading the CodeRefinery material and practising myself exercises. I particularly like to read the instructor notes just before teaching: they usually highlight important aspects both for preparing and teaching. +> - I usually do not show too much in advance the material as I think it prevents asking questions. If you have less competent practitioners in the classroom, they can easily copy-paste to avoid slowing down the entire classroom. +> - Ideally, I'd like to give several exercises so anyone can work at its own pace. I find it is important that everybody gets something different from the workshop. +> - I love breaks as it gives us an opportunity to discuss with attendees on their research topics. I am especially interested to understand what software they write and how they plan to use what they learn during our workshops. +{: .challenge} + +> ## Bjørn Lindi +> +> My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this "BLOB" (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the "BLOB", to be able to share it with others. +> +>In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic. +> +>When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson. +> +>Tools that I find useful in preparing a lesson is concept maps and Learner Personas, though I have develop to few them. +>- [Concept Maps](https://teachtogether.tech/#s:memory-concept-maps) +>- [Learner Personas](https://teachtogether.tech/#s:process-personas) +{: .challenge} + +> ## Thor Wikfeldt +> +> I never want to leave any learner behind and I really don't like seeing confused, blank faces in the classroom. +> At the same time I sometimes worry about some participants getting bored if a lesson is progressing slowly. +> This is always a difficult compromise and something I struggle with! +> +> I try to focus on making concepts intuitive, to "make sense" to the learners. Of course this is usually +> based on how I learned the topic myself and how it makes sense to me. +> +> I try to establish connections between topics: "this thing here is similar to what we saw in the previous +> lesson where we learned about X...". +> +> Before mastering a lesson by teaching in many times I try to "follow the script". After becoming very +> familiar with a lesson I start to improvise more and react more dynamically to questions, e.g. by taking a +> detour to explain a confusing topic more clearly. +> +> What I think I do too often: copy-paste code/text from lesson material. This can leave learners behind - +> typing out the code and describing it is slower, but more learning takes place. More advanced learners +> will hopefully "be compensated" by interesting advanced exercises which follow. +{: .challenge} + +> ## Stefan Negru +> +> A lesson is a conversation, it is useful if both the trainer and the trainee are engaged. +> For that reason I try to have, most of the time, a conversation with the classroom and +> after we finish parts of a lesson, step back and see how we might use what we learned. +> +> That brings me to another point I follow throughout the lessons, answering questions like: +> * How can we apply in practice what we just learned? +> * Do you see yourself (the trainee) using that in practice, why or why not? +> +> Most of the times those seem like open-ended questions to the trainees that just learned +> something new, so I try to find examples, most of the times from personal experience. +> +> Last thing is that analogies are important when I teach, I try to find analogies in order +> to simplify a convoluted part of a lesson. +{: .challenge} + +> ## Radovan Bast +> +> My teaching changed by 180 degrees after taking the Carpentries instructor +> training. Before that I used slides, 45 minute lecture blocks, and separate +> exercise sessions. After the Carpentries instructor training I embraced the +> interaction, exercises, demos, and typos. +> +> My goal for a lesson is to spark curiosity to try things after the lesson, +> both for the novices ("This looks like a useful tool, I want to try using it +> after the workshop.") and the more experienced participants ("Aha - I did not +> know you could do this. I wonder whether I can make it work with X."). I like +> to start lessons with a question because this makes participants look up from +> their browsers. +> +> Keeping both the novices and the experts engaged during a lesson can be +> difficult and offering additional exercises seems to be a good compromise. +> +> For me it is a good sign if there are many questions. I like to encourage +> questions by asking questions to the participants. But I also try not to go +> into a rabbit hole when I get a question where only experts will appreciate +> the answer. +> +> I try to avoid jargon and "war stories" from the professional developers' +> perspective or the business world. Most researchers may not relate to them. +> For examples I always try to use the research context. Avoid "customer", +> "production", also a lot of Agile jargon is hard to relate to. +> +> Less and clear is better than more and unclear. Simple examples are better +> than complicated examples. Almost never I have felt or got the feedback that +> something was too simple. I am repeating in my head to not use the words +> "simply", "just", "easy". If participants take home one or two points from +> a lesson, that's for me success. +> +> I prepare for the lesson by reading the instructor guide and all issues and +> open pull requests. I might not be able to solve issues, but I don't want to +> be surprised by known issues. I learn the material to a point where I know +> precisely what comes next and am never surprised by the next episode or +> slide. This allows me to skip and distill the essence and not read bullet +> point by bullet point. +> +> I try to never deviate from the script and if I do, be very explicit about +> it. +> +> A great exercise I can recommend is to watch a tutorial on a new programming +> language/tool you have never used. It can feel very overwhelming and fast to +> get all these new concepts and tools thrown at self. This can prepare me for +> how a participant might feel. +> +> I find it very helpful if there is somebody else in the room who helps me +> detecting when I go too fast or become too confusing. I like when two +> instructors complement each other during a lesson but when doing that to +> others, I am often worried of interrupting their flow and timing too much. +> +> A mistake I often do is to type too fast and in my mind I force myself +> to slow down. +{: .challenge} + +> ## Sabry Razick +> My approach is to show it is fun to demystify concepts. Once a concept is +> not a mystery anymore, the learners will understand is what it means, where +> it is coming from, why it is in place and what it could it offer for their future. +> I try to relate concepts to real life with a twist of humour whenever possible if +> the outcome is certain not be offensive to any one. I use diagrams whenever possible, +> I have spent weeks creating diagrams that is sometime three or four sentences. That +> effort I consider worthwhile as my intention is not to teach, but to demystify. +> Once that is achieved, learners will learn the nitty gritty on their own easily +> and with confidence, when they have the use-case. +> +> +{: .challenge} + +> ## Juho Lehtonen +> I'm gradually realising the different ways to get a hint whether the workshop +> participants are still following or perhaps bored. I assume it's communicating +> with the class, with exercises and simply by asking now and then. I also try +> to remember to observe how people look like (puzzled, bored) while I teach, not +> so obvious for me. +> +> I believe that learners communicating with each other, in addition to with +> instructors and helpers, really helps them to understand things faster. (At least +> it helps me). So I try to make sure that no one sits or works alone at the workshops. +{: .challenge} + +> ## Richard Darst +> +> Like many people, I've often been teaching, but rarely a teacher. I +> tend to teach like I am doing an informal mentorship. +> I've realized long ago that my most important lessons weren't +> learned in classes, but by a combination of seeing things done by +> friends and independent study after that. I've realized that +> teaching (the things I teach) is trying to correct these differences +> in backgrounds. +> +> My main job is supporting computing infrastructure, so my teaching +> is very grounded in real-world problems. I'm often start at the +> very basics, because this is what I see missing most often. +> +> When teaching, I like lots of audience questions and don't mind +> going off-script a bit (even though I know it should be minimized). +> I find that sufficient audience interest allows any lesson to be a +> success - you don't have to know everything perfectly, just show how +> you'd approach a problem. +> +{: .challenge} + +> ## João M. da Silva +> +> I started giving technical trainings twenty years ago, and hence my perspective +> is perhaps more inclined towards the development of hands-on abilities and +> capability to solve problems, independently or in a team. +> +> But the development of hands-on practical skills, requires some essential +> knowledge about the domain and some willingness to try different approaches +> in case one gets stuck. Some call this the "KSA approach" +> ("Knowledge-Skills-Attitude). Hence, I +> try to impart the essential knowledge (and where to find out more) at my +> trainings. And to encourage and challenge students in order to make them +> overcome their self-perceived limits (e.g. "I'm a Humanist, I can't use +> Python virtualenv"). +> +> I've been trying to study more about the Cognitive aspects of learning over the years, +> and I should find out the time to return to that. There's very interesting +> research in Problem Solving, with Learning being a important component in that domain. +> +> Storytelling: humans are neurologically made for paying attention to good +> stories, and that's something that I try to put into account: to give +> a lesson like it would be a relevant narrative for the students, one that they +> could relate to and help them in their work +> +> I like to draw and be creative with that, but have to pay attention to +> my handwriting during my trainings. I reckon that Architectural diagrams +> help students to understand the big picture, so I should invest more on +> those when development training material. I would also like to start looking into +> Concept Maps and Semantic Trees in training. +{: .challenge} diff --git a/branch/community-teaching/_sources/03-teaching-style.md.txt b/branch/community-teaching/_sources/03-teaching-style.md.txt new file mode 100644 index 0000000..8164130 --- /dev/null +++ b/branch/community-teaching/_sources/03-teaching-style.md.txt @@ -0,0 +1,336 @@ +--- +layout: episode +title: "Carpentries and CodeRefinery approach to teaching" +teaching: 30 +exercises: 30 +questions: + - "What pedagogical concepts underpin CodeRefinery and Carpentry workshops?" + - "How to get and give feedback?" + - "Who are the CodeRefinery learners?" + - "Why is it important to define learning objectives?" +objectives: + - "Explain The Carpentries and CodeRefinery approaches to teaching" + - "Understand what is meant by feedback, cognitive development, mental models and reverse instructional design" + - "Explain and practice important pedagogical concepts" +keypoints: + - "CodeRefinery lessons and teaching build on these principles" +--- +# Interactive teaching style + + +## What are the top issues new instructors face? + +```{solution} + - Breaks are not negotiable, minimum 10 minutes. + - Breakout sessions too short. Make them as long as possible, don't expect to come back for + new intro, then go back. + - Get the speed correct. Not too fast and not too slow. + - People will accomplish less than you expect. Expect learners to be 5 times slower than you, at best! + - All the other tools and stuff will go wrong. Try to not bring in a dependency when you don't need it. + - Trying to accomplish too much: it's OK to cut out and adapt to the audience. + Have a reserve session at the end you prepare, but are ready to skip. + - Explaining how, but not why. + - Running out of time to making your environment match the learner's. + - Running out of time to set up good screen sharing practices + - (terminal history, portion of screen, remote history) in advance. + - Assuming learners remember what they have already learned, or know the prerequisites. Or have stuff installed and configured. + - Not managing expectations: learners think that you will accomplish everything, and feel sad when you don't. + - Special issues when lessons delivered online (discussed during Workshop preparation and organization) +``` + + +# The Carpentries and CodeRefinery approaches to teaching + +Here we will give you a very short overview of the Carpentries approach to teaching and highlight +parts that are most important for teaching CodeRefinery style lessons. + +Most CodeRefinery instructors have completed the +[Carpentry instructor training workshop](https://carpentries.github.io/instructor-training/), which +[anyone can apply for](https://carpentries.org/become-instructor/) + +> ## This material +> +> This section is derived from the +> [Carpentries instructor training material](https://carpentries.github.io/instructor-training/). +> We encourage you to further study this material later, and to sign up for a 2-day Carpentry +> intructor training workshop. +{: .callout} + +--- + +## Key principles + +The "Carpentries" approach to teaching is based on: + +- Applying research-based teaching principles, especially as they apply to the + Carpentries audience. +- Understanding the importance of a respectful and inclusive classroom environment. + + +### Carpentries teaching principles + +- Learners need to practice what they are learning in real time and get **feedback** on what they + are doing. That is why the teaching approach relies on **live coding**. +- Learners best learn in a respectful classroom environment, so the Carpentries use a + [Code of Conduct](https://docs.carpentries.org/topic_folders/policies/code-of-conduct.html). +- Learners are encouraged to help each other during workshops as this improves their confidence + and reinforces concepts taught. +- Carpentry instructors try to have learners do something that they think is useful in their + daily work within **15 minutes of starting each lesson**. + +![What to Teach](https://carpentries.github.io/instructor-training/fig/what-to-teach.png) + +In CodeRefinery, we follow The Carpentries teaching principles but in addition to **live coding** +we often use **group discussions** to put in context the concepts we are teaching. + +Applying these teaching principles are not sufficient and in addition we need to be able to check +the effectiveness of our methods. + +--- + +## On the importance of feedback + +Feedback is an essential part of effective learning. Feedback is bi-directional: +- To be effective, instructors need feedback on their learners' progress. Learners can also check their progress and ask relevant questions to get clarification. +- Instructors also need feedback on their teaching. For instance, this can help them to adapt the pace, add/skip optional exercises and improve their teaching. + +### Getting/giving feedback on learners' progress + +This feedback comes through what is called *formative assessments* (in contrast + to *summative assessment*). + +> ## Summative Assessment +> *Summative assessment* is used +> to judge whether a learner has reached an acceptable level of competence. +> Usually at the end of a course +> Learners either "pass" or "fail" a summative assessment. +> One example is a driving exam, +> which tells the rest of society whether someone can safely be allowed on the road. Most assessment done in university +> courses is summative, and is used to assign course grades. +{: .callout} + +> ## Formative assessment +> *Formative assessment* takes place during teaching and learning. It sounds like +> a fancy term, but it can be used to describe any interaction or activity +> that provides feedback to both instructors and learners about learners' level of understanding of the +> material. For learners, this feedback can help focus their study efforts. For instructors, it allows them to refocus +> their instruction to respond to challenges that learners are facing. +> Used continuously +{: .callout} + +Learners don't "pass" or "fail" formative assessments; they are simply a feedback mechanism. +For example, a music teacher might ask a learner to play a scale very slowly +in order to see whether they are breathing correctly, +and if not, what they should change. + +Formative assessment is most useful when it happens frequently (we'll talk about how frequently later) +and when the results are easily interpretable by the learner and instructor. + + +CodeRefinery uses different instruments to get feedback from learners: + +- Surveys: we will discuss about CodeRefinery pre/post-surveys in the episode + {doc}`workshops-online`. +- Exercises: we have many exercises during CodeRefinery workshops and use polls too but not necessarily many multiple-choice questions. + This is something that we may change in the future but the initial reason was that we build on existing knowledge + (see below section on our target audience) and give recommendations for best software practices: + there is no unique solution and you would like our learners to choose the approach that is most suitable for them. + For the same reasons, we have many optional exercises to accommodate the different levels. + We would like everyone to get something useful out of the CodeRefinery workshops. + +### Getting/giving feedback on teaching + +Teaching is a skill. One of the objective of the CodeRefinery Instructor training is to give you +the confidence in teaching CodeRefinery lessons. Later we will have group work where we will +practice teaching some lessons. + +Before doing so, we will learn here to give feedback on teaching using the same +positive-vs-negative and content-vs-presentation rubric. + +> ## Give feedback on teaching (optional, 10 mn) +> This exercise aims at learning to give feedback. It is optional as we have +> similar exercises when {doc}`practising teaching `). +> As a group, we will watch [this video of teaching](https://www.youtube.com/watch?v=-ApVt04rB4U) and +> give feedback on two axes: positive vs. negative and content vs. presentation. Have each person in +> the class add one point to a 2x2 grid on a whiteboard or in the shared notes (hackMD, etherpad, google doc) without duplicating any points. +> For online instructor training event, use breakout room (4-5 persons per group) to facilitate discussion. Then each group reports to the shared notes. +> You can use a [rubric](http://carpentries.github.io/instructor-training/demos_rubric/) (used during The Carpentries teaching demos) to help you take notes. +> What did other people see that you missed? What did they think that you strongly agree or disagree with? +> +{: .challenge} + +--- + +## Who are the learners + +The first task in teaching is to figure out who your learners are. The Carpentries approach is +based on the work of researchers like [Patricia Benner](https://en.wikipedia.org/wiki/Patricia_Benner), +who applied the +[Dreyfus model of skill acquisition](https://en.wikipedia.org/wiki/Dreyfus_model_of_skill_acquisition) +in her studies of +[how nurses progress from novice to expert](http://journals.sagepub.com/doi/10.1177/0270467604265061) +([see also books by Benner](https://www.worldcat.org/search?q=au%3ABenner%2C+Patricia+E.&qt=hot_author)). +This work indicates that through practice and formal instruction, learners acquire skills and advance +through distinct stages. In simplified form, the three stages of this model are: + +### Novices, competent practitioners and experts + +![Novice, Competent Practitioner, Expert](https://carpentries.github.io/instructor-training/fig/skill-level.svg) + +* *Novice*: someone who doesn't know what they don't know, i.e., + they don't yet know what the key ideas in the domain are or how they relate. + One sign that someone is a novice is that their questions "aren't even wrong". + + - Example: A *novice* learner in a Carpentries workshop might never have heard of the bash + shell, and therefore may have no understanding of how it relates to their file system or + other programs on their computer. + + - Example HPC: A learner who has never executed a program on remote computer in headless mode + + - Example HPC: A learner who has no understanding about using a queue system and having a + hard time why a program can not be run directly after login in. + +* *Competent practitioner*: someone who has enough understanding for everyday purposes. + They won't know all the details of how something works and their understanding may not + be entirely accurate, but it is sufficient for completing normal tasks with normal + effort under normal circumstances. + + - Example: A *competent practitioner* in a Carpentries workshop might have used the shell + before and understand how to move around directories and use individual programs, but + they might not understand how they can fit these programs together to build scripts + and automate large tasks. + + - Example: A *competent practitioner* in a CodeRefinery workshop is someone that understands + the concepts of best software practices and its importance. He/she clearly sees the + benefits of applying best software practices but he/she does not fully know yet how and + what to use for their own projects. + + - Example HPC: Knows how to establish a connection to a cluster and have submitted jobs. + But may not know how to request optimal amount of resources in a job and how to setup + parallel jobs + + +* *Expert*: someone who can easily handle situations that are out of the ordinary. + + - Example: An *expert* in a Carpentries workshop may have experience writing and running shell + scripts and, when presented with a problem, immediately sees how these skills can be used + to solve the problem. + + - Example HPC: A learner who has a good understanding of the queue system, parallel processing + and understand how to interpret error reports when something goes wrong and knows how to + get help. + + +### Cognitive Development and Mental Models + +Effective learning is facilitated by the creation of a well-founded mental model. A mental model +is a collection of concepts and facts, along with the relationships between those concepts, which +a person has about a topic. For example, a long-time resident of the United States may have an +advanced understanding of the location of US states, major cities and landmarks, weather patterns, +regional economies and demographic patterns, as well as the relationships among these, compared +with their understanding of these relationships for other countries. In other words, their mental +model of the United States is more complex compared with their mental model of other countries. + +We can distinguish between a *novice* and a *competent practitioner* for a given domain based +on the complexity of their mental models. + +* A *novice* is someone who has not yet built a mental model of the domain. + They therefore reason by analogy and guesswork, borrowing bits and pieces + of their mental models of other domains which seem superficially similar. +* A *competent practitioner* is someone who has a mental model that's good enough + for everyday purposes. This model does not have to be completely accurate in order + to be useful: for example, the average driver's mental model of how a car works + probably doesn't include most of the complexities that a mechanical engineer + would be concerned with. + +We could expect a mixture of learners from *novice* and *competent practitioner* groups +in HPC training events. + +![Mental Models](https://carpentries.github.io/instructor-training/fig/mental_models.svg) + +--- + +### How “knowledge” gets in the way + +Mental models are hardly ever built from scratch. Every learner comes to a topic with +some amount of information, ideas and opinions about the topic. This is true even in +the case where a learner can’t articulate their prior knowledge and beliefs. + +In many cases, this prior knowledge is incomplete or inaccurate. Inaccurate beliefs +can be termed “misconceptions” and can impede learning by making it more difficult for +learners to incorporate new, correct information into their mental models. +Correcting learners’ misconceptions is at least as important as presenting them with +correct information. Broadly speaking, misconceptions fall into three categories: + +- **Simple factual errors**, such as believing that Vancouver is the capital of + British Columbia. These are the easiest to correct. +- **Broken models**, such as believing that motion and acceleration must be in the + same direction. We can address these by having learners reason through examples to + see contradictions. +- **Fundamental beliefs**, such as “the world is only a few thousand years old” or + “human beings cannot affect the planet’s climate”. These beliefs are deeply connected + to the learner’s social identity and are the hardest to change. + + +The current HPC carpentry workshop material are aimed at **Novice** of HPC + +Among *Novice* learners there might be learners who are experts in their domain and very +competent in the program they are executing, but may not have used a HPC system before. +Then among the **competent practitioners** There might be learners who repeat some procedures +they have inherited but lack a in-depth understanding of what's going on. That is why it is +important to get accurate feedback, before and during the workshops to understand the learner profiles. + + +> ## Exercise: How to identify learner profiles? +> +> 1. How to identify leaner profiles from surveys and during the class +> 2. Which types of learners should the leassons focus on +{: .challenge} + +--- + +## CodeRefinery Curriculum and Reverse Instructional Design (with recommendations for HPC carpentries) + +When writing a CodeRefinery lesson, we take a “reverse” approach to instruction, +as described in Wiggins and McTighe’s +[Understanding by Design](http://www.worldcat.org/title/understanding-by-design/oclc/56491025), +that keeps the focus firmly on learning outcomes. The order of preparation in this case becomes + +- Determine your learning objectives +- Decide what constitutes evidence that objectives have been met, and design assessments + to target that evidence +- Design instruction: Sort assessments in order of increasing complexity, + and write content that connects everything together + +### Working with learning objectives + +Each CodeRefinery lesson (also the HPC capentries lessons) usually has a *learning objectives* section. +Good learning objectives are quite specific about the intended effect of a lesson on its learners. +We aim to create learning objectives that are specific, accurate, and informative for +both learners and instructors. + + +### Using Bloom's Taxonomy to write effective learning objectives + +[Bloom's Taxonomy](https://cft.vanderbilt.edu/guides-sub-pages/blooms-taxonomy/) is a framework for thinking about learning that breaks progress down into discrete, hierarchical steps. +While many ideas have come and gone in education, Bloom's has remained a useful tool for educators, in particular because the +hierarchy seems to be reasonably valid: outcomes at the top of the hierarchy cannot be achieved without mastery of outcomes at +the bottom. In the long term, everybody wants to be at the top. However, in aiming to meet learners where they are, we also +need to be mindful about helping them to ["grow a level,"](https://software-carpentry.org/blog/2018/03/tractenberg-summary.html) helping them to recognize when they have achieved that growth, and +guiding them to look ahead to where we might not be able to take them. + +![Bloom's Taxonomy](https://carpentries.github.io/instructor-training/fig/Blooms.png) + +Image credit: Vanderbilt University Center for Teaching + +### Revisiting Learning objectives + +When using existing teaching material, *reverse instructional design* principles might be applied as +follows: + +1. Review the lesson's learning objectives carefully, thinking about how they will work for your audience +2. Scan the lesson to identify promising points to check in with your learners, using formative assessment to verify that objectives have been met +3. Review the connecting content in detail to be sure everything works and you have anticipated likely problems and questions. + + +We strongly encourage you to read them before teaching a lesson and to review whether they still match the content of the lesson: diff --git a/branch/community-teaching/_sources/about-coderefinery.md.txt b/branch/community-teaching/_sources/about-coderefinery.md.txt new file mode 100644 index 0000000..fac5c92 --- /dev/null +++ b/branch/community-teaching/_sources/about-coderefinery.md.txt @@ -0,0 +1,100 @@ +# About the CodeRefinery project and CodeRefinery workshops + +```{keypoints} +- Teaches intermediate-level software development tool lessons +- Training network for other lessons, too +- Publicly-funded discrete projects (3 projects actually) transitioning towards an open community project +- We have online material, teaching, and exercise sessions +- We want more people to work with us, and to work with more people +``` + +CodeRefinery is a +[Nordic e-Infrastructure Collaboration (NeIC)](https://neic.no/) +project that has started in October 2016 and is +funded until February 2025. + +The funding from 2022-2025 is designed to keep this project active +beyond 2025 by forming a support network and building a community of +instructors and contributors. + +```{discussion} History + +The CodeRefinery project idea grew out of two [SeSE](http://sese.nu) courses given at KTH Stockholm in 2014 and 2016: +- [http://sese.nu/scientific-software-development-toolbox/](http://sese.nu/scientific-software-development-toolbox/) +- [http://sese.nu/scientific-software-development-toolbox-2016/](http://sese.nu/scientific-software-development-toolbox-2016/) + +The project proposal was submitted to NeIC in 2015, accepted in 2015, and started in 2016. + +We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form. +``` + + +## Main goals + +- Develop and maintain **training material on software best practices** for researchers that already write code. Our material addresses all academic disciplines and tries to be as programming language-independent as possible. +- Provide a [code repository hosting service](https://coderefinery.org/repository/) that is open and free for all researchers based in universities and research institutes from Nordic countries. +- Provide **training opportunities** in the Nordics using Carpentries and CodeRefinery training materials. +- Articulate and implement the CodeRefinery **sustainability plan**. + + +## Impact + +We collect feedback and survey results to measure our impact. + +3-6 months after attending a workshop, past participants are asked to complete a short post-workshop survey. +The survey questions aim to establish what impact CodeRefinery workshops have on how past participants develop +research software. + +[Pre- and post-workshop survey results](https://coderefinery.org/about/impact/) + +- Overall quality of research software has improved: more reusable, modular, reproducible and documented. +- Collaboration on research software development has become easier +- Past participants share their new knowledge with colleagues +- Usage of several tools is improved, and new tools are adopted + +[Free-form answers](https://coderefinery.org/#what-do-our-participants-say-after-attending-a-workshop) +also suggest that workshops are having the intended effects on how people develop code. A common theme is: +> *I wish I had known this stuff already as a grad student 10+ years ago...* + +We would love to get suggestions on how we can better quantify our impact. This +would make it easier for us to convince institutions to partner with us and +also open up funding opportunities. + + +## Target audience + +### Carpentries audience + +The Carpentries aims to teach computational **competence** to learners through an applied approach, avoiding the theoretical and general in favor of the practical and specific. + +**Learners do not need to have any prior experience in programming.** One major goal of a Carpentry workshop is to raise awareness on the tools researchers can learn/use to speed up their research. + +By showing learners how to solve specific problems with specific tools and providing hands-on practice, learners develops confidence for future learning. + +> ## Novices +> We often qualify Carpentry learners as **novices**: they do not know what they need to learn yet. A typical example is the usage of version control: the Carpentry `git` lesson aims to give a very high level conceptual overview of Git but it does not explain how it can be used in research projects. +{: .callout} + + +### CodeRefinery audience + +In that sense, CodeRefinery workshops differ from Carpentry workshops as we assume our audience already writes code and scripts and we aim at teaching them **best software practices**. + +Our learners usually do not have a good overview of **best software practices** but are aware of the need to learn them. Very often, they know the tools (Git, Jupyter, etc.) we are teaching but have difficulties to make the best use of them in their software development workflow. + +Whenever we can, we should direct learners that do not have sufficient coding experience to Carpentries workshops. + +> ## Competent practitioners +> We often qualify CodeRefinery learners as **competent practitioners** because they already have an understanding of their needs. +> *Novices* and *competent practitioners* will be more clearly defined in the {doc}`next section <03-teaching-style>`. +{: .callout} + +> ## Best software practices for whom? +> It can be useful to ask the question: *best software practices for whom*? +> CodeRefinery teaches *best software practices* derived from producing and +> shipping software. These practices are also very good for sharing software, +> though our audience will probably not need to embrace *all* aspects of +> software engineering. +{: .callout} diff --git a/branch/community-teaching/_sources/backward-lesson-design.md.txt b/branch/community-teaching/_sources/backward-lesson-design.md.txt new file mode 100644 index 0000000..7f141b0 --- /dev/null +++ b/branch/community-teaching/_sources/backward-lesson-design.md.txt @@ -0,0 +1,152 @@ +(backwards-lesson-design)= + +# Backwards lesson design + +It happens far too often: someone creates a lesson, but they think +about what is interesting to them, not what is important for the +learners. In fact, an earlier version of this instructor training had +this very issue. + +It is critical to backwards design almost any piece of communication, +especially something as widespread as teaching. + + +## The approach + +- You don't think about how to do something and try to explain it. +- Avoid the typical approach *"I want to show a number of things which I think are cool about + tool X - how do I press these into 90 minutes?"* +- Instead, you start defining your target audience by answering to questions + such **What is the expected educational level of my audience?**, **Have they + been already exposed to the technologies I am planning to teach?**, **What + tools do they already use?**, **What are the main issues they are currently + experiencing?**. It is important to discuss these points with a group of + colleagues, preferably from diverse backgrounds and institutions to reduce + biases. Once you clarified your target audience, it is useful to create + **learner personas**; that will help you during the development process by + providing concrete examples of potential learners showing up at your + workshops. For each **learner personas**, try to think of what is **useful to + them**: *"What do they **need** to + [remember/understand/apply/analyze/evaluate/create](https://coderefinery.github.io/instructor-training/03-teaching-style/#using-bloom-s-taxonomy-to-write-effective-learning-objectives)?"*. + Asking and answering to these questions will allow you to define the + background knowledge (starting points) and goals (end points) of your + learners. Then, you create a sequence of exercises which test incrementally + progressing tasks and acquisition of the new skills (from starting to end + points). +- Then, you write the minimum amount + of material to teach the gap between exercises. + + +## The process + +As described in ["A lesson design process" in the book Teaching Tech +Together](https://teachtogether.tech/en/index.html#s:process): + +1. Understand your learners + +2. Brainstorm rough ideas + +3. Create an summative assessment to know your overall goal + + * CodeRefinery translation: think of the things your learners will + be able to do at the end of the lesson. Think simple! The + simpler the better. Think of three main points they will + remember, of which maybe one or two are a concrete skill. + +4. Create formative assessments to go from the starting point to this. + + * CodeRefinery translation: think of some engaging and active + exercises. + +5. Order the formative assessments (exercises) into a reasonable order. + +6. Write just enough material to get from one assessment (exercise) to + another. + +7. Describe the course so the learners know if it is relevant to them. + +We can't emphasize enough how important it is to **know your end +state and keep it simple**. + +```{discussion} Example: designing an HPC Carpentry lesson + +Let's take as an example the *[HPC Carpentry lesson](https://hpc-carpentry.github.io/hpc-intro/)* + +**Target audience** + - What is the expected educational level of my audience? + - A PhD student, postdoc or young researcher. + - Have they been already exposed to the technologies I am planning to teach? + - The word **HPC** is not new to them and they may have already used an HPC but are still not capable of giving a proper definition of HPC. In addition, we do not expect them to know much about parallelism and they cannot make any distinction between various available parallelism paradigms. + - What tools do they already use? + - serial codes, multi-threaded codes, data parallelism; usually out-of-the-box tools. + - they may have tried to "scale" their code (multiprocessing, threading, GPUs) with more or less success. + - What are the main issues they are currently experiencing? + - they cannot solve their problems either because they would like to run the same code but with many different datasets or because their problem is larger (more computations/memory). + - most of the time they know their codes can run on HPC (from the documentation) but never really had the opportunity to try it out. + - Very few will have their own codes where they may have tried different things to speed it up (threading, task parallelism) but have no clear strategy. + +**Learner persona** + - Sonya is a 1st year PhD student: she recently moved to Oslo and joined the + Computational and Systems Neuroscience group. She will be using the + [NEST](https://nest-simulator.readthedocs.io/), a simulator for spiking + neural network model. She used NEST during her master thesis but on her + small cluster: **she never used an HPC resource** and is really excited about it. + - Robert is a field ecologist who obtained his PhD 6 months ago. He is now + working on a new project with Climate scientists and as a consequence will + need to run global climate models. He is **not very familiar with command + line** even though he attended a Software Carpentry workshop and the idea to + use HPC is a bit terrifying. He knows that he will get support from his + team who has extensive experience with HPC but would like to become more + independent and be able to **run his own simulations** (rather than copying + existing cases). + - Jessica is a postdoc working on a project that investigates numerically the + complex dynamics arising at the tip of a fluid-driven rupture. Fluid + dynamics will be computed by a finite element method solving the + compressible Navier-Stokes equations on a moving mesh. She **uses a code she + has developed** during her PhD and that is based on existing libraries. She + has mostly ran it on a local desktop; her work during her PhD was very + limited due to the lack of computing resources and she is now very keen is + **moving to HPC**; she knows that it will requires some work, in particular to + parallelize her code. This HPC training will be her first experience with + HPC. + +**Learning outcomes** + - Understand the difference between HPCs and other local/remote machines + - Understand the notion of core, nodes, cluster, shared/distributed memory, etc. + - Understand the notion of login nodes. + - Understand the need for a scheduler and how to use it appropriately + - Understand why optimising I/O is important on HPC and how to best use HPC filesystems + - Understand the need to parallelize (or use existing parallel) codes and in which cases HPCs is a must (when communications is required) + - Understand how to get your code ready to use on HPC (access to libraries, installation of your own libraries/software, etc.) + - Understand that an HPC is an operational machine and is not meant for developing codes. + +**Exercises** + - Get basic information such the number of CPUs, memory from your laptop and try to do the same on a HPC. Discuss outcomes. + - Try to create files on the different filesystems on your HPC resource and access them. + - Create different types of job scripts, submit and check outputs. + - Make a concrete example to run a specific software on your HPC (something like GROMACS). +``` + + +## Exercises + +```{exercise} Backwards-design a lesson/topic +Choose a simple lesson topic and apply backwards lesson design. You +won't get all the way through, but come up with a logical +progression of exercises. + +The section you pick should require **screen sharing** and be of some **follow-along +task** (preferably using a shell). + +Some suggestions: +- Regular expressions +- Making papers in LaTeX +- Making figures in your favorite programming language +- Linux shell basics +- Something non-technical, such as painting a room +- An instructor training for CodeRefinery +- Some aspect from an already existing lesson +- [Introduction to high-performance computing](https://hpc-carpentry.github.io/hpc-intro/) (or an episode therein) +- [Unix shell in a HPC context](https://hpc-carpentry.github.io/hpc-shell/) (or an episode therein) +- A lesson you always wanted to teach +``` diff --git a/branch/community-teaching/_sources/collaboration-models.rst.txt b/branch/community-teaching/_sources/collaboration-models.rst.txt new file mode 100644 index 0000000..11ea3e6 --- /dev/null +++ b/branch/community-teaching/_sources/collaboration-models.rst.txt @@ -0,0 +1,69 @@ +Collaboration models +==================== + + + +Model: CodeRefinery +------------------- + +* Before Covid-19, workshops were physically around the Nordics, + instructors would travel (or already be there). + + * Maximum size: ~40 people + * High workload per person + +* After several small scaling attempts, now we have: + + * Two large workshops per year - livestream format + * Combined organization efforts + * Instructors from each location - on average two lessons taught. + * Locations with staff can have **local breakout rooms**: physical + place to help during exercises. + +* Others in the world can register and interact using HackMD, but no + promises of help. + +* Content still available to anyone in the world: live + instant + replay. + +* Course page and material: + https://coderefinery.github.io/2022-03-22-workshop/ + + + +Model: Python for Scientific Computing +-------------------------------------- + +* Aalto Scientific Computing wanted to host a course, **Python for + Scientific Computing** +* ASC came up with initial vision and announced it +* ASC hosted an open initial meeting, inviting any interested + organizers or instructors +* We went over the plan and refined the topics and schedule. We also + decided things such as the date, organizers, and instructors for + each lesson. +* Registration was open to everyone in the world, non-Nordic + participants could watch via livestream. +* People prepared their parts and came together and presented. + Organizers kept everything on track. +* **Compared to the amount of effort each person put in, the results + were great.** +* A 2021 version also happened and was even larger. +* Course page: https://scicomp.aalto.fi/training/scip/python-for-scicomp/ +* Material: https://aaltoscicomp.github.io/python-for-scicomp/ + + + +Exercises +--------- + +.. exercise:: List successes and failures in collaborative teaching + + Using HackMD, list some successes and failures in collaborative + teaching that you have experienced. + +.. exercise:: Recommendations for co-teaching + + If you have experience with co-teaching, what approach/technique/trick + can you recommend a colleague who would like to try co-teaching for the + first time? diff --git a/branch/community-teaching/_sources/distributed.md.txt b/branch/community-teaching/_sources/distributed.md.txt new file mode 100644 index 0000000..477f0d2 --- /dev/null +++ b/branch/community-teaching/_sources/distributed.md.txt @@ -0,0 +1,32 @@ +# Distributed workshop organization + +```{keypoints} +- If another university/organization wants to run the course, they can easily join our existing course at little cost/risk to them and to us. +- Each organization that joins provides a great benefit to us (helpers, instructors). +- They can reserve an in-person breakout room and provide mentors while watching the livestream: A great experience for their audience. +``` + + +## It is easier to join and follow than to start or lead + +Organizing a course is time intensive and so is developing a course. Many +courses given in country A are also relevant in other countries and instead of +developing and possibly re-inventing courses independently in different places, +it is so much more rewarding to collaborate and share. + +In our courses we wish and try to make it easier for teams and organizations +and universities to join, at little risk and cost to them, possibly for a short +period of time, possibly only as observer. Later observers can progress to +exercise leads, expert helpers, instructors, and co-organizers. + +One model that we have successfully tried is that the course is delivered via +live-stream to all partners and all the partner needs to do is to reserve a +room and motivate few people to help local learners as exercise leads during +exercise sessions which can happen in-person. + +```{discussion} Lessons learned from organizing larger workshops + +- **One person is needed to coordinate the registration process** and this person should + not have teaching duties in addition to this role. +- Generally it helps to have **well-defined roles** (see {ref}`workshop-roles`). +``` diff --git a/branch/community-teaching/_sources/diversity-and-inclusion.rst.txt b/branch/community-teaching/_sources/diversity-and-inclusion.rst.txt new file mode 100644 index 0000000..5baf30d --- /dev/null +++ b/branch/community-teaching/_sources/diversity-and-inclusion.rst.txt @@ -0,0 +1,58 @@ +Diversity and inclusion +======================= + +When we are teaching, we fill a critical role in between people and +technology. We are not un-involved technical staff teaching asocial +topics, but we are very connected to the social context of the tools. +Unfortunately, there are major demographic imbalances in most +computing. + + + +Primary articles +---------------- + +* Several sections from the Carpentries Instructor Training: + `Motivation and demotivation + `__ + and `Equity, inclusion, accessibility + `__. +* Exercise leaders `During the workshop + `__ + + + +Support services vs diversity +----------------------------- + +Study this presentation by Richard Darst: + +* Watch: https://www.youtube.com/watch?v=z1VS1wleN-o +* Or read: https://docs.google.com/presentation/d/e/2PACX-1vQkzOMFI5SFnx69D4qRq_3N-mtcv7GUbPZd4A6UYpEKZUMGK0FL5W0RsSe6Alzxv1nE635Yl1GpyCKk/pub + +Summary: + +* Computing is hard and quite often our ability to learn quickly is + connected to our social group. +* Good technical services serve the role of mentors +* This mentorship helps to equalize +* Our entire system of research should be configured for more + equality. Modernization usually takes it the other way. + + + +Exercises +--------- + +.. exercise:: Reflect on how your job can be defined to promote diversity. + + What are some (possibly surprising) ways that your job promote + diversity and equality among people of different backgrounds? + + + +See also +-------- + +(none yet) + diff --git a/branch/community-teaching/_sources/exercises.rst.txt b/branch/community-teaching/_sources/exercises.rst.txt new file mode 100644 index 0000000..4aa70a7 --- /dev/null +++ b/branch/community-teaching/_sources/exercises.rst.txt @@ -0,0 +1,10 @@ +Exercise list +============= + +This is a list of all exercises and solutions in this lesson, mainly +as a reference for helpers and instructors. This list is +automatically generated from all of the other pages in the lesson. +Any single teaching event will probably cover only a subset of these, +depending on their interests. + +.. exerciselist:: diff --git a/branch/community-teaching/_sources/future.md.txt b/branch/community-teaching/_sources/future.md.txt new file mode 100644 index 0000000..edb0dec --- /dev/null +++ b/branch/community-teaching/_sources/future.md.txt @@ -0,0 +1,55 @@ +# Possibilities for Carpentries + +```{keypoints} +- Carpentries is currently designed around small workshops, so many of these ideas can't directly apply +- Yet **many of these tools and also team teaching can still be used** +- You can run your own breakout room for any of our workshops +- Join as observer if you want to see our workshop organization and tools in action +``` + +CodeRefinery workshops can be a good progression step after taking a +Carpentries workshop. + +Helping out at a CodeRefinery workshop as exercise lead can be a good +progression step for those who have helped out at a Carpentries workshop or who +have taken the Carpentries instructor training. + + +# CodeRefinery's plans + +```{keypoints} +- We are continuing to focus on online-first with local breakout rooms +- We welcome people joining us, either individually or as an organization +- Still interested in collaboration with Carpentries +- We need to become better at marketing and outreach +``` + + +## Biggest open problems + +- How to give helpers and contributors more credit and visibility +- How to promote/engage new members +- What are we? Non-profit? Institution collaboration network? Selling services? +- Funding and sustainability (but we have ideas: collaboration network) + + +## How you can join + +Individual level: + +- Join [CodeRefinery + chat](https://coderefinery.github.io/manuals/chat/) +- Lead a team, co-teach, or help organize a workshop +- Generally provide marketing and outreach + +Organization level: +- Have your organization join CodeRefinery +- Officially co-advertise and co-teach workshops +- Run local breakout rooms and join a workshop as a team +- Send an observer to a workshop + + +## Aside: Nordic-RSE (research software engineers) + +- [Nordic-RSE online unconference 2022](https://nordic-rse.org/events/2022-online-unconference/) +- [Bi-weekly meetings](https://nordic-rse.org/events/meeting/#community-discussions-biweekly) diff --git a/branch/community-teaching/_sources/guide.rst.txt b/branch/community-teaching/_sources/guide.rst.txt new file mode 100644 index 0000000..e05b967 --- /dev/null +++ b/branch/community-teaching/_sources/guide.rst.txt @@ -0,0 +1,14 @@ +Instructor's guide +------------------ + +In a lesson that was further developed, this would include an +instructor's guide that mentioned: + +* Background of why the course is how it is +* Recommendations of teaching it +* Known pitfalls of teaching it, so that other instructors can avoid + them +* Possibly how to contribute, long-term plans, etc. + +For example, see `git-intro's instructor guide +`__. diff --git a/branch/community-teaching/_sources/hackmd.rst.txt b/branch/community-teaching/_sources/hackmd.rst.txt new file mode 100644 index 0000000..1347785 --- /dev/null +++ b/branch/community-teaching/_sources/hackmd.rst.txt @@ -0,0 +1,66 @@ +HackMD +====== + +The name "HackMD" doesn't do this concept justice, nor do the more +common descriptions of "shared notes" or "collaborative document". It +is a full replacement for chat: perhaps it could be called **random +access chat** or **parallel 2D chat** ? + +**HackMD** itself is a web service for collaborative documents in +Markdown. This isn't special to HackMD, but we have used it for its +scalability, markdown support, and privacy in the "view" mode. + + + +Primary articles +---------------- + +* HackMD instructors for the audience: https://coderefinery.github.io/manuals/hackmd-mechanics/ +* HackMD manager role description: https://coderefinery.github.io/manuals/hackmd-helper/ +* Example published HackMD after six 3-hour CodeRefinery sessions: https://coderefinery.github.io/2022-03-22-workshop/questions/ + + + +Advantages +---------- + +* Synchronous questions, no disadvantage for quiet people. +* Anonymous questions. +* Parallel answers by a large number of helpers. +* Easier to go back and review past questions during Q&A sessions + (compared to scrolling through chat), for example finding important + or unanswered questions. +* The above can make a course feel much more interactive than it would + otherwise. + + + +Disadvantages +------------- + +* *Overwhelming* flood of information + + * But you wanted more interaction, right? + * Co-teaching helps here, one person can focus on watching. + * Students must be warned to be deliberate about where they focus + their attention (different learners have different interests). + +* It is another tool to use + + * Not required for basic learners, learners can begin using when + they are comfortable. + + + +Exercise +-------- + +.. exercise:: + + * Actively use HackMD during this course. + * Observe how the instructors integrate it during the course + itself, and can immediately respond to the questions. + * Observe how instructors occasionally mention and screenshare + HackMD to validate to the audience that it is being watched. + * Keep HackMD open. Can you balance it and watching. Does it + increase or decrease engagement? diff --git a/branch/community-teaching/_sources/index.rst.txt b/branch/community-teaching/_sources/index.rst.txt new file mode 100644 index 0000000..e207328 --- /dev/null +++ b/branch/community-teaching/_sources/index.rst.txt @@ -0,0 +1,146 @@ +Community teaching training +=========================== + +.. admonition:: Under development (mid 2022) + + As of mid-2022, this material has been reworked for our summer workshop and + for the CarpentryCon 2022 workshop. The material will continue to be + improved before a longer training session in the autumn. + + This material is the new version of our previous `Instructor + training `__. + + +What this course covers +----------------------- + +In 2020, we got farther from our offices but closer to each other. If +you could adapt to the circumstances, a huge number of possibilities +were opened - in particular with collaborative teaching. In this +training, you will learn how we use them. Teaching from 2019 is +almost obsolete - join us to learn more. + +- **Tools of teaching**: how to make the most out of online (and + other) teaching. +- **Workshop organization, collaboratively**: our vision of teaching + together outside of our silos. +- **Socio-technical factors**: social and technical barriers to + learning, why you need to care, and what you can do about them. +- **Lesson development, collaboratively**: how to design lessons and + teaching materials so that they can be open and shared. + + +Who is the course for? +---------------------- + +Teaching is a profession, but also something that everyone needs to be +able to do to some degree, since everyone has their own personal +specialties they will either teach or mentor. + +This course can be relevant for different learner personas: + +- **You run a practical teaching program** at your institution (for example + as part of a research computing group) and would like to learn best + practices for collaborative teaching, so that you aren't re-inventing + the same thing over and over again. + +- **You are a technical specialist** who is frustrated with the way you + currently try to teach others who need to use your software or + infrastructure. You can't spend too much time to become a + professional, but you know you need something more than what you've + been doing. Thus, you would like to adopt some of the best practices of + designing and teaching interactive, hands-on workshops. + +- **You've been teaching alone**, but would like to join a collaboration + network for more co-teaching and to reduce the amount of duplication + of effort. + +- **You are interested in teaching CodeRefinery lessons**, and would like a + comprehensive kick-start to how CodeRefinery works, either to join us, + or teach its lessons with us or independently. + + +.. toctree:: + :maxdepth: 1 + :caption: Preparation + + preparation + + +.. toctree:: + :maxdepth: 1 + :caption: Introduction + + welcome + about-coderefinery + + +.. toctree:: + :maxdepth: 1 + :caption: Teaching tools + + teaching-online + team-teaching + hackmd + teams + livestreaming + instructor-tech-setup + video-recording + video-editing + + distributed + + +.. toctree:: + :maxdepth: 1 + :caption: Workshop organization + + why-teach-together + distributed + collaboration-models + workshop-roles + + +.. toctree:: + :maxdepth: 1 + :caption: Social-technical considerations + + why-are-computers-hard + diversity-and-inclusion + Accessibility and usability (placeholder) + Mentoring (placeholder) + + +.. toctree:: + :maxdepth: 1 + :caption: Lesson design and development + + lessons-with-version-control + backward-lesson-design + + +.. toctree:: + :maxdepth: 1 + :caption: Wrap-up, future, and getting involved + + future + + +.. toctree:: + :maxdepth: 1 + :caption: Reference + + other-resources + guide + exercises + + +.. toctree:: + :maxdepth: 1 + :caption: Old contents - we need to move/merge + + 02-teaching-philosophies.md + 03-teaching-style.md + workshops-online.md + teaching-strategies + teaching-practice.md diff --git a/branch/community-teaching/_sources/instructor-tech-setup.md.txt b/branch/community-teaching/_sources/instructor-tech-setup.md.txt new file mode 100644 index 0000000..676f52e --- /dev/null +++ b/branch/community-teaching/_sources/instructor-tech-setup.md.txt @@ -0,0 +1,93 @@ +# Instructor tech setup + +```{keypoints} +- Screenshare: **portrait layout** instead of sharing entire screen +- Prompt: **adjust your prompt** to make commands easy to read +- **Readability** and beauty is important: adjust your setup for your audience +- **Share the history** of your commands +- Get set up a **few days in advance** and get an outside reviewer +``` + + +## Screenshare + +Compare the following two screen-shares (you can find many more in +[the coderefinery manuals](https://coderefinery.github.io/manuals/instructor-tech-online/): + +```{figure} https://coderefinery.github.io/manuals/_images/screenshare-fullhd.png +:width: 80% + +FullHD. +``` + +```{figure} https://coderefinery.github.io/manuals/_images/s10-kickstart-prompt-log.png +:width: 45% + +Portrait, latest proposed best practices. +``` + +Share a portrait layout (left or right half of your screen) +instead of sharing entire screen. + +Motivation: +- This makes it easier for you to look at some other notes or to coordinate + with other instructors at the same time + without distracting with too much information. +- This makes it possible for participants to have something else open in the + other screen half: terminal or browser or notebook. + + +## Adjust your prompt/configuration/colors + +Adjust your prompt to make commands easy to read. What looks good for your own +work (many terminals, small font, extensions, shortcuts, color scheme) is +usually not the best for other people watching you. Adjust your setup for your +audience. Remove distractions. + +You *need* to spend some time getting set up before you teach. 10 minutes +before the session starts is typically too late. Get set up a **few days in +advance** and get an outside reviewer. + +```{discussion} Should instructors be forced to have a consistent screenshare? + +There are pros and cons to all instructors using the same screenshare and prompt. + +- What are the advantages? +- What are the opportunities of instructors showing different setups? +- How does it depend on the lesson and the experience of learners? +``` + + +## Share the history of your commands + +Even if you type slowly it is almost impossible to follow every command. We +all get distracted or want to read up on something or while following a command +fails on the learner laptop while instructor gets no error. + +Add pauses and share the commands that you have typed so that one can catch up. + + +## More examples and how to set it up + +- Generally making your screen look good (prompt, remove distractions, + command line history, etc): + +- Online setup for screen-shares: + + + +## Exercises + +```{exercise} Evaluate screen captures + +Evaluate screenshots within the [instructor tech +setup](https://coderefinery.github.io/manuals/instructor-tech-online/) lesson. +Use the collaborative document to make a list of the trade-offs of each one. +Which one do you prefer? Which are useful in each situation? +``` + +```{exercise} Set up your own environment + +Set up your screen to teach something. Get some feedback from +another learner. We will discuss among the class. +``` diff --git a/branch/community-teaching/_sources/lessons-with-version-control.md.txt b/branch/community-teaching/_sources/lessons-with-version-control.md.txt new file mode 100644 index 0000000..82bed4e --- /dev/null +++ b/branch/community-teaching/_sources/lessons-with-version-control.md.txt @@ -0,0 +1,106 @@ +# Lesson development with version control + +So, we want to practically share. We have these minimum requirements: + +* Someone can get the preferred form of modification, to improve + without limitation. + +* It is trivial to track differences and send the changes back to the + source, with little cost to the original maintainer. + +Especially with the second of these, version control in an online +platform seems to be the only reasonable option. + + +## Version control and static site generators + +CodeRefinery and the Carpentries use git and Github to develop +lessons. The general procedure is this: + +* Version control to store the raw files in text format +* A static website compiler to convert them to HTML files +* Serving to the public via Github Pages (but this could be replaced + with other systems) + +This allows for true collaborative development and community +contributions. + +Carpentries uses a custom website complierer based on R, CodeRefinery +uses the Sphinx documentation engine which is used in many different +projects for documentation. CodeRefinery's use of a standard tool +allows us to build on a huge and growing ecosystem of extensions and +themes, and promotes local reuse. + +The exact static website generator used isn't so important, as long as +some form of version control is used. + +A open-source license is the last bit to consider: without a license, +it can't be reused and passed on, and there is little incentive for +someone to contribute. + + +## CodeRefinery lesson tools + +CodeRefinery uses the following tools to actually make its lessons +right now: + +* [Sphinx](https://www.sphinx-doc.org/) (a common documentation + generator, widely used in open source projects in general) +* The [sphinx-lesson](https://github.com/coderefinery/sphinx-lesson), which is more of + a small collection of other extensions than new development itself. +* Github for hosting lessons: +* Github Actions and Github Pages for building and web serving our + lessons. + + +## Exercises + +```{exercise} Contribute to a sample lesson +* Open this very lesson in GitHub (it uses the same format as + typical CodeRefinery lessons): + + +* Browse the files and understand the general idea. Check out at + least these and use HackMD to record their functions: + + * .github/workflows/sphinx.yml + * content/conf.py + * content/index.rst + * content/lessons-with-version-control.rst + +* If you want, try to make a pull request to this lesson. It + doesn't have to have any significant content, it can be a pure + test pull request. +``` + +```{exercise} (advanced) Create your own lesson +Use the +[sphinx-lesson-template](https://github.com/coderefinery/sphinx-lesson-template) +to create a new lesson of your choice. Alternatively, use the current +Carpentries system, or some other system of your choice. +``` + + +## Recommendations and lessons learned + +- Convert feedback about lessons and suggestions for improvements into *issues* + so that these don't get lost. +- Make your lesson citable: get a DOI. +- Credit contributors (not only Git commits). +- Instructor guide is essential for new instructors. +- Lesson changes should be accompanied with instructor guide changes (it's like + a documentation for the lesson material). +- Apply and validate {ref}`backwards-lesson-design` again and again. +- Make it possible to try out new ideas (by making the lesson branch-able). +- Before making larger changes, talk with somebody and discuss these changes. +- For substantial changes we recommend to first open an issue and describe your + idea and collect feedback before you start with an extensive rewrite. +- For things still under construction, open a draft pull request to collect + feedback and to signal to others what you are working on. + + +## See also + +- [CodeRefinery git-intro](https://coderefinery.github.io/git-intro/) +- [CodeRefinery git-collaborative](https://coderefinery.github.io/git-collaborative/) +- [Carpentries lesson development](https://docs.carpentries.org/topic_folders/lesson_development/index.html) diff --git a/branch/community-teaching/_sources/livestreaming.rst.txt b/branch/community-teaching/_sources/livestreaming.rst.txt new file mode 100644 index 0000000..3ccf56e --- /dev/null +++ b/branch/community-teaching/_sources/livestreaming.rst.txt @@ -0,0 +1,84 @@ +Livestreaming +============= + +In a large lecture, in effect, you don't interact with most people - +not even close. Yet, trying to force this limited interaction greatly +limits our possible reach, and keeps us in an awkward state of +expecting live interaction yet usually receiving minimal. When we try +this online, it forces a closed + +Teaching via livestreaming allows us to: + +* Reach a near-unlimited number of people +* Fully embrace online tools for interaction, instead of asking people + to speak up. This equalizes the participation for shy or passive + participants. +* By being large, be more efficient and use the extra resources for + meaningful interactions in small groups. + + + +Primary articles +---------------- + +* CodeRefinery MOOC strategy: + https://coderefinery.github.io/manuals/coderefinery-mooc/ +* Intro to livestream teaching: + https://coderefinery.github.io/manuals/livestream-teaching/ +* Broadcaster role description (hints on the actual tools): + https://coderefinery.github.io/manuals/broadcaster/ +* OBS (open broadcaster software) and livestream crash course: + https://coderefinery.github.io/manuals/obs/ + + +Summary +------- + +* There are actually three levels here. + + * In-person + * Online meeting + * Online livestream + +.. figure:: https://coderefinery.github.io/manuals/_images/mooc-diagram.png + + The general presence and information flow within the MOOC strategy. + +* CodeRefinery livestreams via Twitch, but Twitch is not an essential + aspect. + +* We can invite anyone in the world, no risk of disruptions from + trolls. + +* This has enabled us to fully embrace strategies such as HackMD and + co-teaching. + + * While we tried these in-person, they didn't work well since the + loud, extroverted people would dominate. + + + +Tech details +~~~~~~~~~~~~ + +* We stream by using OBS to capture a Zoom meeting. We can switch + between a gallery view, screenshare, and mixed. + +* Dedicated instructor Zoom meeting - no learners. Thus, no chance of + privacy violations. + + * Learners can attend different ways: a) independently online b) + in-person breakout room c) Zoom breakout rooms. + +* We don't have time to get into details here... see the linked + documents and also join us for in-person experience while we improve + our materials more. + + + +Exercises +--------- + +.. exercise:: (advanced) Set up and install OBS as a livestreaming tool. + + This exercise is open-ended. diff --git a/branch/community-teaching/_sources/other-resources.md.txt b/branch/community-teaching/_sources/other-resources.md.txt new file mode 100644 index 0000000..0b04ff9 --- /dev/null +++ b/branch/community-teaching/_sources/other-resources.md.txt @@ -0,0 +1,23 @@ +# Other resources + +- The future of teaching" (35 min content only, 45 min with Q&A, or 15 min reading). + [Watch it on YouTube](https://www.youtube.com/watch?v=S9Jor12Cxdc) + or [read it](https://hackmd.io/KRqQirJ_Rn2SHcE-t1iAUg) if you prefer. +- [The old "CodeRefinery instructor training" + program](https://coderefinery.github.io/instructor-training/): this is + replaced by what you are reading now. +- [CodeRefinery manuals](https://coderefinery.github.io/manuals/) +- Our gradual pathway to instructor from the manuals: + [helper intro](https://coderefinery.github.io/manuals/helper-intro/) and + [instructor intro](https://coderefinery.github.io/manuals/instructor-intro/). +- [Carpentries instructor training](https://carpentries.org/instructors/): + more intensive, but focused only on teaching. +- [Carpentries curriculum development handbook](https://cdh.carpentries.org/) +- [Teaching Tech Together](https://teachtogether.tech/): a book + about similar topics by someone involved in Carpentries. +- [Carpentries general organizational documentation](https://docs.carpentries.org/) +- [How to help someone use a computer, by Phil Agre](https://www.librarian.net/stax/4965/how-to-help-someone-use-a-computer-by-phil-agre/). + Summary: Most of our teaching challenge is helping people to overcome bad user + interface design. +- [The Science of Learning](https://carpentries.github.io/instructor-training/files/papers/science-of-learning-2015.pdf): + provides a brief overview of some key evidence-based results in teaching. diff --git a/branch/community-teaching/_sources/placeholder.rst.txt b/branch/community-teaching/_sources/placeholder.rst.txt new file mode 100644 index 0000000..09e5355 --- /dev/null +++ b/branch/community-teaching/_sources/placeholder.rst.txt @@ -0,0 +1,2 @@ +Placeholder +=========== diff --git a/branch/community-teaching/_sources/preparation.md.txt b/branch/community-teaching/_sources/preparation.md.txt new file mode 100644 index 0000000..86b7596 --- /dev/null +++ b/branch/community-teaching/_sources/preparation.md.txt @@ -0,0 +1,46 @@ +# Pre-workshop preparation + +These things will help you get the most out of this workshop, by +giving you a broad overview at the beginning that you might only get +later on in the lesson. + +Don't worry if you don't have time to do everything here. The most +important ones are listed first. + + +## Read "How to help someone use a computer" (5 min) + +[How to help someone use a computer, by Phil +Agre](https://www.librarian.net/stax/4965/how-to-help-someone-use-a-computer-by-phil-agre/). +Summary: Most of our teaching challenge is helping people to overcome bad user +interface design. + + +## Browse a CodeRefinery lesson (5 min) + +Please take 5 minutes and go through a [CodeRefinery +lesson](https://coderefinery.org/lessons/) and understand the general +layout. Don't go in-depth to any of the material (unless you want, +obviously). We would recommend +[git-intro](https://coderefinery.github.io/git-intro/) if you don't +have a preference. + + +## (optional) Watch "The future of teaching" (35 min content only, 45 min with Q&A, or 15 min reading) + +The "The Future of Teaching" talk is a summary of many things in this +course. You could watch it as a preparation (or if you are reading on +your own, as a summary). This is low priority, since we will cover +most of these things in the course itself. +[Watch it on YouTube](https://www.youtube.com/watch?v=S9Jor12Cxdc) +or [read it](https://hackmd.io/KRqQirJ_Rn2SHcE-t1iAUg) if you prefer. + + +## (optional) Read "The science of learning" (20 min) + +Read this short paper [The Science of +Learning](https://carpentries.github.io/instructor-training/files/papers/science-of-learning-2015.pdf) +which provides a brief overview of some key evidence-based results in +teaching. This paper is also used by [The +Carpentries](https://carpentries.org/) for their Instructor Training +workshops. diff --git a/branch/community-teaching/_sources/teaching-online.md.txt b/branch/community-teaching/_sources/teaching-online.md.txt new file mode 100644 index 0000000..1c33476 --- /dev/null +++ b/branch/community-teaching/_sources/teaching-online.md.txt @@ -0,0 +1,27 @@ +# Teaching online + +Is online teaching better or worse? As usual for that question, "it's +all a trade-off". We believe that many people tried to directly +translate in-person strategies to online, and teaching suffered. In +some ways, this even revealed the flaws of in-person pedagogy (remove +some interaction and not much is left other than an info-dump). + +```{exercise} +Using HackMD, brainstorm advantages and disadvantages of online and +in-person teaching. For each disadvantage of each, think of ways to compensate. + +``` + +* We won't elaborate more here right now - most of the rest of the + course somehow relates to online teaching! +* We will see many techniques which compensate for some of the + disadvantages in the section **tools of teaching**. +* **Workshop organization** will discuss new collaborative + opportunities with online teaching. + + + +## See also + +* The rest of this course +* CodeRefinery manuals: https://coderefinery.github.io/manuals/ diff --git a/branch/community-teaching/_sources/teaching-practice.md.txt b/branch/community-teaching/_sources/teaching-practice.md.txt new file mode 100644 index 0000000..1323c86 --- /dev/null +++ b/branch/community-teaching/_sources/teaching-practice.md.txt @@ -0,0 +1,76 @@ +# Teaching practice and feedback + +Goals of the teaching practice: + +- In groups of 4-5 persons we will practice teaching a **5-minute segment + of a lesson of your choice**. +- The section you pick should require **screen sharing** and be of some + **demonstration or follow-along task** (preferably using a shell) to also + practice having a good screen-sharing setup. +- We will practice giving **constructive feedback**. +- We will practice improving our 5-minute segment by taking the feedback into account. +- In both session you can teach the same topic/segment but if you prefer you can also + change the topic/aspect for the second session. + +--- + +## Instructor demo + +- In order to demonstrate the goals of this section, the instructor + will make a 5-minute demo for your evaluation. +- It is designed to include some good and bad practices for you to + notice. + +--- + +## Teaching demos part 1 + +In group rooms, 50 minutes. + +```{challenge} +- We organize the breakout rooms to not only discuss one lesson/topic so that it is more interesting + to listen and also probably we will all get more useful feedback. +- Give each other **constructive verbal feedback** on the teaching demos, for example + using [this demo rubric](https://carpentries.github.io/instructor-training/demos_rubric/). +- Write down questions (in the collaborative document) that you would like to + discuss in the main room or interesting conclusions which you would like to + share with others. +``` + +## Teaching demos, part 2 + +In group rooms, 50 minutes. + +```{challenge} +- In the second round we distribute the rooms differently so that you can + present it to a **new group of workshop participants** and can receive new + feedback. +- Ask for feedback and one/few point(s) you want to improve. +- In your second trial check whether you feel the demonstration improved. +- Share your lessons learned in the collaborative document. +- Give us also feedback on this exercise format. Was it useful? What can we improve? +``` + +--- + +## Discussion + +```{discussion} Main room discussion + - We discuss questions and conclusions which came up during the group work session. +``` + +--- + +## Optional: feedback for two live-coding examples + +```{challenge} +Teaching by live coding is a +[performance art which requires practice](https://teachtogether.tech/#s:performance-exercises). +This exercise highlights some typical pitfalls that most instructors +fall into sooner or later, and also shows how to avoid them. +Watch closely since we will be giving feedback! +- Watch these two videos: [video 1](https://youtu.be/bXxBeNkKmJE) and + [video 2](https://youtu.be/SkPmwe_WjeY) +- What was better in video 1 and what was better in video 2? +- Please give feedback in the shared workshop document. +``` diff --git a/branch/community-teaching/_sources/teaching-strategies.md.txt b/branch/community-teaching/_sources/teaching-strategies.md.txt new file mode 100644 index 0000000..2e93a21 --- /dev/null +++ b/branch/community-teaching/_sources/teaching-strategies.md.txt @@ -0,0 +1,220 @@ +# How to teach online + +```{objectives} +- Understand the benefits and disadvantage of online teaching, + compared to in-person + +- Set up a good screen share + +- Understand the benefits and disadvantages of team teaching + +- Prepare for the teaching practice +``` + + +## Why teaching mechanics matter + +- When you teach, you are mainly showing a basic example for the + learner to follow along +- The learner has a *lot* more to think about than you do, so you need + to minimize the possible distractions and unnecessary weirdness. +- A learner will often only one small screen, limiting the number of + things that they can think about. +- You are must faster than learners (5 times possibly?) You have to + do things to slow yourself down. +- It's easy to save these mechanics until the end, and then you run + out of time. + + + + +## Shell sharing + +```{discussion} Discussion: what goes into a good shell share or demonstration? + +When you are following along with a type-along demonstration, what +things: + +- Are useful to make it easy to follow along +- Make it harder to follow along + +Answer in the collaborative notes +``` + +When doing any demonstration, there are difficulties: + +- If one misses something, you can't rewind to see it - is there any + way to catch up? +- The learner must get oriented with the whole picture, while + instructor knows precisely where to focus. + +A good **shell share** has some of the following properties: + +- Large font +- Shell history, available separately from the main shell window +- Closely matches the type-along instructions + +We have a collection of shell sharing systems: +- We will look over [lesson presentation +hints](https://coderefinery.github.io/manuals/instructor-tech-setup/#terminal-history-window). +- There are other things you can copy +- Whatever you do, do *something*. + +```{discussion} +The instructor will demonstrate several shell-sharing systems. You +will use this in the teaching practice. +``` + + + +## Screen sharing + +`````{discussion} + +Look at the various [screen layouts in the CodeRefinery +manuals](https://coderefinery.github.io/manuals/instructor-tech-setup/#screen-sharing). +Use the HackMD to comment about what which are better or worse. + +````{output} HackMD prototype +:class: dropdown +``` +- S1 + - good: + - bad: +- S2 + - good: + - bad: +- S3 + - good: + - bad: +- S4 + - good: + - bad: +- Student layouts: + - ... +- Instructor layouts: + - ... +``` +```` +````` + +- Many learners will have a smaller screen than you. +- You should plan for learners with only one small screen. +- A learner will **need to focus on both your screen share and their + work**. +- Sharing your a whole screen is almost always a bad idea, if you want + the learners to do anything at the same time. +- If you constrict yourself, then your experience is more similar to + that of a learner. + +Vertical sharing: +- CodeRefinery has recently started trialing a **vertical share** + system, where you share a vertical half of your screen. +- This allows learners with one screen to display your screen + side-by-side with their learn +- Zoom provides a "Share a part of screen" that is good for this. + + + +## Meta-talk + +Don't just teach, also make sure you guide the learners through the +course. + +- You know what you just discussed, and what is coming next, but + learners are often stuck thinking about now. +- Give a lot of "meta-talk" that is not just about the topic you are + teaching, but how you are teaching it. +- Examples + - **Why** you are doing each episode + - What is the purpose of each exercise + - Clearly state what someone should accomplish in each exercise and + how long it will take - don't assume this is obvious. + - What is the point of each lesson. How much should people expect + to get from it? Should you follow everything, or are some things + advanced and optional? Make that clear. + + + +## Teach teaching + +- Demonstration-based teaching require two different types of focus: + - Doing the mechanical steps as a demonstration + - Explaining why you are doing it +- This is a lot for one person to keep in mind, so can multiple people + work together for this? +- Team teaching idea: + - One person is doing the demonstrations + - One person is giving the commentary about what they are doing + - The lecture becomes a discussion between two people instead. + +Advantages: +- This reduces the pressure on each person (reduces demo effect) +- You are less likely to forget things +- It slows you down in teaching +- It makes the lesson more interesting to listen to +- One person can follow questions +- Great for introducing new instructors (which half is easier to start + with?) + +Disadvantage: +- Requires two people's time +- Requires coordination when preparing (slows you down in preparation) +- Unfamiliar concept to most people + + + +## Questions + +- Questions are great, and important for any practical and interactive + class +- But questions in main room doesn't scale to very large rooms. +- CodeRefinery strategy: HackMD for questions + - Chat is not good enough, you can't reply to old things + - HackMD allows threaded replies and follow up later + - You need some other helpers to watch HackMD and answer, and bring + things up to you. And let you know how things are going. + - Learners can ask anonymously + - Learners don't have to worry about interrupting the flow. + - Disadvantage: can produce information overload, warn people to not + follow too closely + - With too few people, it can turn out to be very quiet. +- We will learn more about HackMD questions tomorrow in + {doc}`workshops-online`. + +```{seealso} +* {doc}`workshops-online` +* [HackMD +mechanics](https://coderefinery.github.io/manuals/hackmd-mechanics/) +and [HackMD +helpers](https://coderefinery.github.io/manuals/hackmd-helper/) on +CodeRefinery manulas. +``` + + + +## Teaching practice + +In {doc}`teaching-practice`, you will break into groups and try to +apply these strategies to a five-minute example session. + + + +## See also + +In this lesson: + +* {doc}`workshops-online` + +CodeRefinery manuals: + +* [Instructor tech + setup](https://coderefinery.github.io/manuals/instructor-tech-setup/) +* [Lesson preparation + hints](https://coderefinery.github.io/manuals/presenting/) (more + focused on in-person) +* [Instructor + introduction](https://coderefinery.github.io/manuals/presenting/) - + has a lot of tips for new instructors, but also more things about + the workshop. +* [Workshop prep call](https://coderefinery.github.io/manuals/workshop-prep-call/) diff --git a/branch/community-teaching/_sources/team-teaching.rst.txt b/branch/community-teaching/_sources/team-teaching.rst.txt new file mode 100644 index 0000000..b6531b3 --- /dev/null +++ b/branch/community-teaching/_sources/team-teaching.rst.txt @@ -0,0 +1,82 @@ +Team teaching +============= + +One of the most significant improvemest of our teaching has been the +concept of **co-teaching**. + +.. admonition:: Co-teaching + + Wikipedia: Co-teaching or team teaching is the division of labor + between educators to plan, organize, instruct and make assessments + on the same group of students, generally in the a common + classroom,[1] and often with a strong focus on those teaching as a + team complementing one another's particular skills or other + strengths. + +*This is not strictly an effect of moving online*. However, the +larger number of instructors and larger audiences make this practical +on a wide scale. + + + +Primary article +--------------- + +https://coderefinery.github.io/manuals/team-teaching/ + + + +Benefits +-------- + +* The course seems very interactive, much more so than expecting + students to speak up. The co-teacher can take on the "voice of the + audience". +* Quicker preparation time since co-teachers can rely on each other in + unexpected situations. +* One co-teacher can be effectively learning at the same time and thus + acting as the "voice of the audience" in another way. +* Great way to onboard new instructors - extensive training and + preparation no longer needed. +* More active minds means better able to watch and react to other + feedback, such as HackMD or chat. +* Less workload - one person does not have to prepare perfectly, any + uncertainty can usually be quickly answered by the other. + + + +Strategies +---------- + +In reality, these strategies are mixed and matched even within a +lesson, and there are many things between these: + +* One person gives lectures, one does the typing during demos. +* "Interview": One primarily doing the "teaching", one guiding by + asking questions - either as an interviewer or as a virtual learner. + +Things that don't work (are not team teaching): + +* Dividing up a lesson into parts, each person gives different parts + independently. + + + +Exercises +--------- + +.. exercise:: + + Divide into groups of two or three. Choose one of the two models + in the team-teaching page, and quickly (5 min) prepare a short + topic (3-5 min) to team teach. You can quickly scan the + "preparation" section at the bottom. + + The challenge is not just to give the lesson, but to prepare the + lesson quickly and rely on each other to give a good lesson anyway. + + +See also +-------- + +(none yet) diff --git a/branch/community-teaching/_sources/teams.rst.txt b/branch/community-teaching/_sources/teams.rst.txt new file mode 100644 index 0000000..cf03ccb --- /dev/null +++ b/branch/community-teaching/_sources/teams.rst.txt @@ -0,0 +1,106 @@ +Teams +===== + +Everyone wants interaction in courses, yet when a group size gets too +large, it doesn't have much interaction. A event in a physical space +naturally makes teams based on who is nearby. When done online, this +needs to be more explicit. + + + +Primary articles +---------------- + +* Exercise leader role description: + https://coderefinery.github.io/manuals/exercise-leaders/ +* Local breakout rooms: + https://coderefinery.github.io/manuals/local-breakout-rooms/?highlight=teams + + + +Basic concepts +-------------- + +- Teams are pre-assigned +- **Exercise leaders** (aka helpers) assigned per team +- Teams stay together during the whole workshop. +- Learners can sign up either alone... +- ... or they can sign up with **a pre-made team**: people who know + each. "bring your own breakout room": + + - When two people in a work group learn a skill, uptake within the + group is often much higher. Thus, we strongly encourage pre-made + teams that know each other. + + - Teams that all come from the same group or field, with a helper + from that field, can transition to help + + + +Online +------ + +In the best online implementations, our teams have these properties: + +- Coordination of breakout rooms is a *lot* of work. +- In zoom, we could request learners to rename to ``(N) Learner + Name``, and then quickly assign people. Now, you can have learners + self-select their rooms. But will they actually do this, or stay in + main room? + +- One helper is assigned per team. + + - In fact, we would limit the number of registrations to 5× the + number of helpers so that all teams have a helper + +- Our registration system (indico) is capable of mailing personalized + messages per person with their team information. This is quite a + bit of work to manage. + +But they have these disadvantages: + +- Much, much harder registration coordination, almost to the point of + being impossible. +- Number of attendees. +- Difficulties when attendees drop out partway through a course. + + + +In-person +--------- + +Teams may natuarally form based on setting location, but + +- Teams may happen naturally by sitting at the same table +- Do teams stay the same day after day? +- Do teams get arranged in a manner useful for learning? +- Do you have one helper per team? +- Do you encourage people to interact explicitly enough? +- Do you ensure that no one gets left out in the crowd? Are the teams + explicit enough? + + + +Discussion: what we actually do +------------------------------- + +- For large enough CodeRefinery workshops, assign teams with one + helper each. Deal with re-adjustment +- The livestream option allows everyone else to follow along. +- In other workshops, create breakout rooms but somehow try let people + self-assign. Most don't. +- For large workshops without enough staff help, livestream and + encourage people to form their own teams and watch themselves - we + don't actually need to be involved. +- Teams can be delegated to a local organizer. + + + +Exercises +--------- + +.. exercise:: Teams + + Consider these questions: + + - Should teams have similar or different people in them? diff --git a/branch/community-teaching/_sources/video-editing.rst.txt b/branch/community-teaching/_sources/video-editing.rst.txt new file mode 100644 index 0000000..869a34b --- /dev/null +++ b/branch/community-teaching/_sources/video-editing.rst.txt @@ -0,0 +1,404 @@ +Video editing +============= + +Video recordings could be useful for people attending a course later, +but also are (perhaps more) useful for **immediate review and catching +up after missing a day in a workshop**. For this, they need to be +released immediately, within a few hours of the workshop. +CodeRefinery can do this. + +Hypothesis: videos must be processed the same evening as they were +recorded, otherwise (it may never happen) or (it's too late to be +useful). To do that, we have to make processing *good enough* (not +perfect) and *fast* and *distributeable* + + +Primary articles +---------------- +* Video editor role description: + https://coderefinery.github.io/manuals/video-editor/ +* ffmpeg-editlist: the primary tool: https://github.com/coderefinery/ffmpeg-editlist + + * Example YAML editlists: + https://github.com/AaltoSciComp/video-editlists-asc + + +Summary +------- + +* Basic principle: privacy is more important than any other factor. + If we can't guarantee privacy, we can't release videos at all. + + - Disclaimers such as "if you don't want to appear in a recording, + leave your video off and don't say anything", since a) accidents + happen especially when coming back from breakout rooms. b) it + creates an incentive to not interact or participate in the course. + +* Livestreaming is important here: by separating the instruction from + the audience audio/video, there is no privacy risk in the raw + recording. They could be released or shared unprocessed. + +* Our overall priorities + + 1) No learner (or anyone not staff) video, audio, names, etc. are + present in the recordings. + 2) Good descriptions. + 3) Removing breaks and other dead time. + 4) Splitting videos into useful chunks (e.g. per-episode), perhaps + equal with the next one: + 5) Good Table of Contents information so learners can jump to the + right spots (this also helps with “good description”.) + +* `ffmpeg-editlist + `__ allows us to + define an edit in a text file (crowdsourceable on Github), and then + generate videos very quickly. + + + +Exercises +--------- + +Exercise A +~~~~~~~~~~ + +These exercises will take you through the whole sequence. + +.. exercise:: Editing-1: Get your sample video + + Download a sample video: + + * Video (raw): http://users.aalto.fi/~darstr1/sample-video/ffmpeg-editlist-demo-kickstart-2023.mkv + * Whisper subtitles (of raw video): + http://users.aalto.fi/~darstr1/sample-video/ffmpeg-editlist-demo-kickstart-2023.srt + * `Schedule of workshop + `__ + (day 1, 11:35--12:25) - used for making the descriptions. + + +.. exercise:: Editing-2: Run Whisper to generate raw subtitles and test video. + + First off, install Whisper and generate the base subtitles, based + on the. Since this is probably too much to expect for a short + lesson, they are provided for you (above), but if you want you can + try using Whisper, or generating the subtitles some other way. + + You can start generating subtitles now, while you do the next + steps, so that they are ready by the time you are ready to apply + the editlist. ffmpeg-editlist can also slice up the subtitles from + the main video to make subtitles for each segment you cut out. + + Whisper is left as an exercise to the reader. + + .. solution:: + + Example Whisper command: + + .. code-block:: + + whisper --device cuda --output_format srt --initial_prompt="Welcome to CodeRefinery day four." --lang en --condition_on_previous_text False INPUT.mkv + + An initial prompt like this make Whisper more likely to output + full sentences, instead of a stream of words with no + punctuation. + + +.. exercise:: Editing-3: Create the basic editlist.yaml file + + Install `ffmpeg-editlist + `__ and try to + follow its instructions, to create an edit with these features: + + * The input definition. + * Two output sections: the "Intro to the course", and "From data + storage to your science" talks (Remember it said the recording + started at 11:35... look at the schedule for hints on when it + might start!). This should have a start/end timestamp from the + *original* video. + + A basic example: + + .. code-block:: yaml + + - input: day1-raw.mkv + + # This is the output from one section. Your result should have two of these sections. + - output: part1.mkv + title: something + description: >- + some long + description of the + segment + editlist: + - start: 10:00 # start timestamp of the section, in *original* video + - end: 20:00 # end timestamp of the section, in the *original* video + + .. solution:: + + This is an excerpt from our `actual editlist file of this course + `__ + + .. code-block:: yaml + + - input: day1-obs.mkv + + - output: day1-intro.mkv + title: 1.2 Introduction + description: >- + General introduction to the workshop. + + https://scicomp.aalto.fi/training/kickstart/intro/ + + editlist: + - start: 00:24:10 + - end: 00:37:31 + + + - output: day1-from-data-storage-to-your-science.mkv + title: "1.3 From data storage to your science" + description: >- + Data is how most computational work starts, whether it is + externally collected, simulation code, or generated. And these + days, you can work on data even remotely, and these workflows + aren't obvious. We discuss how data storage choices lead to + computational workflows. + + https://hackmd.io/@AaltoSciComp/SciCompIntro + + editlist: + - start: 00:37:43 + - end: 00:50:05 + + +.. admonition:: Discussion: what makes a video easy to edit? + :class: discussion + + * Clear speaking and have high audio quality. + * For subtitle generation: Separate sentences cleanly, otherwise it + gets in a "stream of words" instead of "punctuated sentences" + mode. + * Clearly screen-sharing the place you are at, including section + name. + * Clear transitions, "OK, now let's move on to the next lesson, + LESSON-NAME. Going back to the main page, we see it here." + * Clearly indicate where the transitions are + * Hover mouse cursor over the area you are currently talking about. + * Scroll screen when you move on to a new topic. + * Accurate course webpage and sticking to the schedule + + All of these are also good for learners. By editing videos, you + become an advocate for good teaching overall. + + +.. exercise:: Editing-4: Run ffmpeg-editlist + + Install ffmpeg-editlist: ``pip install ffmpeg-editlist[srt]`` (you + may want to use a virtual environment, but these are very minimal + dependencies). + + The ``ffmpeg`` command line tool must be available in your + ``PATH``. + + .. solution:: + + It can be run with (where ``.`` is the directory containing the + input files): + + .. code-block:: console + + $ ffmpeg-editlist editlist.yaml . + + Just running like this is quick and works, but the stream may be + garbled in the first few seconds (because it's missing a key + frame). (A future exercise will go over fixing this. + Basically, add the ``--reencode`` option, which re-encodes the + video (this is **slow**). Don't do it yet. + + Look at the ``.info.txt`` files that come out. + + +.. exercise:: Editing-5: Add more features + + * Several chapter definitions.(re-run and you should see a + ``.info.txt`` file also generated). Video chapter definitions + are timestamps of the *original* video, that get translated to + timestamps of the *output* video. + + .. code-block:: yaml + + - output: part1.mkv + editlist: + - start: 10:00 + - -: Introduction # <-- New, `-` means "at start time" + - 10:45: Part 1 # <-- New + - 15:00: Part 2 # <-- New + - end: 20:00 + + Look at the ``.info.txt`` files that come out now. What is new in it? + + * Add in "workshop title", "workshop description", and see the + ``.info.txt`` files that come out now. This is ready for + copy-pasting into a YouTube description (first line is the title, + rest is the description). + + Look at the new ``.info.txt`` files. What is new? + + .. solution:: + + * This course actually didn't have chapters for the first day + sessions, but you can `see chapters for day 2 here + `__, + for example. + * `Example of the workshop description for this course + `__ + * Example info.txt file for the general introduction to the + course. The part after the ``-----`` is the workshop description. + + .. code-block:: + + 1.2 Introduction - HPC/SciComp Kickstart summer 2023 + + General introduction to the workshop. + + https://scicomp.aalto.fi/training/kickstart/intro/ + + 00:00 Begin introduction <-- Invented for the exercise demo, not real + 03:25 Ways to attend <-- Invented for the exercise demo, not real + 07:12 What if you get lost <-- Invented for the exercise demo, not real + + ----- + + This is part of the Aalto Scientific Computing "Getting + started with Scientific Computing and HPC Kickstart" 2023 + workshop. The videos are available to everyone, but may be + most useful to the people who attended the workshop and want + to review later. + + Playlist: + https://www.youtube.com/playlist?list=PLZLVmS9rf3nMKR2jMglaN4su3ojWtWMVw + + Workshop webpage: + https://scicomp.aalto.fi/training/scip/kickstart-2023/ + + Aalto Scientific Computing: https://scicomp.aalto.fi/ + + +.. exercise:: Editing-6: Subtitles + + Re-run ffmpeg-editlist with the ``--srt`` option (you have to + install it with ``pip install ffmpeg-editlist[srt]`` to pull in the + necessary dependency). Notice how ``.srt`` files come out now. + + Use some subtitle editor to edit the *original* subtitle file, to + fix up any transcription mistakes you may find. You could edit + directly, use ``subtitle-editor`` on Linux, or find some other + tool. + + What do you learn from editing the subtitles? + + .. solution:: + + ..code-block:: + + $ ffmpeg-editlist --srt editlist.yaml + + There should now be a ``.srt`` file also generated. It + generated by finding the ``.srt`` of the original video, and + cutting it the same way it cuts the video. Look and you see it + aligns with the original. + + This means that someone could have been working on fixing the + Whisper subtitles while someone else was doing the yaml-editing. + + +.. exercise:: Editing-6: Subtitles + + Re-run ffmpeg-editlist with the ``--srt`` option (you have to + install it with ``pip install ffmpeg-editlist[srt]`` to pull in the + necessary dependency). Notice how ``.srt`` files come out now. + + Use some subtitle editor to edit the *original* subtitle file, to + fix up any transcription mistakes you may find. You could edit + directly, use ``subtitle-editor`` on Linux, or find some other + tool. + + What do you learn from editing the subtitles? + + +.. exercise:: Editing-7: Generate the final output file. + + * Run ffmpeg-editlist with the ``--reencode`` option: this + re-encodes the video and makes sure that there is no black point + at the start. + + * If you re-run with ``--check``, it won't output a new video file, + but it *will* re-output the ``.info.txt`` and ``.srt`` files. + This is useful when you adjust descriptions or chapters. + + +.. admonition:: Discussion: how to distribute this? + :class: discussion + + Create a flowchat of all the parts that need to be done, and which + parts can be done in parallel. Don't forget things that you might + need to do before the workshop starts. + + How hard was this editing? Was it worth it? + + + +Exercise B +~~~~~~~~~~ + +This is similar to the above but more brief and not on a real example +video. + +.. exercise:: Use ffmpeg-editlist to edit this sample video + + Prerequisites: ``ffmpeg`` must be installed on your computer + outside of Python. Be able to install ffmpeg-editlist. This is + simple in a Python virtual environment, but if not the only + dependency is ``PyYAML``. + + * Download the sample video: http://users.aalto.fi/~darstr1/sample-video/sample-video-to-edit.raw.mkv + * Copy a sample editlist YAML + * Modify it to cut out the dead time at the beginning and the end. + * If desired, add a description and table-of-contents to the + video. + * Run ffmpeg-editlist to produce a processed video. + +.. solution:: + + .. code:: yaml + + - input: sample-video-to-edit.raw.mkv + - output: sample-video-to-edit.processed.mkv + description: > + editlist: + - start: 00:16 + - 00:15: demonstration + - 00:20: discussion + - stop: 00:25 + + .. code:: console + + $ ffmpeg-editlist editlist.yaml video/ -o video/ + + Along with the processed video, we get + ``sample-video-to-edit.processed.mkv.info.txt``:: + + This is a sample video + + + 00:00 Demonstration + 00:04 Discussion + + + +See also +-------- + +* ffmpeg-editlist demo: https://www.youtube.com/watch?v=thvMNTBJg2Y +* Full demo of producing videos (everything in these exercises): https://www.youtube.com/watch?v=_CoBNe-n2Ak +* Example YAML editlists: + https://github.com/AaltoSciComp/video-editlists-asc diff --git a/branch/community-teaching/_sources/video-recording.md.txt b/branch/community-teaching/_sources/video-recording.md.txt new file mode 100644 index 0000000..4c051dc --- /dev/null +++ b/branch/community-teaching/_sources/video-recording.md.txt @@ -0,0 +1,64 @@ +# Video recording + +```{keypoints} +- We don't expect many people to watch the recording from scratch later (but + some do) (some might look afterwards a few pieces, cmp. reading a book vs + look ing sth up from a book) +- Learners getting an "instant replay" to review, or to **make up for a lost day**, is great. +- Privacy is more important than any other factor +- **Recording only works if privacy is guaranteed and effort is low**. + This is only possible with the **instructor-audience split setup** of livestreaming. +``` + + +## We try to release videos on the same day + +Video recordings could be useful for people attending a course later, but also +are (perhaps more) useful for **immediate review and catching up after missing +a day in a workshop**. + +For this, they need to be released immediately, within a few hours of the +workshop (see {doc}`video-editing`). CodeRefinery can do this. + +For the videos to be released soon we need to make sure we guarantee privacy of +learners (see below). Our livestream setup makes the privacy guarantee easy at +the cost of separating instructors and learners into different video rooms. + +Good preparation and documentation helps to make video recording and video +editing easier. + + +## Privacy is more important than any other factor + +If we can't guarantee privacy, we can't release videos at all. + +Some events add a disclaimers such as "if you don't want to appear +in a recording, leave your video off and don't say anything". We +would prefer not to do this, since: +- we *know* accidents happen (especially when coming back from breakout rooms) +- it creates an incentive to not interact by voice/video +- it could pressure participants to not object in order "to not be difficult" + +**Livestreaming solves this for us**: + +- By separating the instruction from + the audience audio/video, there is no privacy risk in the raw + recording. They could be released or shared unprocessed. + +- Recording with Zoom in a large meeting with all the instructors and + learners is simple, but not good for privacy: there are always + mistakes, reviewing takes too long. + +- Livestream platforms also provide instant recordings of the whole + stream, and some make instant replays possible. This could remove + the need for making our own videos, since one of the most important + cases is this instant replay idea. + + +## Broadcasting role and setup + +In the live-streaming setup, the Broadcasting role is central to video +recording. + +Broadcaster description (most is not directly about recording): + diff --git a/branch/community-teaching/_sources/welcome.md.txt b/branch/community-teaching/_sources/welcome.md.txt new file mode 100644 index 0000000..a3b9e8c --- /dev/null +++ b/branch/community-teaching/_sources/welcome.md.txt @@ -0,0 +1,65 @@ +# Welcome and introduction + +```{discussion} What do we want to get out of this workshop +- Introduction of instructors and helpers +- Each instructor can say what we want to get out of the instructor training +- But we want to know from everybody and collect these in the live notes +``` + +--- + +## Goals for this workshop + +```{discussion} Goals for this instructor training +- **Inspire teachers and staff who have to teach indirectly as part of + their job**: use best practices for the modern world, especially + for online teaching. +- **Promote collaboration in teaching**: less going alone. +- **Promote CodeRefinery sustainability**: form a network that can + work together to share the work and benefits. +``` + + +### Giving confidence + +> *Goal number one should be that we give participants the confidence to +> independently apply the tools or knowledge learnt. This is more important +> that giving a "complete" overview.* [Lucy Whalley gave this great comment at one of our workshops] + +- You don't have to know everything to use (or teach) something. +- For the large majority of topics we teach, there are many resources online + which provide how-to guides or tutorials. And the Stack Overflow answer bank + isn't getting any smaller. So we need to ask why do people attend in-person + sessions if there is information freely available? Our impression is that + it is for confidence building, identity formation, perhaps signposting to + resources. +- This also links with building a welcoming/inclusive environment: for example, + imposter syndrome, which disproportionately affects under-represented groups + ([link](https://www.ncda.org/aws/NCDA/pt/sd/news_article/245005/_PARENT/CC_layout_details/false)), + can manifest as low self-confidence --> building the confidence of + students in the classroom may lead to a more diverse community. + +--- + +## Tools for this workshop + +We often start workshops with these: +- [HackMD mechanics and controls](https://coderefinery.github.io/manuals/hackmd-mechanics/) +- [Zoom mechanics and controls](https://coderefinery.github.io/manuals/zoom-mechanics/) (but this got less relevant + since starting teaching via live-streaming where participants only interact via HackMD) + +--- + +## Code of Conduct + +- We follow [The CodeRefinery Code of + Conduct](https://coderefinery.org/about/code-of-conduct/). +- This is a hands-on, interactive workshop. + - Be kind to each other and help each other as best you can. + - If you can't help someone or there is some problem, let someone know. + - If you notice something that prevents you from learning as well as you can, let us know and don't suffer silently. +- It's also about the little things: + - volume + - font size + - generally confusing instructor + - **not enough breaks** diff --git a/branch/community-teaching/_sources/why-are-computers-hard.rst.txt b/branch/community-teaching/_sources/why-are-computers-hard.rst.txt new file mode 100644 index 0000000..a36b27a --- /dev/null +++ b/branch/community-teaching/_sources/why-are-computers-hard.rst.txt @@ -0,0 +1,65 @@ +Why are computers hard? +======================= + +Most of the time, when teaching, our difficulty is not what you expect. + + + +Initial reading +--------------- + +Read the following: + +.. admonition:: How to help someone use a computer, by Phil Agre + + https://www.librarian.net/stax/4965/how-to-help-someone-use-a-computer-by-phil-agre/ + +Of each of the points made, how many are related to: + +* The computing itself +* The user interface +* The ability of the user to work in the computing environment +* Something else + + + +Usability +--------- + +As said in the text above: + + Most user interfaces are terrible. When people make mistakes it’s + usually the fault of the interface. You’ve forgotten how many ways + you’ve learned to adapt to bad interfaces. You’ve forgotten how + many things you once assumed that the interface would be able to + do for you. + + + +Deep abstraction layers +----------------------- + +Most technology is built on abstraction layers, for good reason. They +help simplify implementation and understanding. + + +.. exercise:: + + Think of a tool or technology that is easy to understand and use if + you understand the underlying abstraction layers, but is almost + impossible otherwise. + + + +Conclusion: what are we teaching, then? +--------------------------------------- + +As teachers of computing, we fill a critical role that is more +determined by our audience, than the technology we are teaching. + + + +See also +-------- + +(none yet) diff --git a/branch/community-teaching/_sources/why-teach-together.rst.txt b/branch/community-teaching/_sources/why-teach-together.rst.txt new file mode 100644 index 0000000..c2831c3 --- /dev/null +++ b/branch/community-teaching/_sources/why-teach-together.rst.txt @@ -0,0 +1,84 @@ +Why teach together? +=================== + +We usually say so much about the value of collaboration. Despite us +saying this, our teaching is still far too alone. Covid-19 gave us a +kick that reduced our barriers and led to lasting changes in how we +taught (eventually leading to this very course). + +Open Science / FAIR data is heavily emphazised these days. But let's +add a "C" to FAIR: "collaborative". Instead of people doing their own +thing and releasing, develop, iterate, and maintain **collaboratively**. + + + +Ways to teach together +---------------------- + +* Develop materials together - avoid duplication. +* :doc:`team-teaching` +* Extensive use of helpers and team leaders. +* HackMD for parallel and mass answers. + + + +Advantages +---------- + +* You need to teach anyway, less effort if you combine. +* If done right, minimal extra effort for others to receive benefit (+ + you get publicity). +* Many of the previously presented teaching strategies work best in + large courses - this makes the course more engaging than a small + event with minimal interaction. +* More engaging for the audience. +* Easier on-boarding of new instructors (less "scary" to teach a new course + with other instructors). + + +Challenges and disadvantages +---------------------------- + +* Coordination + + * Finding suitable partners with the same vision + * Coordination efforts (if others don't understand the vision). + +* Materials + + * May not be perfectly tuned to your own audience + * May not iterate as fast as you need + +* Co-teaching + + * Difficulty in finding co-teachers + * Required effort of syncing among staff + * It might revert to independent teaching if you aren't careful. + +* HackMD + + * Can possibly overload both student and teacher. + + + +Exercises +--------- + +.. exercise:: What similarities do we have? + + Using HackMD, make two lists: + + * What courses do you think your local community would benefit + from, which you don't currently have? `+1` other people's items + which are also relevant to you. + + * Which courses are you thinking of preparing for your local + community? `+1` other people's items which you would be + interested in helping out with. + + + +See also +-------- + +* :doc:`collaboration-models` diff --git a/branch/community-teaching/_sources/workshop-roles.rst.txt b/branch/community-teaching/_sources/workshop-roles.rst.txt new file mode 100644 index 0000000..351b994 --- /dev/null +++ b/branch/community-teaching/_sources/workshop-roles.rst.txt @@ -0,0 +1,77 @@ +.. _workshop-roles: + +Workshop roles +============== + +Running massive workshops requires a lot of people. We have a variety +of roles with different levels of support. + +As usual, roles are a plan, and a plans are made to be updated. + + + +Primary articles +---------------- + +* Workshop roles: https://coderefinery.github.io/manuals/roles-overview/ + + + +Summary +------- + +Lower levels mean "top level sometimes split into some of these +sub-roles". + +* **Instructor coordinator:** coordinates schedule and instructors + + * **Instructor:** Teaches along with a co-teacher. + + * **Expert helper:** Spare person, usually watching HackMD but also + rotates among breakout rooms. Often instructs some lessons. + + * **Director:** Manages the flow of the schedule during the + workshop, introduces each lesson, etc. (often the instructor + coordinator) + + * **Broadcaster:** Manages the livestreaming + + * **Video editor:** Edits and publishes videos the day of the + workshop. + +* **Registration coordinator:** coordinates registration, helpers, and + breakout rooms. + + * **Exercise leader coordinator:** Onboards exercise leaders + * **Host:** Manages the learner breakout rooms, learner questions, + etc. (often the registration coordinator) + * **Advertisement coordinator:** Advertises and outreaches + +* Under both registration coordinator and instructor coordinator + + * **HackMD manager:** always watches and formats HackMD and + publishes it same-day. "Eyes on the ground" via HackMD and chat + and quickly communicates important information to instructor and + registration coordinators. + +* **Learner:** attends and learns +* **Exercise leader:** serves as a guide to the team, receives small + amount of training before the workshop. + + + +Exercises +--------- + +.. exercise:: How many people teach in your workshops? + + * Using HackMD, make a histogram of how many (instructors + + organizers) you typically have in your workshops. + * List some of the common roles you have used. + + + +See also +-------- + +(none yet) diff --git a/branch/community-teaching/_sources/workshops-online.md.txt b/branch/community-teaching/_sources/workshops-online.md.txt new file mode 100644 index 0000000..abf5222 --- /dev/null +++ b/branch/community-teaching/_sources/workshops-online.md.txt @@ -0,0 +1,256 @@ +--- +layout: episode +title: "Lessons learned from running online and in-person workshops" +teaching: 20 +exercises: 10 +questions: + - "What are the steps for organizing a CodeRefinery workshop?" + - "What can I learn about running my own workshop?" + - "What have we learned from running large online workshops?" +objectives: + - "Learn how to use the manuals to organize and teach a workshop." +keypoints: + - "There are many aspects to consider to deliver a successful workshop." + - "CodeRefinery maintains a number of manuals - use them when preparing a workshop." +--- + +> ## Workshop manuals +> CodeRefinery maintains a number of [workshop manuals](https://github.com/coderefinery/manuals/) +> with most of the "primary" information. This episode condenses this +> into a quick overview. +{: .callout} + + +# Running a workshop: online + + +## Online teaching discussion + +```{discussion} Discussion: Online vs in-person + +In notes: +- Compare and contrast the benefits of online teaching with + in-person: {advantage, disadvantage} × {content, presentation} +- How do you have to prepare differently? +- What are your own experiences? +``` + + + +## Case study: Mega-CodeRefinery and Finland HPC Kickstart + +- Mega-CodeRefinery + - Audience of around 90-100 + - "bring your own breakout room" (see below) + - 3 days/week, 6 days total + - Lessons as normal in CodeRefinery +- HPC Kickstart + - 250 registered, ~180 max participants + - Multi-university: local differences made this much harder to manage. + - Breakout rooms not pre-planned. + +Mega-CodeRefinery worked very well, HPC kickstart didn't - but not +because of the size. + + + +## General workshop arrangements + +> ## Manuals link +> - [before the +> workshop](https://github.com/coderefinery/manuals/blob/master/workshop-administration.md#before-the-workshop) +{: .callout} + +- Select a coordinator, recruit instructors (at least 3 is important), + find helpers +- Find a good lecture room: + [requirements](https://github.com/coderefinery/manuals/blob/master/workshop-requirements-inperson.md) +- Set up workshop webpage using the [Github, template + repository](https://github.com/coderefinery/template-workshop-webpage]: + [see + manuals](https://github.com/coderefinery/manuals/blob/master/workshop-administration.md#set-up-workshop-page) +- Advertising the workshop +- Communication with registered participants + + + +## CodeRefinery online scaling strategy + +- We started online workshops in 2020 March, for the obvious reasons. +- First, we started with two "normal size" (20 people) practice + workshops +- Then we did a 100 person workshop. It went well, but there is less + tolerance for problems. + + +### Basic preparation + +- You need more breaks are needed +- People have a way of doing too many things and not focusing. +- "[How to attend an online + workshop](https://coderefinery.github.io/manuals/how-to-attend-online/)" + guide to prepare learners + +### Basic platform: Zoom + +- Zoom (not the most ethical, but worked well and was available) +- [Zoom mechanics: instructions for + students](https://coderefinery.github.io/manuals/zoom-mechanics/). + - Mostly things that are known + - We don't use Zoom interaction features much anymore + (faster/slower/etc), but breakout rooms and HackMD instead +- See also: [Online training + manual](https://coderefinery.github.io/manuals/online-training/) + (which is getting a bit old compared to what is below). + +### Breakout rooms, bring your own team + +- Breakout rooms are + - Static: same people across whole workshop + - Contain one helper per room (see below) +- Team registration: accept a "team" field when registering, people on the + same team are put together. + - Gives motivations for learners to bring their colleagues and + learn together. + - More than one person learning together greatly increases update +- You need a powerful enough registration system to assign rooms and + email them to people! +- We ask people to name themselves "(N) Firstname Lastname" or "(N,H) + Firstname Lastname" for helpers. Then it is fast to assign them to + their designated breakout rooms. +- See also: [Breakout room + mechanics](https://coderefinery.github.io/manuals/breakout-rooms-helping/) + + +### Helper training + +- Each breakout room has a helper +- Helper should be a little bit familiar, but not expected to be able + to answer all questions. +- Special, custom [helper + training](https://coderefinery.github.io/manuals/helper-intro/) + since helpers make or break the workshop +- Helper recruitment: + - Our networks + - Team registration: if a team registers with their own helper, then + they are guaranteed to get in together. "bring your own breakout + room" + - Former learners, ask them to come back. +- Two helper trainings the week before the workshop. + +### Staff roles + +To reduce stress on any one person, we clearly define the different +roles and try to avoid overlap. We actually have enough people for +all of these, so it works well. + +- Workshop coordinator + - Registration, etc. +- Zoom host + - Handles registration, breakout rooms, recording, Zoom chat. +- HackMD helper + - Dedicated to watching HackMD and answering questions quickly. + - [Host on manuals](https://coderefinery.github.io/manuals/host/) +- Expert helpers + - "Spare hands" who rotate between breakout rooms and make sure + helpers are doing well. + - Give feedback to instructor about how breakout rooms are going. + - Take the place of missing helpers. + - Easy way for any people with a bit of spare time to help out. + - [Expert helpers in workshop](https://coderefinery.github.io/manuals/expert-helpers/) +- Instructors + - Teach, they shouldn't overlap with the above roles (but serve as + expert helpers other times). + - Usually also improve the lesson a bit before teaching + - [General staff intro in manuals](https://coderefinery.github.io/manuals/instructor-intro/) +- Workshop preparation meeting + - Get together, introduce roles, kickstart instructors + - [Workshop prep meeting in manuals](https://coderefinery.github.io/manuals/workshop-prep-call/) + + +### HackMD + +- We've been using it here +- Chat doesn't work wen large, written + document does. +- HackMD can just about scale to ~100 person workshop. Recommend + learners keep it in view mode while not editing. +- Voice questions are still allowed, but will be recorded. Staff + raise important questions from HackMD to the instructor immediately. +- HackMD also allows communication when in breakout rooms. +- You can get multiple answers, and answers can be improved over + time. +- [HackMD + mechanics](https://coderefinery.github.io/manuals/hackmd-mechanics/) + and [HackMD + helpers](https://coderefinery.github.io/manuals/hackmd-helper/). + +### Recording and streaming + +- When you have 100 people, main room is quiet anyway: you don't lose + much by recording. + - Questions anonymously in HackMD, privacy loss is not so bad +- Breakout rooms are never recorded +- Streaming + - We streamed via Twitch: https://twitch.tv/coderefinery + - We typically get 5-40 viewers. + - Zoom can directly send the stream to Twitch: no extra software + needed. + - Twitch archives videos for 14 days, which allows learners to get + an instant reply (we get hundreds of views in the next days). + - So while possibly not useful for new people to learn, the instant + reply *is* very useful. Instructor can also work on problems in + main stream during breakout rooms, which learners can watch + later. + - Streamers also have access to HackMD to ask questions. +- Certain tricks needed to keep learners from appearing in recording + or stream + - "Spotlight video", host does not go to gallery view, uses dual + monitor mode. We are still figuring this out. + +### Installation time + +- People *have* to be ready once we start, or else everything fails. +- Two installation help times the week before. +- Every email emphasizes that you have to be prepared, and "requires" + you to attend workshops (but really it's only) +- Installation instructions include *steps to verify* +- Installation instructions also include *video demonstrations* of + installation and verification. +- We haven't had that many installation problems, but also we keep the + requirements simple. +- Helper introduction is right before software install time, so + helpers can stay and help with install if they want. +- *Design to be easy to install and get set up.* + +### Other notes + +- Make breakout sessions as long as possible: 10 minutes is really too + short. 20 minutes is a good minimum time. +- Be very clear about exercise expectations +- Keep HackMD updated as a log. +- Don't combine breaks and breakout times. +- The more people you have, the more diverse audience you have and the + more people overwhelmed and under whelmed. + + + +## Workshop collaborations + +Why limit ourselves to CodeRefinery workshop? Why not use our network +and techniquess for more + +- Case study: [Python for Scientific + Computing](https://aaltoscicomp.github.io/python-for-scicomp/) + - Started by Aalto + - Announced to CodeRefinery, five more instructors from three + countries joined. + - Rapid collaboration, taught course shortly later. + - Announced to all institutions. Some places had physical rooms, + some were pure online + - Also streamed + - It was much more fun and less stressful to work together + +- We want to continue this kind of collaboration in other workshops. + + diff --git a/branch/community-teaching/_static/_sphinx_javascript_frameworks_compat.js b/branch/community-teaching/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 0000000..8141580 --- /dev/null +++ b/branch/community-teaching/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/branch/community-teaching/_static/basic.css b/branch/community-teaching/_static/basic.css new file mode 100644 index 0000000..f316efc --- /dev/null +++ b/branch/community-teaching/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/branch/community-teaching/_static/check-solid.svg b/branch/community-teaching/_static/check-solid.svg new file mode 100644 index 0000000..92fad4b --- /dev/null +++ b/branch/community-teaching/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/branch/community-teaching/_static/clipboard.min.js b/branch/community-teaching/_static/clipboard.min.js new file mode 100644 index 0000000..54b3c46 --- /dev/null +++ b/branch/community-teaching/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/branch/community-teaching/_static/copybutton.css b/branch/community-teaching/_static/copybutton.css new file mode 100644 index 0000000..f1916ec --- /dev/null +++ b/branch/community-teaching/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/branch/community-teaching/_static/copybutton.js b/branch/community-teaching/_static/copybutton.js new file mode 100644 index 0000000..2ea7ff3 --- /dev/null +++ b/branch/community-teaching/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/branch/community-teaching/_static/copybutton_funcs.js b/branch/community-teaching/_static/copybutton_funcs.js new file mode 100644 index 0000000..dbe1aaa --- /dev/null +++ b/branch/community-teaching/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/branch/community-teaching/_static/css/badge_only.css b/branch/community-teaching/_static/css/badge_only.css new file mode 100644 index 0000000..c718cee --- /dev/null +++ b/branch/community-teaching/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/branch/community-teaching/_static/css/fonts/Roboto-Slab-Bold.woff b/branch/community-teaching/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/branch/community-teaching/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/branch/community-teaching/_static/css/fonts/Roboto-Slab-Bold.woff2 b/branch/community-teaching/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/branch/community-teaching/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/branch/community-teaching/_static/css/fonts/Roboto-Slab-Regular.woff b/branch/community-teaching/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/branch/community-teaching/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/branch/community-teaching/_static/css/fonts/Roboto-Slab-Regular.woff2 b/branch/community-teaching/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/branch/community-teaching/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/branch/community-teaching/_static/css/fonts/fontawesome-webfont.eot b/branch/community-teaching/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/branch/community-teaching/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/branch/community-teaching/_static/css/fonts/fontawesome-webfont.svg b/branch/community-teaching/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/branch/community-teaching/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/branch/community-teaching/_static/css/fonts/fontawesome-webfont.ttf b/branch/community-teaching/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/branch/community-teaching/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/branch/community-teaching/_static/css/fonts/fontawesome-webfont.woff b/branch/community-teaching/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/branch/community-teaching/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/branch/community-teaching/_static/css/fonts/fontawesome-webfont.woff2 b/branch/community-teaching/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/branch/community-teaching/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/branch/community-teaching/_static/css/fonts/lato-bold-italic.woff b/branch/community-teaching/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/branch/community-teaching/_static/css/fonts/lato-bold-italic.woff differ diff --git a/branch/community-teaching/_static/css/fonts/lato-bold-italic.woff2 b/branch/community-teaching/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/branch/community-teaching/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/branch/community-teaching/_static/css/fonts/lato-bold.woff b/branch/community-teaching/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/branch/community-teaching/_static/css/fonts/lato-bold.woff differ diff --git a/branch/community-teaching/_static/css/fonts/lato-bold.woff2 b/branch/community-teaching/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/branch/community-teaching/_static/css/fonts/lato-bold.woff2 differ diff --git a/branch/community-teaching/_static/css/fonts/lato-normal-italic.woff b/branch/community-teaching/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/branch/community-teaching/_static/css/fonts/lato-normal-italic.woff differ diff --git a/branch/community-teaching/_static/css/fonts/lato-normal-italic.woff2 b/branch/community-teaching/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/branch/community-teaching/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/branch/community-teaching/_static/css/fonts/lato-normal.woff b/branch/community-teaching/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/branch/community-teaching/_static/css/fonts/lato-normal.woff differ diff --git a/branch/community-teaching/_static/css/fonts/lato-normal.woff2 b/branch/community-teaching/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/branch/community-teaching/_static/css/fonts/lato-normal.woff2 differ diff --git a/branch/community-teaching/_static/css/theme.css b/branch/community-teaching/_static/css/theme.css new file mode 100644 index 0000000..19a446a --- /dev/null +++ b/branch/community-teaching/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/branch/community-teaching/_static/doctools.js b/branch/community-teaching/_static/doctools.js new file mode 100644 index 0000000..4d67807 --- /dev/null +++ b/branch/community-teaching/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/branch/community-teaching/_static/documentation_options.js b/branch/community-teaching/_static/documentation_options.js new file mode 100644 index 0000000..87fc516 --- /dev/null +++ b/branch/community-teaching/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'dirhtml', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/branch/community-teaching/_static/file.png b/branch/community-teaching/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/branch/community-teaching/_static/file.png differ diff --git a/branch/community-teaching/_static/jquery.js b/branch/community-teaching/_static/jquery.js new file mode 100644 index 0000000..c4c6022 --- /dev/null +++ b/branch/community-teaching/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!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(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=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,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).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 w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\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(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.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,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){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 H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.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--)b.attrHandle[n[r]]=t}function pe(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 de(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 d=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")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.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}},b.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[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.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},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),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(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.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},j=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)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(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==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(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?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{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 G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.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("(^|"+M+")"+e+"("+M+"|$)"))&&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:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.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 S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(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").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.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),m(t)&&(t=t.call(e,n,S.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)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.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"===S.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"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.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)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.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?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.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)}}),S.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){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/community-teaching/_static/js/html5shiv.min.js b/branch/community-teaching/_static/js/html5shiv.min.js new file mode 100644 index 0000000..cd1c674 --- /dev/null +++ b/branch/community-teaching/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/community-teaching/_static/js/theme.js b/branch/community-teaching/_static/js/theme.js new file mode 100644 index 0000000..1fddb6e --- /dev/null +++ b/branch/community-teaching/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/branch/community-teaching/_static/minipres.js b/branch/community-teaching/_static/minipres.js new file mode 100644 index 0000000..ad11c87 --- /dev/null +++ b/branch/community-teaching/_static/minipres.js @@ -0,0 +1,223 @@ +// Add goTo method to elements +// http://stackoverflow.com/questions/4801655/how-to-go-to-a-specific-element-on-page +(function($) { + $.fn.goTo = function() { + $('html, body').animate({ + scrollTop: $(this).offset().top //+ 'px' + }, 'fast'); + return this; // for chaining... + } +})(jQuery); + +// NO good way to do this!. Copy a hack from here +// https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript +// https://stackoverflow.com/a/2880929 +var urlParams; +(window.onpopstate = function () { + var match, + pl = /\+/g, // Regex for replacing addition symbol with a space + search = /([^&=]+)=?([^&]*)/g, + decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, + query = window.location.search.substring(1); + urlParams = {}; + while (match = search.exec(query)) + urlParams[decode(match[1])] = decode(match[2]); +})(); + +// Select heading levels +var maxHeading = urlParams['h'] +if (maxHeading === undefined) maxHeading = 2 +var headingLevels = []; +for (h=2 ; h (sections.length-1) ) { + // if we would scroll past bottom, or above top, do nothing + return; + } + + console.log('xxxxxx'); + var targetSection = sections[targetPos]; + console.log(targetSection, typeof(targetSection)); + + // Return targetSection top and height + var secProperties = section_top_and_height(targetSection); + var top = secProperties['top']; + var height = secProperties['height'] + var win_height = window.innerHeight; + //console.info(top, height, win_height) + + var scroll_to = 0; + if (height >= win_height || height == 0) { + scroll_to = top; + } else { + scroll_to = top - (win_height-height)/3.; + } + //console.info(top, height, win_height, scroll_to) + + $('html, body').animate({ + scrollTop: scroll_to //+ 'px' + }, 'fast'); + +} + + +function minipres() { + /* Enable the minipres mode: + - call the hide() function + - set up the scrolling listener + */ + document.addEventListener('keydown', function (event) { + switch(event.which) { + case 37: // left + switch_slide(-1); + event.preventDefault(); + return false; + break; + //case 38: // up + case 39: // right + switch_slide(+1); + event.preventDefault(); + return false; + break; + //case 40: // down + default: + return; // exit this handler for other keys + } + }, true) + + hide() + + // Increase space between sections + //$("div .section").css('margin-bottom', '50%'); + $(sectionSelector).css('margin-top', '50%'); + + // Reduce size/color of other sections + if (hiddenSectionSelector.length > 0) { + var hideNodes = $(hiddenSectionSelector); + console.log(typeof hideNodes, hideNodes); + for (node in hideNodes) { + console.log("a", typeof node, node); + node = hideNodes[node]; // what's right way to iterate values? + console.log("b", typeof node, node); + if (node.parentNode && node.parentNode.className == "section") { + node = node.parentNode; + console.log("c", typeof node, node); + //node.css['transform'] = 'scale(.5)'; + //node.css['transform-origin'] = 'top center'; + $(node).css('color', 'lightgrey'); + //$(node).css('font-size', '20%'); + //$(node).css('visibility', 'collapse'); + //ntahousnatouhasno; + } + } + } +} + +function hide() { + /* Hide all non-essential elements on the page + */ + + // This is for sphinx_rst_theme and readthedocs + $(".wy-nav-side").remove(); + $(".wy-nav-content-wrap").css('margin-left', 0); + $('.rst-versions').remove(); // readthedocs version selector + + // Add other formats here. +} + + +var slideshow = minipres; + +if (window.location.search.match(/[?&](minipres|slideshow|pres)([=&]|$)/) ) { + //minipres() + window.addEventListener("load", minipres); +} else if (window.location.search.match(/[?&](plain)([=&]|$)/) ) { + window.addEventListener("load", hide); +} diff --git a/branch/community-teaching/_static/minus.png b/branch/community-teaching/_static/minus.png new file mode 100644 index 0000000..d96755f Binary files /dev/null and b/branch/community-teaching/_static/minus.png differ diff --git a/branch/community-teaching/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css b/branch/community-teaching/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css new file mode 100644 index 0000000..3356631 --- /dev/null +++ b/branch/community-teaching/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css @@ -0,0 +1,2342 @@ +/* Variables */ +:root { + --mystnb-source-bg-color: #f7f7f7; + --mystnb-stdout-bg-color: #fcfcfc; + --mystnb-stderr-bg-color: #fdd; + --mystnb-traceback-bg-color: #fcfcfc; + --mystnb-source-border-color: #ccc; + --mystnb-source-margin-color: green; + --mystnb-stdout-border-color: #f7f7f7; + --mystnb-stderr-border-color: #f7f7f7; + --mystnb-traceback-border-color: #ffd6d6; + --mystnb-hide-prompt-opacity: 70%; + --mystnb-source-border-radius: .4em; + --mystnb-source-border-width: 1px; +} + +/* Whole cell */ +div.container.cell { + padding-left: 0; + margin-bottom: 1em; +} + +/* Removing all background formatting so we can control at the div level */ +.cell_input div.highlight, +.cell_output pre, +.cell_input pre, +.cell_output .output { + border: none; + box-shadow: none; +} + +.cell_output .output pre, +.cell_input pre { + margin: 0px; +} + +/* Input cells */ +div.cell div.cell_input, +div.cell details.above-input>summary { + padding-left: 0em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + background-color: var(--mystnb-source-bg-color); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; + border-radius: var(--mystnb-source-border-radius); +} + +div.cell_input>div, +div.cell_output div.output>div.highlight { + margin: 0em !important; + border: none !important; +} + +/* All cell outputs */ +.cell_output { + padding-left: 1em; + padding-right: 0em; + margin-top: 1em; +} + +/* Text outputs from cells */ +.cell_output .output.text_plain, +.cell_output .output.traceback, +.cell_output .output.stream, +.cell_output .output.stderr { + margin-top: 1em; + margin-bottom: 0em; + box-shadow: none; +} + +.cell_output .output.text_plain, +.cell_output .output.stream { + background: var(--mystnb-stdout-bg-color); + border: 1px solid var(--mystnb-stdout-border-color); +} + +.cell_output .output.stderr { + background: var(--mystnb-stderr-bg-color); + border: 1px solid var(--mystnb-stderr-border-color); +} + +.cell_output .output.traceback { + background: var(--mystnb-traceback-bg-color); + border: 1px solid var(--mystnb-traceback-border-color); +} + +/* Collapsible cell content */ +div.cell details.above-input div.cell_input { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-top: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; +} + +div.cell div.cell_input.above-output-prompt { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +div.cell details.above-input>summary { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; + padding-left: 1em; + margin-bottom: 0; +} + +div.cell details.above-output>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.below-input>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-top: none; + border-bottom-left-radius: var(--mystnb-source-border-radius); + border-bottom-right-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.hide>summary>span { + opacity: var(--mystnb-hide-prompt-opacity); +} + +div.cell details.hide[open]>summary>span.collapsed { + display: none; +} + +div.cell details.hide:not([open])>summary>span.expanded { + display: none; +} + +@keyframes collapsed-fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} +div.cell details.hide[open]>summary~* { + -moz-animation: collapsed-fade-in 0.3s ease-in-out; + -webkit-animation: collapsed-fade-in 0.3s ease-in-out; + animation: collapsed-fade-in 0.3s ease-in-out; +} + +/* Math align to the left */ +.cell_output .MathJax_Display { + text-align: left !important; +} + +/* Pandas tables. Pulled from the Jupyter / nbsphinx CSS */ +div.cell_output table { + border: none; + border-collapse: collapse; + border-spacing: 0; + color: black; + font-size: 1em; + table-layout: fixed; +} + +div.cell_output thead { + border-bottom: 1px solid black; + vertical-align: bottom; +} + +div.cell_output tr, +div.cell_output th, +div.cell_output td { + text-align: right; + vertical-align: middle; + padding: 0.5em 0.5em; + line-height: normal; + white-space: normal; + max-width: none; + border: none; +} + +div.cell_output th { + font-weight: bold; +} + +div.cell_output tbody tr:nth-child(odd) { + background: #f5f5f5; +} + +div.cell_output tbody tr:hover { + background: rgba(66, 165, 245, 0.2); +} + +/** source code line numbers **/ +span.linenos { + opacity: 0.5; +} + +/* Inline text from `paste` operation */ + +span.pasted-text { + font-weight: bold; +} + +span.pasted-inline img { + max-height: 2em; +} + +tbody span.pasted-inline img { + max-height: none; +} + +/* Font colors for translated ANSI escape sequences +Color values are copied from Jupyter Notebook +https://github.com/jupyter/notebook/blob/52581f8eda9b319eb0390ac77fe5903c38f81e3e/notebook/static/notebook/less/ansicolors.less#L14-L21 +Background colors from +https://nbsphinx.readthedocs.io/en/latest/code-cells.html#ANSI-Colors +*/ +div.highlight .-Color-Bold { + font-weight: bold; +} + +div.highlight .-Color[class*=-Black] { + color: #3E424D +} + +div.highlight .-Color[class*=-Red] { + color: #E75C58 +} + +div.highlight .-Color[class*=-Green] { + color: #00A250 +} + +div.highlight .-Color[class*=-Yellow] { + color: #DDB62B +} + +div.highlight .-Color[class*=-Blue] { + color: #208FFB +} + +div.highlight .-Color[class*=-Magenta] { + color: #D160C4 +} + +div.highlight .-Color[class*=-Cyan] { + color: #60C6C8 +} + +div.highlight .-Color[class*=-White] { + color: #C5C1B4 +} + +div.highlight .-Color[class*=-BGBlack] { + background-color: #3E424D +} + +div.highlight .-Color[class*=-BGRed] { + background-color: #E75C58 +} + +div.highlight .-Color[class*=-BGGreen] { + background-color: #00A250 +} + +div.highlight .-Color[class*=-BGYellow] { + background-color: #DDB62B +} + +div.highlight .-Color[class*=-BGBlue] { + background-color: #208FFB +} + +div.highlight .-Color[class*=-BGMagenta] { + background-color: #D160C4 +} + +div.highlight .-Color[class*=-BGCyan] { + background-color: #60C6C8 +} + +div.highlight .-Color[class*=-BGWhite] { + background-color: #C5C1B4 +} + +/* Font colors for 8-bit ANSI */ + +div.highlight .-Color[class*=-C0] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC0] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C1] { + color: #800000 +} + +div.highlight .-Color[class*=-BGC1] { + background-color: #800000 +} + +div.highlight .-Color[class*=-C2] { + color: #008000 +} + +div.highlight .-Color[class*=-BGC2] { + background-color: #008000 +} + +div.highlight .-Color[class*=-C3] { + color: #808000 +} + +div.highlight .-Color[class*=-BGC3] { + background-color: #808000 +} + +div.highlight .-Color[class*=-C4] { + color: #000080 +} + +div.highlight .-Color[class*=-BGC4] { + background-color: #000080 +} + +div.highlight .-Color[class*=-C5] { + color: #800080 +} + +div.highlight .-Color[class*=-BGC5] { + background-color: #800080 +} + +div.highlight .-Color[class*=-C6] { + color: #008080 +} + +div.highlight .-Color[class*=-BGC6] { + background-color: #008080 +} + +div.highlight .-Color[class*=-C7] { + color: #C0C0C0 +} + +div.highlight .-Color[class*=-BGC7] { + background-color: #C0C0C0 +} + +div.highlight .-Color[class*=-C8] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC8] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C9] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC9] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C10] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC10] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C11] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC11] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C12] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC12] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C13] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC13] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C14] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC14] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C15] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC15] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C16] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC16] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C17] { + color: #00005F +} + +div.highlight .-Color[class*=-BGC17] { + background-color: #00005F +} + +div.highlight .-Color[class*=-C18] { + color: #000087 +} + +div.highlight .-Color[class*=-BGC18] { + background-color: #000087 +} + +div.highlight .-Color[class*=-C19] { + color: #0000AF +} + +div.highlight .-Color[class*=-BGC19] { + background-color: #0000AF +} + +div.highlight .-Color[class*=-C20] { + color: #0000D7 +} + +div.highlight .-Color[class*=-BGC20] { + background-color: #0000D7 +} + +div.highlight .-Color[class*=-C21] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC21] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C22] { + color: #005F00 +} + +div.highlight .-Color[class*=-BGC22] { + background-color: #005F00 +} + +div.highlight .-Color[class*=-C23] { + color: #005F5F +} + +div.highlight .-Color[class*=-BGC23] { + background-color: #005F5F +} + +div.highlight .-Color[class*=-C24] { + color: #005F87 +} + +div.highlight .-Color[class*=-BGC24] { + background-color: #005F87 +} + +div.highlight .-Color[class*=-C25] { + color: #005FAF +} + +div.highlight .-Color[class*=-BGC25] { + background-color: #005FAF +} + +div.highlight .-Color[class*=-C26] { + color: #005FD7 +} + +div.highlight .-Color[class*=-BGC26] { + background-color: #005FD7 +} + +div.highlight .-Color[class*=-C27] { + color: #005FFF +} + +div.highlight .-Color[class*=-BGC27] { + background-color: #005FFF +} + +div.highlight .-Color[class*=-C28] { + color: #008700 +} + +div.highlight .-Color[class*=-BGC28] { + background-color: #008700 +} + +div.highlight .-Color[class*=-C29] { + color: #00875F +} + +div.highlight .-Color[class*=-BGC29] { + background-color: #00875F +} + +div.highlight .-Color[class*=-C30] { + color: #008787 +} + +div.highlight .-Color[class*=-BGC30] { + background-color: #008787 +} + +div.highlight .-Color[class*=-C31] { + color: #0087AF +} + +div.highlight .-Color[class*=-BGC31] { + background-color: #0087AF +} + +div.highlight .-Color[class*=-C32] { + color: #0087D7 +} + +div.highlight .-Color[class*=-BGC32] { + background-color: #0087D7 +} + +div.highlight .-Color[class*=-C33] { + color: #0087FF +} + +div.highlight .-Color[class*=-BGC33] { + background-color: #0087FF +} + +div.highlight .-Color[class*=-C34] { + color: #00AF00 +} + +div.highlight .-Color[class*=-BGC34] { + background-color: #00AF00 +} + +div.highlight .-Color[class*=-C35] { + color: #00AF5F +} + +div.highlight .-Color[class*=-BGC35] { + background-color: #00AF5F +} + +div.highlight .-Color[class*=-C36] { + color: #00AF87 +} + +div.highlight .-Color[class*=-BGC36] { + background-color: #00AF87 +} + +div.highlight .-Color[class*=-C37] { + color: #00AFAF +} + +div.highlight .-Color[class*=-BGC37] { + background-color: #00AFAF +} + +div.highlight .-Color[class*=-C38] { + color: #00AFD7 +} + +div.highlight .-Color[class*=-BGC38] { + background-color: #00AFD7 +} + +div.highlight .-Color[class*=-C39] { + color: #00AFFF +} + +div.highlight .-Color[class*=-BGC39] { + background-color: #00AFFF +} + +div.highlight .-Color[class*=-C40] { + color: #00D700 +} + +div.highlight .-Color[class*=-BGC40] { + background-color: #00D700 +} + +div.highlight .-Color[class*=-C41] { + color: #00D75F +} + +div.highlight .-Color[class*=-BGC41] { + background-color: #00D75F +} + +div.highlight .-Color[class*=-C42] { + color: #00D787 +} + +div.highlight .-Color[class*=-BGC42] { + background-color: #00D787 +} + +div.highlight .-Color[class*=-C43] { + color: #00D7AF +} + +div.highlight .-Color[class*=-BGC43] { + background-color: #00D7AF +} + +div.highlight .-Color[class*=-C44] { + color: #00D7D7 +} + +div.highlight .-Color[class*=-BGC44] { + background-color: #00D7D7 +} + +div.highlight .-Color[class*=-C45] { + color: #00D7FF +} + +div.highlight .-Color[class*=-BGC45] { + background-color: #00D7FF +} + +div.highlight .-Color[class*=-C46] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC46] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C47] { + color: #00FF5F +} + +div.highlight .-Color[class*=-BGC47] { + background-color: #00FF5F +} + +div.highlight .-Color[class*=-C48] { + color: #00FF87 +} + +div.highlight .-Color[class*=-BGC48] { + background-color: #00FF87 +} + +div.highlight .-Color[class*=-C49] { + color: #00FFAF +} + +div.highlight .-Color[class*=-BGC49] { + background-color: #00FFAF +} + +div.highlight .-Color[class*=-C50] { + color: #00FFD7 +} + +div.highlight .-Color[class*=-BGC50] { + background-color: #00FFD7 +} + +div.highlight .-Color[class*=-C51] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC51] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C52] { + color: #5F0000 +} + +div.highlight .-Color[class*=-BGC52] { + background-color: #5F0000 +} + +div.highlight .-Color[class*=-C53] { + color: #5F005F +} + +div.highlight .-Color[class*=-BGC53] { + background-color: #5F005F +} + +div.highlight .-Color[class*=-C54] { + color: #5F0087 +} + +div.highlight .-Color[class*=-BGC54] { + background-color: #5F0087 +} + +div.highlight .-Color[class*=-C55] { + color: #5F00AF +} + +div.highlight .-Color[class*=-BGC55] { + background-color: #5F00AF +} + +div.highlight .-Color[class*=-C56] { + color: #5F00D7 +} + +div.highlight .-Color[class*=-BGC56] { + background-color: #5F00D7 +} + +div.highlight .-Color[class*=-C57] { + color: #5F00FF +} + +div.highlight .-Color[class*=-BGC57] { + background-color: #5F00FF +} + +div.highlight .-Color[class*=-C58] { + color: #5F5F00 +} + +div.highlight .-Color[class*=-BGC58] { + background-color: #5F5F00 +} + +div.highlight .-Color[class*=-C59] { + color: #5F5F5F +} + +div.highlight .-Color[class*=-BGC59] { + background-color: #5F5F5F +} + +div.highlight .-Color[class*=-C60] { + color: #5F5F87 +} + +div.highlight .-Color[class*=-BGC60] { + background-color: #5F5F87 +} + +div.highlight .-Color[class*=-C61] { + color: #5F5FAF +} + +div.highlight .-Color[class*=-BGC61] { + background-color: #5F5FAF +} + +div.highlight .-Color[class*=-C62] { + color: #5F5FD7 +} + +div.highlight .-Color[class*=-BGC62] { + background-color: #5F5FD7 +} + +div.highlight .-Color[class*=-C63] { + color: #5F5FFF +} + +div.highlight .-Color[class*=-BGC63] { + background-color: #5F5FFF +} + +div.highlight .-Color[class*=-C64] { + color: #5F8700 +} + +div.highlight .-Color[class*=-BGC64] { + background-color: #5F8700 +} + +div.highlight .-Color[class*=-C65] { + color: #5F875F +} + +div.highlight .-Color[class*=-BGC65] { + background-color: #5F875F +} + +div.highlight .-Color[class*=-C66] { + color: #5F8787 +} + +div.highlight .-Color[class*=-BGC66] { + background-color: #5F8787 +} + +div.highlight .-Color[class*=-C67] { + color: #5F87AF +} + +div.highlight .-Color[class*=-BGC67] { + background-color: #5F87AF +} + +div.highlight .-Color[class*=-C68] { + color: #5F87D7 +} + +div.highlight .-Color[class*=-BGC68] { + background-color: #5F87D7 +} + +div.highlight .-Color[class*=-C69] { + color: #5F87FF +} + +div.highlight .-Color[class*=-BGC69] { + background-color: #5F87FF +} + +div.highlight .-Color[class*=-C70] { + color: #5FAF00 +} + +div.highlight .-Color[class*=-BGC70] { + background-color: #5FAF00 +} + +div.highlight .-Color[class*=-C71] { + color: #5FAF5F +} + +div.highlight .-Color[class*=-BGC71] { + background-color: #5FAF5F +} + +div.highlight .-Color[class*=-C72] { + color: #5FAF87 +} + +div.highlight .-Color[class*=-BGC72] { + background-color: #5FAF87 +} + +div.highlight .-Color[class*=-C73] { + color: #5FAFAF +} + +div.highlight .-Color[class*=-BGC73] { + background-color: #5FAFAF +} + +div.highlight .-Color[class*=-C74] { + color: #5FAFD7 +} + +div.highlight .-Color[class*=-BGC74] { + background-color: #5FAFD7 +} + +div.highlight .-Color[class*=-C75] { + color: #5FAFFF +} + +div.highlight .-Color[class*=-BGC75] { + background-color: #5FAFFF +} + +div.highlight .-Color[class*=-C76] { + color: #5FD700 +} + +div.highlight .-Color[class*=-BGC76] { + background-color: #5FD700 +} + +div.highlight .-Color[class*=-C77] { + color: #5FD75F +} + +div.highlight .-Color[class*=-BGC77] { + background-color: #5FD75F +} + +div.highlight .-Color[class*=-C78] { + color: #5FD787 +} + +div.highlight .-Color[class*=-BGC78] { + background-color: #5FD787 +} + +div.highlight .-Color[class*=-C79] { + color: #5FD7AF +} + +div.highlight .-Color[class*=-BGC79] { + background-color: #5FD7AF +} + +div.highlight .-Color[class*=-C80] { + color: #5FD7D7 +} + +div.highlight .-Color[class*=-BGC80] { + background-color: #5FD7D7 +} + +div.highlight .-Color[class*=-C81] { + color: #5FD7FF +} + +div.highlight .-Color[class*=-BGC81] { + background-color: #5FD7FF +} + +div.highlight .-Color[class*=-C82] { + color: #5FFF00 +} + +div.highlight .-Color[class*=-BGC82] { + background-color: #5FFF00 +} + +div.highlight .-Color[class*=-C83] { + color: #5FFF5F +} + +div.highlight .-Color[class*=-BGC83] { + background-color: #5FFF5F +} + +div.highlight .-Color[class*=-C84] { + color: #5FFF87 +} + +div.highlight .-Color[class*=-BGC84] { + background-color: #5FFF87 +} + +div.highlight .-Color[class*=-C85] { + color: #5FFFAF +} + +div.highlight .-Color[class*=-BGC85] { + background-color: #5FFFAF +} + +div.highlight .-Color[class*=-C86] { + color: #5FFFD7 +} + +div.highlight .-Color[class*=-BGC86] { + background-color: #5FFFD7 +} + +div.highlight .-Color[class*=-C87] { + color: #5FFFFF +} + +div.highlight .-Color[class*=-BGC87] { + background-color: #5FFFFF +} + +div.highlight .-Color[class*=-C88] { + color: #870000 +} + +div.highlight .-Color[class*=-BGC88] { + background-color: #870000 +} + +div.highlight .-Color[class*=-C89] { + color: #87005F +} + +div.highlight .-Color[class*=-BGC89] { + background-color: #87005F +} + +div.highlight .-Color[class*=-C90] { + color: #870087 +} + +div.highlight .-Color[class*=-BGC90] { + background-color: #870087 +} + +div.highlight .-Color[class*=-C91] { + color: #8700AF +} + +div.highlight .-Color[class*=-BGC91] { + background-color: #8700AF +} + +div.highlight .-Color[class*=-C92] { + color: #8700D7 +} + +div.highlight .-Color[class*=-BGC92] { + background-color: #8700D7 +} + +div.highlight .-Color[class*=-C93] { + color: #8700FF +} + +div.highlight .-Color[class*=-BGC93] { + background-color: #8700FF +} + +div.highlight .-Color[class*=-C94] { + color: #875F00 +} + +div.highlight .-Color[class*=-BGC94] { + background-color: #875F00 +} + +div.highlight .-Color[class*=-C95] { + color: #875F5F +} + +div.highlight .-Color[class*=-BGC95] { + background-color: #875F5F +} + +div.highlight .-Color[class*=-C96] { + color: #875F87 +} + +div.highlight .-Color[class*=-BGC96] { + background-color: #875F87 +} + +div.highlight .-Color[class*=-C97] { + color: #875FAF +} + +div.highlight .-Color[class*=-BGC97] { + background-color: #875FAF +} + +div.highlight .-Color[class*=-C98] { + color: #875FD7 +} + +div.highlight .-Color[class*=-BGC98] { + background-color: #875FD7 +} + +div.highlight .-Color[class*=-C99] { + color: #875FFF +} + +div.highlight .-Color[class*=-BGC99] { + background-color: #875FFF +} + +div.highlight .-Color[class*=-C100] { + color: #878700 +} + +div.highlight .-Color[class*=-BGC100] { + background-color: #878700 +} + +div.highlight .-Color[class*=-C101] { + color: #87875F +} + +div.highlight .-Color[class*=-BGC101] { + background-color: #87875F +} + +div.highlight .-Color[class*=-C102] { + color: #878787 +} + +div.highlight .-Color[class*=-BGC102] { + background-color: #878787 +} + +div.highlight .-Color[class*=-C103] { + color: #8787AF +} + +div.highlight .-Color[class*=-BGC103] { + background-color: #8787AF +} + +div.highlight .-Color[class*=-C104] { + color: #8787D7 +} + +div.highlight .-Color[class*=-BGC104] { + background-color: #8787D7 +} + +div.highlight .-Color[class*=-C105] { + color: #8787FF +} + +div.highlight .-Color[class*=-BGC105] { + background-color: #8787FF +} + +div.highlight .-Color[class*=-C106] { + color: #87AF00 +} + +div.highlight .-Color[class*=-BGC106] { + background-color: #87AF00 +} + +div.highlight .-Color[class*=-C107] { + color: #87AF5F +} + +div.highlight .-Color[class*=-BGC107] { + background-color: #87AF5F +} + +div.highlight .-Color[class*=-C108] { + color: #87AF87 +} + +div.highlight .-Color[class*=-BGC108] { + background-color: #87AF87 +} + +div.highlight .-Color[class*=-C109] { + color: #87AFAF +} + +div.highlight .-Color[class*=-BGC109] { + background-color: #87AFAF +} + +div.highlight .-Color[class*=-C110] { + color: #87AFD7 +} + +div.highlight .-Color[class*=-BGC110] { + background-color: #87AFD7 +} + +div.highlight .-Color[class*=-C111] { + color: #87AFFF +} + +div.highlight .-Color[class*=-BGC111] { + background-color: #87AFFF +} + +div.highlight .-Color[class*=-C112] { + color: #87D700 +} + +div.highlight .-Color[class*=-BGC112] { + background-color: #87D700 +} + +div.highlight .-Color[class*=-C113] { + color: #87D75F +} + +div.highlight .-Color[class*=-BGC113] { + background-color: #87D75F +} + +div.highlight .-Color[class*=-C114] { + color: #87D787 +} + +div.highlight .-Color[class*=-BGC114] { + background-color: #87D787 +} + +div.highlight .-Color[class*=-C115] { + color: #87D7AF +} + +div.highlight .-Color[class*=-BGC115] { + background-color: #87D7AF +} + +div.highlight .-Color[class*=-C116] { + color: #87D7D7 +} + +div.highlight .-Color[class*=-BGC116] { + background-color: #87D7D7 +} + +div.highlight .-Color[class*=-C117] { + color: #87D7FF +} + +div.highlight .-Color[class*=-BGC117] { + background-color: #87D7FF +} + +div.highlight .-Color[class*=-C118] { + color: #87FF00 +} + +div.highlight .-Color[class*=-BGC118] { + background-color: #87FF00 +} + +div.highlight .-Color[class*=-C119] { + color: #87FF5F +} + +div.highlight .-Color[class*=-BGC119] { + background-color: #87FF5F +} + +div.highlight .-Color[class*=-C120] { + color: #87FF87 +} + +div.highlight .-Color[class*=-BGC120] { + background-color: #87FF87 +} + +div.highlight .-Color[class*=-C121] { + color: #87FFAF +} + +div.highlight .-Color[class*=-BGC121] { + background-color: #87FFAF +} + +div.highlight .-Color[class*=-C122] { + color: #87FFD7 +} + +div.highlight .-Color[class*=-BGC122] { + background-color: #87FFD7 +} + +div.highlight .-Color[class*=-C123] { + color: #87FFFF +} + +div.highlight .-Color[class*=-BGC123] { + background-color: #87FFFF +} + +div.highlight .-Color[class*=-C124] { + color: #AF0000 +} + +div.highlight .-Color[class*=-BGC124] { + background-color: #AF0000 +} + +div.highlight .-Color[class*=-C125] { + color: #AF005F +} + +div.highlight .-Color[class*=-BGC125] { + background-color: #AF005F +} + +div.highlight .-Color[class*=-C126] { + color: #AF0087 +} + +div.highlight .-Color[class*=-BGC126] { + background-color: #AF0087 +} + +div.highlight .-Color[class*=-C127] { + color: #AF00AF +} + +div.highlight .-Color[class*=-BGC127] { + background-color: #AF00AF +} + +div.highlight .-Color[class*=-C128] { + color: #AF00D7 +} + +div.highlight .-Color[class*=-BGC128] { + background-color: #AF00D7 +} + +div.highlight .-Color[class*=-C129] { + color: #AF00FF +} + +div.highlight .-Color[class*=-BGC129] { + background-color: #AF00FF +} + +div.highlight .-Color[class*=-C130] { + color: #AF5F00 +} + +div.highlight .-Color[class*=-BGC130] { + background-color: #AF5F00 +} + +div.highlight .-Color[class*=-C131] { + color: #AF5F5F +} + +div.highlight .-Color[class*=-BGC131] { + background-color: #AF5F5F +} + +div.highlight .-Color[class*=-C132] { + color: #AF5F87 +} + +div.highlight .-Color[class*=-BGC132] { + background-color: #AF5F87 +} + +div.highlight .-Color[class*=-C133] { + color: #AF5FAF +} + +div.highlight .-Color[class*=-BGC133] { + background-color: #AF5FAF +} + +div.highlight .-Color[class*=-C134] { + color: #AF5FD7 +} + +div.highlight .-Color[class*=-BGC134] { + background-color: #AF5FD7 +} + +div.highlight .-Color[class*=-C135] { + color: #AF5FFF +} + +div.highlight .-Color[class*=-BGC135] { + background-color: #AF5FFF +} + +div.highlight .-Color[class*=-C136] { + color: #AF8700 +} + +div.highlight .-Color[class*=-BGC136] { + background-color: #AF8700 +} + +div.highlight .-Color[class*=-C137] { + color: #AF875F +} + +div.highlight .-Color[class*=-BGC137] { + background-color: #AF875F +} + +div.highlight .-Color[class*=-C138] { + color: #AF8787 +} + +div.highlight .-Color[class*=-BGC138] { + background-color: #AF8787 +} + +div.highlight .-Color[class*=-C139] { + color: #AF87AF +} + +div.highlight .-Color[class*=-BGC139] { + background-color: #AF87AF +} + +div.highlight .-Color[class*=-C140] { + color: #AF87D7 +} + +div.highlight .-Color[class*=-BGC140] { + background-color: #AF87D7 +} + +div.highlight .-Color[class*=-C141] { + color: #AF87FF +} + +div.highlight .-Color[class*=-BGC141] { + background-color: #AF87FF +} + +div.highlight .-Color[class*=-C142] { + color: #AFAF00 +} + +div.highlight .-Color[class*=-BGC142] { + background-color: #AFAF00 +} + +div.highlight .-Color[class*=-C143] { + color: #AFAF5F +} + +div.highlight .-Color[class*=-BGC143] { + background-color: #AFAF5F +} + +div.highlight .-Color[class*=-C144] { + color: #AFAF87 +} + +div.highlight .-Color[class*=-BGC144] { + background-color: #AFAF87 +} + +div.highlight .-Color[class*=-C145] { + color: #AFAFAF +} + +div.highlight .-Color[class*=-BGC145] { + background-color: #AFAFAF +} + +div.highlight .-Color[class*=-C146] { + color: #AFAFD7 +} + +div.highlight .-Color[class*=-BGC146] { + background-color: #AFAFD7 +} + +div.highlight .-Color[class*=-C147] { + color: #AFAFFF +} + +div.highlight .-Color[class*=-BGC147] { + background-color: #AFAFFF +} + +div.highlight .-Color[class*=-C148] { + color: #AFD700 +} + +div.highlight .-Color[class*=-BGC148] { + background-color: #AFD700 +} + +div.highlight .-Color[class*=-C149] { + color: #AFD75F +} + +div.highlight .-Color[class*=-BGC149] { + background-color: #AFD75F +} + +div.highlight .-Color[class*=-C150] { + color: #AFD787 +} + +div.highlight .-Color[class*=-BGC150] { + background-color: #AFD787 +} + +div.highlight .-Color[class*=-C151] { + color: #AFD7AF +} + +div.highlight .-Color[class*=-BGC151] { + background-color: #AFD7AF +} + +div.highlight .-Color[class*=-C152] { + color: #AFD7D7 +} + +div.highlight .-Color[class*=-BGC152] { + background-color: #AFD7D7 +} + +div.highlight .-Color[class*=-C153] { + color: #AFD7FF +} + +div.highlight .-Color[class*=-BGC153] { + background-color: #AFD7FF +} + +div.highlight .-Color[class*=-C154] { + color: #AFFF00 +} + +div.highlight .-Color[class*=-BGC154] { + background-color: #AFFF00 +} + +div.highlight .-Color[class*=-C155] { + color: #AFFF5F +} + +div.highlight .-Color[class*=-BGC155] { + background-color: #AFFF5F +} + +div.highlight .-Color[class*=-C156] { + color: #AFFF87 +} + +div.highlight .-Color[class*=-BGC156] { + background-color: #AFFF87 +} + +div.highlight .-Color[class*=-C157] { + color: #AFFFAF +} + +div.highlight .-Color[class*=-BGC157] { + background-color: #AFFFAF +} + +div.highlight .-Color[class*=-C158] { + color: #AFFFD7 +} + +div.highlight .-Color[class*=-BGC158] { + background-color: #AFFFD7 +} + +div.highlight .-Color[class*=-C159] { + color: #AFFFFF +} + +div.highlight .-Color[class*=-BGC159] { + background-color: #AFFFFF +} + +div.highlight .-Color[class*=-C160] { + color: #D70000 +} + +div.highlight .-Color[class*=-BGC160] { + background-color: #D70000 +} + +div.highlight .-Color[class*=-C161] { + color: #D7005F +} + +div.highlight .-Color[class*=-BGC161] { + background-color: #D7005F +} + +div.highlight .-Color[class*=-C162] { + color: #D70087 +} + +div.highlight .-Color[class*=-BGC162] { + background-color: #D70087 +} + +div.highlight .-Color[class*=-C163] { + color: #D700AF +} + +div.highlight .-Color[class*=-BGC163] { + background-color: #D700AF +} + +div.highlight .-Color[class*=-C164] { + color: #D700D7 +} + +div.highlight .-Color[class*=-BGC164] { + background-color: #D700D7 +} + +div.highlight .-Color[class*=-C165] { + color: #D700FF +} + +div.highlight .-Color[class*=-BGC165] { + background-color: #D700FF +} + +div.highlight .-Color[class*=-C166] { + color: #D75F00 +} + +div.highlight .-Color[class*=-BGC166] { + background-color: #D75F00 +} + +div.highlight .-Color[class*=-C167] { + color: #D75F5F +} + +div.highlight .-Color[class*=-BGC167] { + background-color: #D75F5F +} + +div.highlight .-Color[class*=-C168] { + color: #D75F87 +} + +div.highlight .-Color[class*=-BGC168] { + background-color: #D75F87 +} + +div.highlight .-Color[class*=-C169] { + color: #D75FAF +} + +div.highlight .-Color[class*=-BGC169] { + background-color: #D75FAF +} + +div.highlight .-Color[class*=-C170] { + color: #D75FD7 +} + +div.highlight .-Color[class*=-BGC170] { + background-color: #D75FD7 +} + +div.highlight .-Color[class*=-C171] { + color: #D75FFF +} + +div.highlight .-Color[class*=-BGC171] { + background-color: #D75FFF +} + +div.highlight .-Color[class*=-C172] { + color: #D78700 +} + +div.highlight .-Color[class*=-BGC172] { + background-color: #D78700 +} + +div.highlight .-Color[class*=-C173] { + color: #D7875F +} + +div.highlight .-Color[class*=-BGC173] { + background-color: #D7875F +} + +div.highlight .-Color[class*=-C174] { + color: #D78787 +} + +div.highlight .-Color[class*=-BGC174] { + background-color: #D78787 +} + +div.highlight .-Color[class*=-C175] { + color: #D787AF +} + +div.highlight .-Color[class*=-BGC175] { + background-color: #D787AF +} + +div.highlight .-Color[class*=-C176] { + color: #D787D7 +} + +div.highlight .-Color[class*=-BGC176] { + background-color: #D787D7 +} + +div.highlight .-Color[class*=-C177] { + color: #D787FF +} + +div.highlight .-Color[class*=-BGC177] { + background-color: #D787FF +} + +div.highlight .-Color[class*=-C178] { + color: #D7AF00 +} + +div.highlight .-Color[class*=-BGC178] { + background-color: #D7AF00 +} + +div.highlight .-Color[class*=-C179] { + color: #D7AF5F +} + +div.highlight .-Color[class*=-BGC179] { + background-color: #D7AF5F +} + +div.highlight .-Color[class*=-C180] { + color: #D7AF87 +} + +div.highlight .-Color[class*=-BGC180] { + background-color: #D7AF87 +} + +div.highlight .-Color[class*=-C181] { + color: #D7AFAF +} + +div.highlight .-Color[class*=-BGC181] { + background-color: #D7AFAF +} + +div.highlight .-Color[class*=-C182] { + color: #D7AFD7 +} + +div.highlight .-Color[class*=-BGC182] { + background-color: #D7AFD7 +} + +div.highlight .-Color[class*=-C183] { + color: #D7AFFF +} + +div.highlight .-Color[class*=-BGC183] { + background-color: #D7AFFF +} + +div.highlight .-Color[class*=-C184] { + color: #D7D700 +} + +div.highlight .-Color[class*=-BGC184] { + background-color: #D7D700 +} + +div.highlight .-Color[class*=-C185] { + color: #D7D75F +} + +div.highlight .-Color[class*=-BGC185] { + background-color: #D7D75F +} + +div.highlight .-Color[class*=-C186] { + color: #D7D787 +} + +div.highlight .-Color[class*=-BGC186] { + background-color: #D7D787 +} + +div.highlight .-Color[class*=-C187] { + color: #D7D7AF +} + +div.highlight .-Color[class*=-BGC187] { + background-color: #D7D7AF +} + +div.highlight .-Color[class*=-C188] { + color: #D7D7D7 +} + +div.highlight .-Color[class*=-BGC188] { + background-color: #D7D7D7 +} + +div.highlight .-Color[class*=-C189] { + color: #D7D7FF +} + +div.highlight .-Color[class*=-BGC189] { + background-color: #D7D7FF +} + +div.highlight .-Color[class*=-C190] { + color: #D7FF00 +} + +div.highlight .-Color[class*=-BGC190] { + background-color: #D7FF00 +} + +div.highlight .-Color[class*=-C191] { + color: #D7FF5F +} + +div.highlight .-Color[class*=-BGC191] { + background-color: #D7FF5F +} + +div.highlight .-Color[class*=-C192] { + color: #D7FF87 +} + +div.highlight .-Color[class*=-BGC192] { + background-color: #D7FF87 +} + +div.highlight .-Color[class*=-C193] { + color: #D7FFAF +} + +div.highlight .-Color[class*=-BGC193] { + background-color: #D7FFAF +} + +div.highlight .-Color[class*=-C194] { + color: #D7FFD7 +} + +div.highlight .-Color[class*=-BGC194] { + background-color: #D7FFD7 +} + +div.highlight .-Color[class*=-C195] { + color: #D7FFFF +} + +div.highlight .-Color[class*=-BGC195] { + background-color: #D7FFFF +} + +div.highlight .-Color[class*=-C196] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC196] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C197] { + color: #FF005F +} + +div.highlight .-Color[class*=-BGC197] { + background-color: #FF005F +} + +div.highlight .-Color[class*=-C198] { + color: #FF0087 +} + +div.highlight .-Color[class*=-BGC198] { + background-color: #FF0087 +} + +div.highlight .-Color[class*=-C199] { + color: #FF00AF +} + +div.highlight .-Color[class*=-BGC199] { + background-color: #FF00AF +} + +div.highlight .-Color[class*=-C200] { + color: #FF00D7 +} + +div.highlight .-Color[class*=-BGC200] { + background-color: #FF00D7 +} + +div.highlight .-Color[class*=-C201] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC201] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C202] { + color: #FF5F00 +} + +div.highlight .-Color[class*=-BGC202] { + background-color: #FF5F00 +} + +div.highlight .-Color[class*=-C203] { + color: #FF5F5F +} + +div.highlight .-Color[class*=-BGC203] { + background-color: #FF5F5F +} + +div.highlight .-Color[class*=-C204] { + color: #FF5F87 +} + +div.highlight .-Color[class*=-BGC204] { + background-color: #FF5F87 +} + +div.highlight .-Color[class*=-C205] { + color: #FF5FAF +} + +div.highlight .-Color[class*=-BGC205] { + background-color: #FF5FAF +} + +div.highlight .-Color[class*=-C206] { + color: #FF5FD7 +} + +div.highlight .-Color[class*=-BGC206] { + background-color: #FF5FD7 +} + +div.highlight .-Color[class*=-C207] { + color: #FF5FFF +} + +div.highlight .-Color[class*=-BGC207] { + background-color: #FF5FFF +} + +div.highlight .-Color[class*=-C208] { + color: #FF8700 +} + +div.highlight .-Color[class*=-BGC208] { + background-color: #FF8700 +} + +div.highlight .-Color[class*=-C209] { + color: #FF875F +} + +div.highlight .-Color[class*=-BGC209] { + background-color: #FF875F +} + +div.highlight .-Color[class*=-C210] { + color: #FF8787 +} + +div.highlight .-Color[class*=-BGC210] { + background-color: #FF8787 +} + +div.highlight .-Color[class*=-C211] { + color: #FF87AF +} + +div.highlight .-Color[class*=-BGC211] { + background-color: #FF87AF +} + +div.highlight .-Color[class*=-C212] { + color: #FF87D7 +} + +div.highlight .-Color[class*=-BGC212] { + background-color: #FF87D7 +} + +div.highlight .-Color[class*=-C213] { + color: #FF87FF +} + +div.highlight .-Color[class*=-BGC213] { + background-color: #FF87FF +} + +div.highlight .-Color[class*=-C214] { + color: #FFAF00 +} + +div.highlight .-Color[class*=-BGC214] { + background-color: #FFAF00 +} + +div.highlight .-Color[class*=-C215] { + color: #FFAF5F +} + +div.highlight .-Color[class*=-BGC215] { + background-color: #FFAF5F +} + +div.highlight .-Color[class*=-C216] { + color: #FFAF87 +} + +div.highlight .-Color[class*=-BGC216] { + background-color: #FFAF87 +} + +div.highlight .-Color[class*=-C217] { + color: #FFAFAF +} + +div.highlight .-Color[class*=-BGC217] { + background-color: #FFAFAF +} + +div.highlight .-Color[class*=-C218] { + color: #FFAFD7 +} + +div.highlight .-Color[class*=-BGC218] { + background-color: #FFAFD7 +} + +div.highlight .-Color[class*=-C219] { + color: #FFAFFF +} + +div.highlight .-Color[class*=-BGC219] { + background-color: #FFAFFF +} + +div.highlight .-Color[class*=-C220] { + color: #FFD700 +} + +div.highlight .-Color[class*=-BGC220] { + background-color: #FFD700 +} + +div.highlight .-Color[class*=-C221] { + color: #FFD75F +} + +div.highlight .-Color[class*=-BGC221] { + background-color: #FFD75F +} + +div.highlight .-Color[class*=-C222] { + color: #FFD787 +} + +div.highlight .-Color[class*=-BGC222] { + background-color: #FFD787 +} + +div.highlight .-Color[class*=-C223] { + color: #FFD7AF +} + +div.highlight .-Color[class*=-BGC223] { + background-color: #FFD7AF +} + +div.highlight .-Color[class*=-C224] { + color: #FFD7D7 +} + +div.highlight .-Color[class*=-BGC224] { + background-color: #FFD7D7 +} + +div.highlight .-Color[class*=-C225] { + color: #FFD7FF +} + +div.highlight .-Color[class*=-BGC225] { + background-color: #FFD7FF +} + +div.highlight .-Color[class*=-C226] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC226] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C227] { + color: #FFFF5F +} + +div.highlight .-Color[class*=-BGC227] { + background-color: #FFFF5F +} + +div.highlight .-Color[class*=-C228] { + color: #FFFF87 +} + +div.highlight .-Color[class*=-BGC228] { + background-color: #FFFF87 +} + +div.highlight .-Color[class*=-C229] { + color: #FFFFAF +} + +div.highlight .-Color[class*=-BGC229] { + background-color: #FFFFAF +} + +div.highlight .-Color[class*=-C230] { + color: #FFFFD7 +} + +div.highlight .-Color[class*=-BGC230] { + background-color: #FFFFD7 +} + +div.highlight .-Color[class*=-C231] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC231] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C232] { + color: #080808 +} + +div.highlight .-Color[class*=-BGC232] { + background-color: #080808 +} + +div.highlight .-Color[class*=-C233] { + color: #121212 +} + +div.highlight .-Color[class*=-BGC233] { + background-color: #121212 +} + +div.highlight .-Color[class*=-C234] { + color: #1C1C1C +} + +div.highlight .-Color[class*=-BGC234] { + background-color: #1C1C1C +} + +div.highlight .-Color[class*=-C235] { + color: #262626 +} + +div.highlight .-Color[class*=-BGC235] { + background-color: #262626 +} + +div.highlight .-Color[class*=-C236] { + color: #303030 +} + +div.highlight .-Color[class*=-BGC236] { + background-color: #303030 +} + +div.highlight .-Color[class*=-C237] { + color: #3A3A3A +} + +div.highlight .-Color[class*=-BGC237] { + background-color: #3A3A3A +} + +div.highlight .-Color[class*=-C238] { + color: #444444 +} + +div.highlight .-Color[class*=-BGC238] { + background-color: #444444 +} + +div.highlight .-Color[class*=-C239] { + color: #4E4E4E +} + +div.highlight .-Color[class*=-BGC239] { + background-color: #4E4E4E +} + +div.highlight .-Color[class*=-C240] { + color: #585858 +} + +div.highlight .-Color[class*=-BGC240] { + background-color: #585858 +} + +div.highlight .-Color[class*=-C241] { + color: #626262 +} + +div.highlight .-Color[class*=-BGC241] { + background-color: #626262 +} + +div.highlight .-Color[class*=-C242] { + color: #6C6C6C +} + +div.highlight .-Color[class*=-BGC242] { + background-color: #6C6C6C +} + +div.highlight .-Color[class*=-C243] { + color: #767676 +} + +div.highlight .-Color[class*=-BGC243] { + background-color: #767676 +} + +div.highlight .-Color[class*=-C244] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC244] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C245] { + color: #8A8A8A +} + +div.highlight .-Color[class*=-BGC245] { + background-color: #8A8A8A +} + +div.highlight .-Color[class*=-C246] { + color: #949494 +} + +div.highlight .-Color[class*=-BGC246] { + background-color: #949494 +} + +div.highlight .-Color[class*=-C247] { + color: #9E9E9E +} + +div.highlight .-Color[class*=-BGC247] { + background-color: #9E9E9E +} + +div.highlight .-Color[class*=-C248] { + color: #A8A8A8 +} + +div.highlight .-Color[class*=-BGC248] { + background-color: #A8A8A8 +} + +div.highlight .-Color[class*=-C249] { + color: #B2B2B2 +} + +div.highlight .-Color[class*=-BGC249] { + background-color: #B2B2B2 +} + +div.highlight .-Color[class*=-C250] { + color: #BCBCBC +} + +div.highlight .-Color[class*=-BGC250] { + background-color: #BCBCBC +} + +div.highlight .-Color[class*=-C251] { + color: #C6C6C6 +} + +div.highlight .-Color[class*=-BGC251] { + background-color: #C6C6C6 +} + +div.highlight .-Color[class*=-C252] { + color: #D0D0D0 +} + +div.highlight .-Color[class*=-BGC252] { + background-color: #D0D0D0 +} + +div.highlight .-Color[class*=-C253] { + color: #DADADA +} + +div.highlight .-Color[class*=-BGC253] { + background-color: #DADADA +} + +div.highlight .-Color[class*=-C254] { + color: #E4E4E4 +} + +div.highlight .-Color[class*=-BGC254] { + background-color: #E4E4E4 +} + +div.highlight .-Color[class*=-C255] { + color: #EEEEEE +} + +div.highlight .-Color[class*=-BGC255] { + background-color: #EEEEEE +} diff --git a/branch/community-teaching/_static/plus.png b/branch/community-teaching/_static/plus.png new file mode 100644 index 0000000..7107cec Binary files /dev/null and b/branch/community-teaching/_static/plus.png differ diff --git a/branch/community-teaching/_static/pygments.css b/branch/community-teaching/_static/pygments.css new file mode 100644 index 0000000..84ab303 --- /dev/null +++ b/branch/community-teaching/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/branch/community-teaching/_static/searchtools.js b/branch/community-teaching/_static/searchtools.js new file mode 100644 index 0000000..92da3f8 --- /dev/null +++ b/branch/community-teaching/_static/searchtools.js @@ -0,0 +1,619 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlinks", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + let score = Math.round(100 * queryLower.length / title.length) + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/branch/community-teaching/_static/sphinx_highlight.js b/branch/community-teaching/_static/sphinx_highlight.js new file mode 100644 index 0000000..8a96c69 --- /dev/null +++ b/branch/community-teaching/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/branch/community-teaching/_static/sphinx_lesson.css b/branch/community-teaching/_static/sphinx_lesson.css new file mode 100644 index 0000000..14b20c6 --- /dev/null +++ b/branch/community-teaching/_static/sphinx_lesson.css @@ -0,0 +1,51 @@ +/* sphinx_lesson.css */ + +body.wy-body-for-nav img.with-border { + border: 2px solid; +} + +.rst-content .admonition-no-content { + padding-bottom: 0px; +} + +.rst-content .demo > .admonition-title::before { + content: "\01F440"; /* Eyes */ } +.rst-content .type-along > .admonition-title::before { + content: "\02328\0FE0F"; /* Keyboard */ } +.rst-content .exercise > .admonition-title::before { + content: "\0270D\0FE0F"; /* Hand */ } +.rst-content .solution > .admonition-title::before { + content: "\02714\0FE0E"; /* Check mark */ } +.rst-content .homework > .admonition-title::before { + content: "\01F4DD"; /* Memo */ } +.rst-content .discussion > .admonition-title::before { + content: "\01F4AC"; /* Speech balloon */ } +.rst-content .questions > .admonition-title::before { + content: "\02753\0FE0E"; /* Question mark */ } +.rst-content .prerequisites > .admonition-title::before { + content: "\02699"; /* Gear */ } +.rst-content .seealso > .admonition-title::before { + content: "\027A1\0FE0E"; /* Question mark */ } + + +/* instructor-note */ +.rst-content .instructor-note { + background: #e7e7e7; +} +.rst-content .instructor-note > .admonition-title { + background: #6a6a6a; +} +.rst-content .instructor-note > .admonition-title::before { + content: ""; +} + + +/* sphinx_toggle_button, make the font white */ +.rst-content .toggle.admonition button.toggle-button { + color: white; +} + +/* sphinx-togglebutton, remove underflow when toggled to hidden mode */ +.rst-content .admonition.toggle-hidden { + padding-bottom: 0px; +} diff --git a/branch/community-teaching/_static/sphinx_rtd_theme_ext_color_contrast.css b/branch/community-teaching/_static/sphinx_rtd_theme_ext_color_contrast.css new file mode 100644 index 0000000..e68feb8 --- /dev/null +++ b/branch/community-teaching/_static/sphinx_rtd_theme_ext_color_contrast.css @@ -0,0 +1,47 @@ +/* The following are for web accessibility of sphinx_rtd_theme: they + * solve some of the most frequent contrast issues. Remove when this + * solved: + * https://github.com/readthedocs/sphinx_rtd_theme/issues/971 + */ +/* background: #fcfcfc, note boxes #E7F2FA */ +a { color: #2573A7; } /* original #2980B9, #1F5C84; */ +body { color: #242424; } /* original #404040, #383838 */ +.wy-side-nav-search>a, .wy-side-nav-search .wy-dropdown>a { + color: #ffffff; +} /* original #fcfcfc */ +footer { color: #737373; } /* original gray=#808080*/ +footer span.commit code, footer span.commit .rst-content tt, .rst-content footer span.commit tt { + color: #737373; +} /* original gray=#808080*/ +.rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal { + color: #AB2314; +} +/* Sidebar background */ +.wy-side-nav-search { background-color: #277CB4;} + +/* Same, but for pygments */ +.highlight .ch { color: #3E7A89; } /* #! line */ +.highlight .c1 { color: #3E7A89; } /* also comments */ +.highlight .nv { color: #AD3ECC; } /* variable */ +.highlight .gp { color: #B45608; } /* prompt character, $*/ +.highlight .si { color: #3975B1; } /* ${} variable text */ +.highlight .nc { color: #0C78A7; } + +/* Sphinx admonitions */ +/* warning */ +.wy-alert.wy-alert-warning .wy-alert-title, .rst-content .wy-alert-warning.note .wy-alert-title, .rst-content .attention .wy-alert-title, .rst-content .caution .wy-alert-title, .rst-content .wy-alert-warning.danger .wy-alert-title, .rst-content .wy-alert-warning.error .wy-alert-title, .rst-content .wy-alert-warning.hint .wy-alert-title, .rst-content .wy-alert-warning.important .wy-alert-title, .rst-content .wy-alert-warning.tip .wy-alert-title, .rst-content .warning .wy-alert-title, .rst-content .wy-alert-warning.seealso .wy-alert-title, .rst-content .admonition-todo .wy-alert-title, .rst-content .wy-alert-warning.admonition .wy-alert-title, .wy-alert.wy-alert-warning .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-warning .admonition-title, .rst-content .wy-alert-warning.note .admonition-title, .rst-content .attention .admonition-title, .rst-content .caution .admonition-title, .rst-content .wy-alert-warning.danger .admonition-title, .rst-content .wy-alert-warning.error .admonition-title, .rst-content .wy-alert-warning.hint .admonition-title, .rst-content .wy-alert-warning.important .admonition-title, .rst-content .wy-alert-warning.tip .admonition-title, .rst-content .warning .admonition-title, .rst-content .wy-alert-warning.seealso .admonition-title, .rst-content .admonition-todo .admonition-title, .rst-content .wy-alert-warning.admonition .admonition-title { + background: #B15E16; } +/* important */ +.wy-alert.wy-alert-success .wy-alert-title, .rst-content .wy-alert-success.note .wy-alert-title, .rst-content .wy-alert-success.attention .wy-alert-title, .rst-content .wy-alert-success.caution .wy-alert-title, .rst-content .wy-alert-success.danger .wy-alert-title, .rst-content .wy-alert-success.error .wy-alert-title, .rst-content .hint .wy-alert-title, .rst-content .important .wy-alert-title, .rst-content .tip .wy-alert-title, .rst-content .wy-alert-success.warning .wy-alert-title, .rst-content .wy-alert-success.seealso .wy-alert-title, .rst-content .wy-alert-success.admonition-todo .wy-alert-title, .rst-content .wy-alert-success.admonition .wy-alert-title, .wy-alert.wy-alert-success .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-success .admonition-title, .rst-content .wy-alert-success.note .admonition-title, .rst-content .wy-alert-success.attention .admonition-title, .rst-content .wy-alert-success.caution .admonition-title, .rst-content .wy-alert-success.danger .admonition-title, .rst-content .wy-alert-success.error .admonition-title, .rst-content .hint .admonition-title, .rst-content .important .admonition-title, .rst-content .tip .admonition-title, .rst-content .wy-alert-success.warning .admonition-title, .rst-content .wy-alert-success.seealso .admonition-title, .rst-content .wy-alert-success.admonition-todo .admonition-title, .rst-content .wy-alert-success.admonition .admonition-title { + background: #12826C; } +/* seealso, note, etc */ +.wy-alert.wy-alert-info .wy-alert-title, .rst-content .note .wy-alert-title, .rst-content .wy-alert-info.attention .wy-alert-title, .rst-content .wy-alert-info.caution .wy-alert-title, .rst-content .wy-alert-info.danger .wy-alert-title, .rst-content .wy-alert-info.error .wy-alert-title, .rst-content .wy-alert-info.hint .wy-alert-title, .rst-content .wy-alert-info.important .wy-alert-title, .rst-content .wy-alert-info.tip .wy-alert-title, .rst-content .wy-alert-info.warning .wy-alert-title, .rst-content .seealso .wy-alert-title, .rst-content .wy-alert-info.admonition-todo .wy-alert-title, .rst-content .wy-alert-info.admonition .wy-alert-title, .wy-alert.wy-alert-info .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-info .admonition-title, .rst-content .note .admonition-title, .rst-content .wy-alert-info.attention .admonition-title, .rst-content .wy-alert-info.caution .admonition-title, .rst-content .wy-alert-info.danger .admonition-title, .rst-content .wy-alert-info.error .admonition-title, .rst-content .wy-alert-info.hint .admonition-title, .rst-content .wy-alert-info.important .admonition-title, .rst-content .wy-alert-info.tip .admonition-title, .rst-content .wy-alert-info.warning .admonition-title, .rst-content .seealso .admonition-title, .rst-content .wy-alert-info.admonition-todo .admonition-title, .rst-content .wy-alert-info.admonition .admonition-title { + background: #277CB4; } +/* error, danger */ +.rst-content .danger .admonition-title, .rst-content .danger .wy-alert-title, .rst-content .error .admonition-title, .rst-content .error .wy-alert-title, .rst-content .wy-alert-danger.admonition-todo .admonition-title, .rst-content .wy-alert-danger.admonition-todo .wy-alert-title, .rst-content .wy-alert-danger.admonition .admonition-title, .rst-content .wy-alert-danger.admonition .wy-alert-title, .rst-content .wy-alert-danger.attention .admonition-title, .rst-content .wy-alert-danger.attention .wy-alert-title, .rst-content .wy-alert-danger.caution .admonition-title, .rst-content .wy-alert-danger.caution .wy-alert-title, .rst-content .wy-alert-danger.hint .admonition-title, .rst-content .wy-alert-danger.hint .wy-alert-title, .rst-content .wy-alert-danger.important .admonition-title, .rst-content .wy-alert-danger.important .wy-alert-title, .rst-content .wy-alert-danger.note .admonition-title, .rst-content .wy-alert-danger.note .wy-alert-title, .rst-content .wy-alert-danger.seealso .admonition-title, .rst-content .wy-alert-danger.seealso .wy-alert-title, .rst-content .wy-alert-danger.tip .admonition-title, .rst-content .wy-alert-danger.tip .wy-alert-title, .rst-content .wy-alert-danger.warning .admonition-title, .rst-content .wy-alert-danger.warning .wy-alert-title, .rst-content .wy-alert.wy-alert-danger .admonition-title, .wy-alert.wy-alert-danger .rst-content .admonition-title, .wy-alert.wy-alert-danger .wy-alert-title { + background: #e31704; +} + +/* Generic admonition titles */ +.wy-alert-title, .rst-content .admonition-title { + background: #277CB4; } diff --git a/branch/community-teaching/_static/tabs.css b/branch/community-teaching/_static/tabs.css new file mode 100644 index 0000000..957ba60 --- /dev/null +++ b/branch/community-teaching/_static/tabs.css @@ -0,0 +1,89 @@ +.sphinx-tabs { + margin-bottom: 1rem; +} + +[role="tablist"] { + border-bottom: 1px solid #a0b3bf; +} + +.sphinx-tabs-tab { + position: relative; + font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; + color: #1D5C87; + line-height: 24px; + margin: 0; + font-size: 16px; + font-weight: 400; + background-color: rgba(255, 255, 255, 0); + border-radius: 5px 5px 0 0; + border: 0; + padding: 1rem 1.5rem; + margin-bottom: 0; +} + +.sphinx-tabs-tab[aria-selected="true"] { + font-weight: 700; + border: 1px solid #a0b3bf; + border-bottom: 1px solid white; + margin: -1px; + background-color: white; +} + +.sphinx-tabs-tab:focus { + z-index: 1; + outline-offset: 1px; +} + +.sphinx-tabs-panel { + position: relative; + padding: 1rem; + border: 1px solid #a0b3bf; + margin: 0px -1px -1px -1px; + border-radius: 0 0 5px 5px; + border-top: 0; + background: white; +} + +.sphinx-tabs-panel.code-tab { + padding: 0.4rem; +} + +.sphinx-tab img { + margin-bottom: 24 px; +} + +/* Dark theme preference styling */ + +@media (prefers-color-scheme: dark) { + body[data-theme="auto"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); + } + + body[data-theme="auto"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); + } + + body[data-theme="auto"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 1px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); + } +} + +/* Explicit dark theme styling */ + +body[data-theme="dark"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); +} + +body[data-theme="dark"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); +} + +body[data-theme="dark"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 2px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); +} diff --git a/branch/community-teaching/_static/tabs.js b/branch/community-teaching/_static/tabs.js new file mode 100644 index 0000000..48dc303 --- /dev/null +++ b/branch/community-teaching/_static/tabs.js @@ -0,0 +1,145 @@ +try { + var session = window.sessionStorage || {}; +} catch (e) { + var session = {}; +} + +window.addEventListener("DOMContentLoaded", () => { + const allTabs = document.querySelectorAll('.sphinx-tabs-tab'); + const tabLists = document.querySelectorAll('[role="tablist"]'); + + allTabs.forEach(tab => { + tab.addEventListener("click", changeTabs); + }); + + tabLists.forEach(tabList => { + tabList.addEventListener("keydown", keyTabs); + }); + + // Restore group tab selection from session + const lastSelected = session.getItem('sphinx-tabs-last-selected'); + if (lastSelected != null) selectNamedTabs(lastSelected); +}); + +/** + * Key focus left and right between sibling elements using arrows + * @param {Node} e the element in focus when key was pressed + */ +function keyTabs(e) { + const tab = e.target; + let nextTab = null; + if (e.keyCode === 39 || e.keyCode === 37) { + tab.setAttribute("tabindex", -1); + // Move right + if (e.keyCode === 39) { + nextTab = tab.nextElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.firstElementChild; + } + // Move left + } else if (e.keyCode === 37) { + nextTab = tab.previousElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.lastElementChild; + } + } + } + + if (nextTab !== null) { + nextTab.setAttribute("tabindex", 0); + nextTab.focus(); + } +} + +/** + * Select or deselect clicked tab. If a group tab + * is selected, also select tab in other tabLists. + * @param {Node} e the element that was clicked + */ +function changeTabs(e) { + // Use this instead of the element that was clicked, in case it's a child + const notSelected = this.getAttribute("aria-selected") === "false"; + const positionBefore = this.parentNode.getBoundingClientRect().top; + const notClosable = !this.parentNode.classList.contains("closeable"); + + deselectTabList(this); + + if (notSelected || notClosable) { + selectTab(this); + const name = this.getAttribute("name"); + selectNamedTabs(name, this.id); + + if (this.classList.contains("group-tab")) { + // Persist during session + session.setItem('sphinx-tabs-last-selected', name); + } + } + + const positionAfter = this.parentNode.getBoundingClientRect().top; + const positionDelta = positionAfter - positionBefore; + // Scroll to offset content resizing + window.scrollTo(0, window.scrollY + positionDelta); +} + +/** + * Select tab and show associated panel. + * @param {Node} tab tab to select + */ +function selectTab(tab) { + tab.setAttribute("aria-selected", true); + + // Show the associated panel + document + .getElementById(tab.getAttribute("aria-controls")) + .removeAttribute("hidden"); +} + +/** + * Hide the panels associated with all tabs within the + * tablist containing this tab. + * @param {Node} tab a tab within the tablist to deselect + */ +function deselectTabList(tab) { + const parent = tab.parentNode; + const grandparent = parent.parentNode; + + Array.from(parent.children) + .forEach(t => t.setAttribute("aria-selected", false)); + + Array.from(grandparent.children) + .slice(1) // Skip tablist + .forEach(panel => panel.setAttribute("hidden", true)); +} + +/** + * Select grouped tabs with the same name, but no the tab + * with the given id. + * @param {Node} name name of grouped tab to be selected + * @param {Node} clickedId id of clicked tab + */ +function selectNamedTabs(name, clickedId=null) { + const groupedTabs = document.querySelectorAll(`.sphinx-tabs-tab[name="${name}"]`); + const tabLists = Array.from(groupedTabs).map(tab => tab.parentNode); + + tabLists + .forEach(tabList => { + // Don't want to change the tabList containing the clicked tab + const clickedTab = tabList.querySelector(`[id="${clickedId}"]`); + if (clickedTab === null ) { + // Select first tab with matching name + const tab = tabList.querySelector(`.sphinx-tabs-tab[name="${name}"]`); + deselectTabList(tab); + selectTab(tab); + } + }) +} + +if (typeof exports === 'undefined') { + exports = {}; +} + +exports.keyTabs = keyTabs; +exports.changeTabs = changeTabs; +exports.selectTab = selectTab; +exports.deselectTabList = deselectTabList; +exports.selectNamedTabs = selectNamedTabs; diff --git a/branch/community-teaching/_static/term_role_formatting.css b/branch/community-teaching/_static/term_role_formatting.css new file mode 100644 index 0000000..0b66095 --- /dev/null +++ b/branch/community-teaching/_static/term_role_formatting.css @@ -0,0 +1,4 @@ +/* Make terms bold */ +a.reference span.std-term { + font-weight: bold; +} diff --git a/branch/community-teaching/_static/togglebutton.css b/branch/community-teaching/_static/togglebutton.css new file mode 100644 index 0000000..54a6787 --- /dev/null +++ b/branch/community-teaching/_static/togglebutton.css @@ -0,0 +1,160 @@ +/** + * Admonition-based toggles + */ + +/* Visibility of the target */ +.admonition.toggle .admonition-title ~ * { + transition: opacity .3s, height .3s; +} + +/* Toggle buttons inside admonitions so we see the title */ +.admonition.toggle { + position: relative; +} + +/* Titles should cut off earlier to avoid overlapping w/ button */ +.admonition.toggle .admonition-title { + padding-right: 25%; + cursor: pointer; +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:hover { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 1%); +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:active { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 3%); +} + +/* Remove extra whitespace below the admonition title when hidden */ +.admonition.toggle-hidden { + padding-bottom: 0; +} + +.admonition.toggle-hidden .admonition-title { + margin-bottom: 0; +} + +/* hides all the content of a page until de-toggled */ +.admonition.toggle-hidden .admonition-title ~ * { + height: 0; + margin: 0; + opacity: 0; + visibility: hidden; +} + +/* General button style and position*/ +button.toggle-button { + /** + * Background and shape. By default there's no background + * but users can style as they wish + */ + background: none; + border: none; + outline: none; + + /* Positioning just inside the admonition title */ + position: absolute; + right: 0.5em; + padding: 0px; + border: none; + outline: none; +} + +/* Display the toggle hint on wide screens */ +@media (min-width: 768px) { + button.toggle-button.toggle-button-hidden:before { + content: attr(data-toggle-hint); /* This will be filled in by JS */ + font-size: .8em; + align-self: center; + } +} + +/* Icon behavior */ +.tb-icon { + transition: transform .2s ease-out; + height: 1.5em; + width: 1.5em; + stroke: currentColor; /* So that we inherit the color of other text */ +} + +/* The icon should point right when closed, down when open. */ +/* Open */ +.admonition.toggle button .tb-icon { + transform: rotate(90deg); +} + +/* Closed */ +.admonition.toggle button.toggle-button-hidden .tb-icon { + transform: rotate(0deg); +} + +/* With details toggles, we don't rotate the icon so it points right */ +details.toggle-details .tb-icon { + height: 1.4em; + width: 1.4em; + margin-top: 0.1em; /* To center the button vertically */ +} + + +/** + * Details-based toggles. + * In this case, we wrap elements with `.toggle` in a details block. + */ + +/* Details blocks */ +details.toggle-details { + margin: 1em 0; +} + + +details.toggle-details summary { + display: flex; + align-items: center; + cursor: pointer; + list-style: none; + border-radius: .2em; + border-left: 3px solid #1976d2; + background-color: rgb(204 204 204 / 10%); + padding: 0.2em 0.7em 0.3em 0.5em; /* Less padding on left because the SVG has left margin */ + font-size: 0.9em; +} + +details.toggle-details summary:hover { + background-color: rgb(204 204 204 / 20%); +} + +details.toggle-details summary:active { + background: rgb(204 204 204 / 28%); +} + +.toggle-details__summary-text { + margin-left: 0.2em; +} + +details.toggle-details[open] summary { + margin-bottom: .5em; +} + +details.toggle-details[open] summary .tb-icon { + transform: rotate(90deg); +} + +details.toggle-details[open] summary ~ * { + animation: toggle-fade-in .3s ease-out; +} + +@keyframes toggle-fade-in { + from {opacity: 0%;} + to {opacity: 100%;} +} + +/* Print rules - we hide all toggle button elements at print */ +@media print { + /* Always hide the summary so the button doesn't show up */ + details.toggle-details summary { + display: none; + } +} \ No newline at end of file diff --git a/branch/community-teaching/_static/togglebutton.js b/branch/community-teaching/_static/togglebutton.js new file mode 100644 index 0000000..215a7ee --- /dev/null +++ b/branch/community-teaching/_static/togglebutton.js @@ -0,0 +1,187 @@ +/** + * Add Toggle Buttons to elements + */ + +let toggleChevron = ` + + + +`; + +var initToggleItems = () => { + var itemsToToggle = document.querySelectorAll(togglebuttonSelector); + console.log(`[togglebutton]: Adding toggle buttons to ${itemsToToggle.length} items`) + // Add the button to each admonition and hook up a callback to toggle visibility + itemsToToggle.forEach((item, index) => { + if (item.classList.contains("admonition")) { + // If it's an admonition block, then we'll add a button inside + // Generate unique IDs for this item + var toggleID = `toggle-${index}`; + var buttonID = `button-${toggleID}`; + + item.setAttribute('id', toggleID); + if (!item.classList.contains("toggle")){ + item.classList.add("toggle"); + } + // This is the button that will be added to each item to trigger the toggle + var collapseButton = ` + `; + + title = item.querySelector(".admonition-title") + title.insertAdjacentHTML("beforeend", collapseButton); + thisButton = document.getElementById(buttonID); + + // Add click handlers for the button + admonition title (if admonition) + admonitionTitle = document.querySelector(`#${toggleID} > .admonition-title`) + if (admonitionTitle) { + // If an admonition, then make the whole title block clickable + admonitionTitle.addEventListener('click', toggleClickHandler); + admonitionTitle.dataset.target = toggleID + admonitionTitle.dataset.button = buttonID + } else { + // If not an admonition then we'll listen for the button click + thisButton.addEventListener('click', toggleClickHandler); + } + + // Now hide the item for this toggle button unless explicitly noted to show + if (!item.classList.contains("toggle-shown")) { + toggleHidden(thisButton); + } + } else { + // If not an admonition, wrap the block in a
block + // Define the structure of the details block and insert it as a sibling + var detailsBlock = ` +
+ + ${toggleChevron} + ${toggleHintShow} + +
`; + item.insertAdjacentHTML("beforebegin", detailsBlock); + + // Now move the toggle-able content inside of the details block + details = item.previousElementSibling + details.appendChild(item) + item.classList.add("toggle-details__container") + + // Set up a click trigger to change the text as needed + details.addEventListener('click', (click) => { + let parent = click.target.parentElement; + if (parent.tagName.toLowerCase() == "details") { + summary = parent.querySelector("summary"); + details = parent; + } else { + summary = parent; + details = parent.parentElement; + } + // Update the inner text for the proper hint + if (details.open) { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintShow; + } else { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintHide; + } + + }); + + // If we have a toggle-shown class, open details block should be open + if (item.classList.contains("toggle-shown")) { + details.click(); + } + } + }) +}; + +// This should simply add / remove the collapsed class and change the button text +var toggleHidden = (button) => { + target = button.dataset['target'] + var itemToToggle = document.getElementById(target); + if (itemToToggle.classList.contains("toggle-hidden")) { + itemToToggle.classList.remove("toggle-hidden"); + button.classList.remove("toggle-button-hidden"); + } else { + itemToToggle.classList.add("toggle-hidden"); + button.classList.add("toggle-button-hidden"); + } +} + +var toggleClickHandler = (click) => { + // Be cause the admonition title is clickable and extends to the whole admonition + // We only look for a click event on this title to trigger the toggle. + + if (click.target.classList.contains("admonition-title")) { + button = click.target.querySelector(".toggle-button"); + } else if (click.target.classList.contains("tb-icon")) { + // We've clicked the icon and need to search up one parent for the button + button = click.target.parentElement; + } else if (click.target.tagName == "polyline") { + // We've clicked the SVG elements inside the button, need to up 2 layers + button = click.target.parentElement.parentElement; + } else if (click.target.classList.contains("toggle-button")) { + // We've clicked the button itself and so don't need to do anything + button = click.target; + } else { + console.log(`[togglebutton]: Couldn't find button for ${click.target}`) + } + target = document.getElementById(button.dataset['button']); + toggleHidden(target); +} + +// If we want to blanket-add toggle classes to certain cells +var addToggleToSelector = () => { + const selector = ""; + if (selector.length > 0) { + document.querySelectorAll(selector).forEach((item) => { + item.classList.add("toggle"); + }) + } +} + +// Helper function to run when the DOM is finished +const sphinxToggleRunWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} +sphinxToggleRunWhenDOMLoaded(addToggleToSelector) +sphinxToggleRunWhenDOMLoaded(initToggleItems) + +/** Toggle details blocks to be open when printing */ +if (toggleOpenOnPrint == "true") { + window.addEventListener("beforeprint", () => { + // Open the details + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.dataset["togglestatus"] = el.open; + el.open = true; + }); + + // Open the admonitions + document.querySelectorAll(".admonition.toggle.toggle-hidden").forEach((el) => { + console.log(el); + el.querySelector("button.toggle-button").click(); + el.dataset["toggle_after_print"] = "true"; + }); + }); + window.addEventListener("afterprint", () => { + // Re-close the details that were closed + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.open = el.dataset["togglestatus"] == "true"; + delete el.dataset["togglestatus"]; + }); + + // Re-close the admonition toggle buttons + document.querySelectorAll(".admonition.toggle").forEach((el) => { + if (el.dataset["toggle_after_print"] == "true") { + el.querySelector("button.toggle-button").click(); + delete el.dataset["toggle_after_print"]; + } + }); + }); +} diff --git a/branch/community-teaching/about-coderefinery/index.html b/branch/community-teaching/about-coderefinery/index.html new file mode 100644 index 0000000..89b48bc --- /dev/null +++ b/branch/community-teaching/about-coderefinery/index.html @@ -0,0 +1,285 @@ + + + + + + + About the CodeRefinery project and CodeRefinery workshops — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • + Edit on GitHub +
  • +
+
+
+
+
+ +
+

About the CodeRefinery project and CodeRefinery workshops

+
+

Keypoints

+
    +
  • Teaches intermediate-level software development tool lessons

  • +
  • Training network for other lessons, too

  • +
  • Publicly-funded discrete projects (3 projects actually) transitioning towards an open community project

  • +
  • We have online material, teaching, and exercise sessions

  • +
  • We want more people to work with us, and to work with more people

  • +
+
+

CodeRefinery is a +Nordic e-Infrastructure Collaboration (NeIC) +project that has started in October 2016 and is +funded until February 2025.

+

The funding from 2022-2025 is designed to keep this project active +beyond 2025 by forming a support network and building a community of +instructors and contributors.

+
+

History

+

The CodeRefinery project idea grew out of two SeSE courses given at KTH Stockholm in 2014 and 2016:

+ +

The project proposal was submitted to NeIC in 2015, accepted in 2015, and started in 2016.

+

We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form.

+
+
+

Main goals

+
    +
  • Develop and maintain training material on software best practices for researchers that already write code. Our material addresses all academic disciplines and tries to be as programming language-independent as possible.

  • +
  • Provide a code repository hosting service that is open and free for all researchers based in universities and research institutes from Nordic countries.

  • +
  • Provide training opportunities in the Nordics using Carpentries and CodeRefinery training materials.

  • +
  • Articulate and implement the CodeRefinery sustainability plan.

  • +
+
+
+

Impact

+

We collect feedback and survey results to measure our impact.

+

3-6 months after attending a workshop, past participants are asked to complete a short post-workshop survey. +The survey questions aim to establish what impact CodeRefinery workshops have on how past participants develop +research software.

+

Pre- and post-workshop survey results

+
    +
  • Overall quality of research software has improved: more reusable, modular, reproducible and documented.

  • +
  • Collaboration on research software development has become easier

  • +
  • Past participants share their new knowledge with colleagues

  • +
  • Usage of several tools is improved, and new tools are adopted

  • +
+

Free-form answers +also suggest that workshops are having the intended effects on how people develop code. A common theme is:

+
+

I wish I had known this stuff already as a grad student 10+ years ago…

+
+

We would love to get suggestions on how we can better quantify our impact. This +would make it easier for us to convince institutions to partner with us and +also open up funding opportunities.

+
+
+

Target audience

+
+

Carpentries audience

+

The Carpentries aims to teach computational competence to learners through an applied approach, avoiding the theoretical and general in favor of the practical and specific.

+

Learners do not need to have any prior experience in programming. One major goal of a Carpentry workshop is to raise awareness on the tools researchers can learn/use to speed up their research.

+

By showing learners how to solve specific problems with specific tools and providing hands-on practice, learners develops confidence for future learning.

+
+

Novices

+

We often qualify Carpentry learners as novices: they do not know what they need to learn yet. A typical example is the usage of version control: the Carpentry git lesson aims to give a very high level conceptual overview of Git but it does not explain how it can be used in research projects.

+
+
+
+

CodeRefinery audience

+

In that sense, CodeRefinery workshops differ from Carpentry workshops as we assume our audience already writes code and scripts and we aim at teaching them best software practices.

+

Our learners usually do not have a good overview of best software practices but are aware of the need to learn them. Very often, they know the tools (Git, Jupyter, etc.) we are teaching but have difficulties to make the best use of them in their software development workflow.

+

Whenever we can, we should direct learners that do not have sufficient coding experience to Carpentries workshops.

+
+

Competent practitioners

+

We often qualify CodeRefinery learners as competent practitioners because they already have an understanding of their needs. +Novices and competent practitioners will be more clearly defined in the next section.

+
+
+

Best software practices for whom?

+

It can be useful to ask the question: best software practices for whom? +CodeRefinery teaches best software practices derived from producing and +shipping software. These practices are also very good for sharing software, +though our audience will probably not need to embrace all aspects of +software engineering.

+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/backward-lesson-design/index.html b/branch/community-teaching/backward-lesson-design/index.html new file mode 100644 index 0000000..ec49cbc --- /dev/null +++ b/branch/community-teaching/backward-lesson-design/index.html @@ -0,0 +1,349 @@ + + + + + + + Backwards lesson design — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Backwards lesson design

+

It happens far too often: someone creates a lesson, but they think +about what is interesting to them, not what is important for the +learners. In fact, an earlier version of this instructor training had +this very issue.

+

It is critical to backwards design almost any piece of communication, +especially something as widespread as teaching.

+
+

The approach

+
    +
  • You don’t think about how to do something and try to explain it.

  • +
  • Avoid the typical approach “I want to show a number of things which I think are cool about +tool X - how do I press these into 90 minutes?”

  • +
  • Instead, you start defining your target audience by answering to questions +such What is the expected educational level of my audience?, Have they +been already exposed to the technologies I am planning to teach?, What +tools do they already use?, What are the main issues they are currently +experiencing?. It is important to discuss these points with a group of +colleagues, preferably from diverse backgrounds and institutions to reduce +biases. Once you clarified your target audience, it is useful to create +learner personas; that will help you during the development process by +providing concrete examples of potential learners showing up at your +workshops. For each learner personas, try to think of what is useful to +them: “What do they need to +remember/understand/apply/analyze/evaluate/create?”. +Asking and answering to these questions will allow you to define the +background knowledge (starting points) and goals (end points) of your +learners. Then, you create a sequence of exercises which test incrementally +progressing tasks and acquisition of the new skills (from starting to end +points).

  • +
  • Then, you write the minimum amount +of material to teach the gap between exercises.

  • +
+
+
+

The process

+

As described in “A lesson design process” in the book Teaching Tech +Together:

+
    +
  1. Understand your learners

  2. +
  3. Brainstorm rough ideas

  4. +
  5. Create an summative assessment to know your overall goal

    +
      +
    • CodeRefinery translation: think of the things your learners will +be able to do at the end of the lesson. Think simple! The +simpler the better. Think of three main points they will +remember, of which maybe one or two are a concrete skill.

    • +
    +
  6. +
  7. Create formative assessments to go from the starting point to this.

    +
      +
    • CodeRefinery translation: think of some engaging and active +exercises.

    • +
    +
  8. +
  9. Order the formative assessments (exercises) into a reasonable order.

  10. +
  11. Write just enough material to get from one assessment (exercise) to +another.

  12. +
  13. Describe the course so the learners know if it is relevant to them.

  14. +
+

We can’t emphasize enough how important it is to know your end +state and keep it simple.

+
+

Example: designing an HPC Carpentry lesson

+

Let’s take as an example the HPC Carpentry lesson

+

Target audience

+
    +
  • What is the expected educational level of my audience?

    +
      +
    • A PhD student, postdoc or young researcher.

    • +
    +
  • +
  • Have they been already exposed to the technologies I am planning to teach?

    +
      +
    • The word HPC is not new to them and they may have already used an HPC but are still not capable of giving a proper definition of HPC. In addition, we do not expect them to know much about parallelism and they cannot make any distinction between various available parallelism paradigms.

    • +
    +
  • +
  • What tools do they already use?

    +
      +
    • serial codes, multi-threaded codes, data parallelism; usually out-of-the-box tools.

    • +
    • they may have tried to “scale” their code (multiprocessing, threading, GPUs) with more or less success.

    • +
    +
  • +
  • What are the main issues they are currently experiencing?

    +
      +
    • they cannot solve their problems either because they would like to run the same code but with many different datasets or because their problem is larger (more computations/memory).

    • +
    • most of the time they know their codes can run on HPC (from the documentation) but never really had the opportunity to try it out.

    • +
    • Very few will have their own codes where they may have tried different things to speed it up (threading, task parallelism) but have no clear strategy.

    • +
    +
  • +
+

Learner persona

+
    +
  • Sonya is a 1st year PhD student: she recently moved to Oslo and joined the +Computational and Systems Neuroscience group. She will be using the +NEST, a simulator for spiking +neural network model. She used NEST during her master thesis but on her +small cluster: she never used an HPC resource and is really excited about it.

  • +
  • Robert is a field ecologist who obtained his PhD 6 months ago. He is now +working on a new project with Climate scientists and as a consequence will +need to run global climate models. He is not very familiar with command +line even though he attended a Software Carpentry workshop and the idea to +use HPC is a bit terrifying. He knows that he will get support from his +team who has extensive experience with HPC but would like to become more +independent and be able to run his own simulations (rather than copying +existing cases).

  • +
  • Jessica is a postdoc working on a project that investigates numerically the +complex dynamics arising at the tip of a fluid-driven rupture. Fluid +dynamics will be computed by a finite element method solving the +compressible Navier-Stokes equations on a moving mesh. She uses a code she +has developed during her PhD and that is based on existing libraries. She +has mostly ran it on a local desktop; her work during her PhD was very +limited due to the lack of computing resources and she is now very keen is +moving to HPC; she knows that it will requires some work, in particular to +parallelize her code. This HPC training will be her first experience with +HPC.

  • +
+

Learning outcomes

+
    +
  • Understand the difference between HPCs and other local/remote machines

  • +
  • Understand the notion of core, nodes, cluster, shared/distributed memory, etc.

  • +
  • Understand the notion of login nodes.

  • +
  • Understand the need for a scheduler and how to use it appropriately

  • +
  • Understand why optimising I/O is important on HPC and how to best use HPC filesystems

  • +
  • Understand the need to parallelize (or use existing parallel) codes and in which cases HPCs is a must (when communications is required)

  • +
  • Understand how to get your code ready to use on HPC (access to libraries, installation of your own libraries/software, etc.)

  • +
  • Understand that an HPC is an operational machine and is not meant for developing codes.

  • +
+

Exercises

+
    +
  • Get basic information such the number of CPUs, memory from your laptop and try to do the same on a HPC. Discuss outcomes.

  • +
  • Try to create files on the different filesystems on your HPC resource and access them.

  • +
  • Create different types of job scripts, submit and check outputs.

  • +
  • Make a concrete example to run a specific software on your HPC (something like GROMACS).

  • +
+
+
+
+

Exercises

+
+

Backwards-design a lesson/topic

+

Choose a simple lesson topic and apply backwards lesson design. You +won’t get all the way through, but come up with a logical +progression of exercises.

+

The section you pick should require screen sharing and be of some follow-along +task (preferably using a shell).

+

Some suggestions:

+
    +
  • Regular expressions

  • +
  • Making papers in LaTeX

  • +
  • Making figures in your favorite programming language

  • +
  • Linux shell basics

  • +
  • Something non-technical, such as painting a room

  • +
  • An instructor training for CodeRefinery

  • +
  • Some aspect from an already existing lesson

  • +
  • Introduction to high-performance computing (or an episode therein)

  • +
  • Unix shell in a HPC context (or an episode therein)

  • +
  • A lesson you always wanted to teach

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/collaboration-models/index.html b/branch/community-teaching/collaboration-models/index.html new file mode 100644 index 0000000..e7c5261 --- /dev/null +++ b/branch/community-teaching/collaboration-models/index.html @@ -0,0 +1,252 @@ + + + + + + + Collaboration models — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Collaboration models

+
+

Model: CodeRefinery

+
    +
  • Before Covid-19, workshops were physically around the Nordics, +instructors would travel (or already be there).

    +
      +
    • Maximum size: ~40 people

    • +
    • High workload per person

    • +
    +
  • +
  • After several small scaling attempts, now we have:

    +
      +
    • Two large workshops per year - livestream format

    • +
    • Combined organization efforts

    • +
    • Instructors from each location - on average two lessons taught.

    • +
    • Locations with staff can have local breakout rooms: physical +place to help during exercises.

    • +
    +
  • +
  • Others in the world can register and interact using HackMD, but no +promises of help.

  • +
  • Content still available to anyone in the world: live + instant +replay.

  • +
  • Course page and material: +https://coderefinery.github.io/2022-03-22-workshop/

  • +
+
+
+

Model: Python for Scientific Computing

+
    +
  • Aalto Scientific Computing wanted to host a course, Python for +Scientific Computing

  • +
  • ASC came up with initial vision and announced it

  • +
  • ASC hosted an open initial meeting, inviting any interested +organizers or instructors

  • +
  • We went over the plan and refined the topics and schedule. We also +decided things such as the date, organizers, and instructors for +each lesson.

  • +
  • Registration was open to everyone in the world, non-Nordic +participants could watch via livestream.

  • +
  • People prepared their parts and came together and presented. +Organizers kept everything on track.

  • +
  • Compared to the amount of effort each person put in, the results +were great.

  • +
  • A 2021 version also happened and was even larger.

  • +
  • Course page: https://scicomp.aalto.fi/training/scip/python-for-scicomp/

  • +
  • Material: https://aaltoscicomp.github.io/python-for-scicomp/

  • +
+
+
+

Exercises

+
+

List successes and failures in collaborative teaching

+

Using HackMD, list some successes and failures in collaborative +teaching that you have experienced.

+
+
+

Recommendations for co-teaching

+

If you have experience with co-teaching, what approach/technique/trick +can you recommend a colleague who would like to try co-teaching for the +first time?

+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/distributed/index.html b/branch/community-teaching/distributed/index.html new file mode 100644 index 0000000..3f91061 --- /dev/null +++ b/branch/community-teaching/distributed/index.html @@ -0,0 +1,221 @@ + + + + + + + Distributed workshop organization — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Distributed workshop organization

+
+

Keypoints

+
    +
  • If another university/organization wants to run the course, they can easily join our existing course at little cost/risk to them and to us.

  • +
  • Each organization that joins provides a great benefit to us (helpers, instructors).

  • +
  • They can reserve an in-person breakout room and provide mentors while watching the livestream: A great experience for their audience.

  • +
+
+
+

It is easier to join and follow than to start or lead

+

Organizing a course is time intensive and so is developing a course. Many +courses given in country A are also relevant in other countries and instead of +developing and possibly re-inventing courses independently in different places, +it is so much more rewarding to collaborate and share.

+

In our courses we wish and try to make it easier for teams and organizations +and universities to join, at little risk and cost to them, possibly for a short +period of time, possibly only as observer. Later observers can progress to +exercise leads, expert helpers, instructors, and co-organizers.

+

One model that we have successfully tried is that the course is delivered via +live-stream to all partners and all the partner needs to do is to reserve a +room and motivate few people to help local learners as exercise leads during +exercise sessions which can happen in-person.

+
+

Lessons learned from organizing larger workshops

+
    +
  • One person is needed to coordinate the registration process and this person should +not have teaching duties in addition to this role.

  • +
  • Generally it helps to have well-defined roles (see Workshop roles).

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/diversity-and-inclusion/index.html b/branch/community-teaching/diversity-and-inclusion/index.html new file mode 100644 index 0000000..841148d --- /dev/null +++ b/branch/community-teaching/diversity-and-inclusion/index.html @@ -0,0 +1,233 @@ + + + + + + + Diversity and inclusion — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Diversity and inclusion

+

When we are teaching, we fill a critical role in between people and +technology. We are not un-involved technical staff teaching asocial +topics, but we are very connected to the social context of the tools. +Unfortunately, there are major demographic imbalances in most +computing.

+
+

Primary articles

+ +
+
+

Support services vs diversity

+

Study this presentation by Richard Darst:

+ +

Summary:

+
    +
  • Computing is hard and quite often our ability to learn quickly is +connected to our social group.

  • +
  • Good technical services serve the role of mentors

  • +
  • This mentorship helps to equalize

  • +
  • Our entire system of research should be configured for more +equality. Modernization usually takes it the other way.

  • +
+
+
+

Exercises

+
+

Reflect on how your job can be defined to promote diversity.

+

What are some (possibly surprising) ways that your job promote +diversity and equality among people of different backgrounds?

+
+
+
+

See also

+

(none yet)

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/exercises/index.html b/branch/community-teaching/exercises/index.html new file mode 100644 index 0000000..f2a4c2e --- /dev/null +++ b/branch/community-teaching/exercises/index.html @@ -0,0 +1,948 @@ + + + + + + + Exercise list — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Exercise list

+

This is a list of all exercises and solutions in this lesson, mainly +as a reference for helpers and instructors. This list is +automatically generated from all of the other pages in the lesson. +Any single teaching event will probably cover only a subset of these, +depending on their interests.

+
+

Teaching online

+

In teaching-online.md:

+
+

Exercise

+

Using HackMD, brainstorm advantages and disadvantages of online and +in-person teaching. For each disadvantage of each, think of ways to compensate.

+
+
+
+

Team teaching

+

In team-teaching.rst:

+
+

Exercise

+

Divide into groups of two or three. Choose one of the two models +in the team-teaching page, and quickly (5 min) prepare a short +topic (3-5 min) to team teach. You can quickly scan the +“preparation” section at the bottom.

+

The challenge is not just to give the lesson, but to prepare the +lesson quickly and rely on each other to give a good lesson anyway.

+
+
+
+

HackMD

+

In hackmd.rst:

+
+

Exercise

+
    +
  • Actively use HackMD during this course.

  • +
  • Observe how the instructors integrate it during the course +itself, and can immediately respond to the questions.

  • +
  • Observe how instructors occasionally mention and screenshare +HackMD to validate to the audience that it is being watched.

  • +
  • Keep HackMD open. Can you balance it and watching. Does it +increase or decrease engagement?

  • +
+
+
+
+

Teams

+

In teams.rst:

+
+

Teams

+

Consider these questions:

+
    +
  • Should teams have similar or different people in them?

  • +
+
+
+
+

Livestreaming

+

In livestreaming.rst:

+
+

(advanced) Set up and install OBS as a livestreaming tool.

+

This exercise is open-ended.

+
+
+
+

Instructor tech setup

+

In instructor-tech-setup.md:

+
+

Evaluate screen captures

+

Evaluate screenshots within the instructor tech +setup lesson. +Use the collaborative document to make a list of the trade-offs of each one. +Which one do you prefer? Which are useful in each situation?

+
+

In instructor-tech-setup.md:

+
+

Set up your own environment

+

Set up your screen to teach something. Get some feedback from +another learner. We will discuss among the class.

+
+
+
+

Video editing

+

In video-editing.rst:

+
+

Editing-1: Get your sample video

+

Download a sample video:

+
+
+
+

In video-editing.rst:

+
+

Editing-2: Run Whisper to generate raw subtitles and test video.

+

First off, install Whisper and generate the base subtitles, based +on the. Since this is probably too much to expect for a short +lesson, they are provided for you (above), but if you want you can +try using Whisper, or generating the subtitles some other way.

+

You can start generating subtitles now, while you do the next +steps, so that they are ready by the time you are ready to apply +the editlist. ffmpeg-editlist can also slice up the subtitles from +the main video to make subtitles for each segment you cut out.

+

Whisper is left as an exercise to the reader.

+ +
+

In video-editing.rst:

+
+

Editing-3: Create the basic editlist.yaml file

+

Install ffmpeg-editlist and try to +follow its instructions, to create an edit with these features:

+
    +
  • The input definition.

  • +
  • Two output sections: the “Intro to the course”, and “From data +storage to your science” talks (Remember it said the recording +started at 11:35… look at the schedule for hints on when it +might start!). This should have a start/end timestamp from the +original video.

  • +
+

A basic example:

+
- input: day1-raw.mkv
+
+# This is the output from one section.  Your result should have two of these sections.
+- output: part1.mkv
+  title: something
+  description: >-
+    some long
+    description of the
+    segment
+  editlist:
+    - start: 10:00    # start timestamp of the section, in *original* video
+    - end: 20:00      # end timestamp of the section, in the *original* video
+
+
+ +
+

In video-editing.rst:

+
+

Editing-4: Run ffmpeg-editlist

+

Install ffmpeg-editlist: pip install ffmpeg-editlist[srt] (you +may want to use a virtual environment, but these are very minimal +dependencies).

+

The ffmpeg command line tool must be available in your +PATH.

+ +
+

In video-editing.rst:

+
+

Editing-5: Add more features

+
    +
  • Several chapter definitions.(re-run and you should see a +.info.txt file also generated). Video chapter definitions +are timestamps of the original video, that get translated to +timestamps of the output video.

    +
    - output: part1.mkv
    +  editlist:
    +  - start: 10:00
    +  - -: Introduction    #  <-- New, `-` means "at start time"
    +  - 10:45: Part 1      #  <-- New
    +  - 15:00: Part 2      #  <-- New
    +  - end: 20:00
    +
    +
    +

    Look at the .info.txt files that come out now. What is new in it?

    +
  • +
  • Add in “workshop title”, “workshop description”, and see the +.info.txt files that come out now. This is ready for +copy-pasting into a YouTube description (first line is the title, +rest is the description).

    +

    Look at the new .info.txt files. What is new?

    +
  • +
+ +
+

In video-editing.rst:

+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+ +
+

In video-editing.rst:

+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+
+

In video-editing.rst:

+
+

Editing-7: Generate the final output file.

+
    +
  • Run ffmpeg-editlist with the --reencode option: this +re-encodes the video and makes sure that there is no black point +at the start.

  • +
  • If you re-run with --check, it won’t output a new video file, +but it will re-output the .info.txt and .srt files. +This is useful when you adjust descriptions or chapters.

  • +
+
+

In video-editing.rst:

+
+

Use ffmpeg-editlist to edit this sample video

+

Prerequisites: ffmpeg must be installed on your computer +outside of Python. Be able to install ffmpeg-editlist. This is +simple in a Python virtual environment, but if not the only +dependency is PyYAML.

+ +
+

In video-editing.rst:

+ +
+
+

Why teach together?

+

In why-teach-together.rst:

+
+

What similarities do we have?

+

Using HackMD, make two lists:

+
    +
  • What courses do you think your local community would benefit +from, which you don’t currently have? +1 other people’s items +which are also relevant to you.

  • +
  • Which courses are you thinking of preparing for your local +community? +1 other people’s items which you would be +interested in helping out with.

  • +
+
+
+
+

Collaboration models

+

In collaboration-models.rst:

+
+

List successes and failures in collaborative teaching

+

Using HackMD, list some successes and failures in collaborative +teaching that you have experienced.

+
+

In collaboration-models.rst:

+
+

Recommendations for co-teaching

+

If you have experience with co-teaching, what approach/technique/trick +can you recommend a colleague who would like to try co-teaching for the +first time?

+
+
+
+

Workshop roles

+

In workshop-roles.rst:

+
+

How many people teach in your workshops?

+
    +
  • Using HackMD, make a histogram of how many (instructors + +organizers) you typically have in your workshops.

  • +
  • List some of the common roles you have used.

  • +
+
+
+
+

Why are computers hard?

+

In why-are-computers-hard.rst:

+
+

Exercise

+

Think of a tool or technology that is easy to understand and use if +you understand the underlying abstraction layers, but is almost +impossible otherwise.

+
+
+
+

Diversity and inclusion

+

In diversity-and-inclusion.rst:

+
+

Reflect on how your job can be defined to promote diversity.

+

What are some (possibly surprising) ways that your job promote +diversity and equality among people of different backgrounds?

+
+
+
+

Lesson development with version control

+

In lessons-with-version-control.md:

+
+

Contribute to a sample lesson

+
    +
  • Open this very lesson in GitHub (it uses the same format as +typical CodeRefinery lessons): +https://github.com/coderefinery/community-teaching/

  • +
  • Browse the files and understand the general idea. Check out at +least these and use HackMD to record their functions:

    +
      +
    • .github/workflows/sphinx.yml

    • +
    • content/conf.py

    • +
    • content/index.rst

    • +
    • content/lessons-with-version-control.rst

    • +
    +
  • +
  • If you want, try to make a pull request to this lesson. It +doesn’t have to have any significant content, it can be a pure +test pull request.

  • +
+
+

In lessons-with-version-control.md:

+
+

(advanced) Create your own lesson

+

Use the +sphinx-lesson-template +to create a new lesson of your choice. Alternatively, use the current +Carpentries system, or some other system of your choice.

+
+
+
+

Backwards lesson design

+

In backward-lesson-design.md:

+
+

Backwards-design a lesson/topic

+

Choose a simple lesson topic and apply backwards lesson design. You +won’t get all the way through, but come up with a logical +progression of exercises.

+

The section you pick should require screen sharing and be of some follow-along +task (preferably using a shell).

+

Some suggestions:

+
    +
  • Regular expressions

  • +
  • Making papers in LaTeX

  • +
  • Making figures in your favorite programming language

  • +
  • Linux shell basics

  • +
  • Something non-technical, such as painting a room

  • +
  • An instructor training for CodeRefinery

  • +
  • Some aspect from an already existing lesson

  • +
  • Introduction to high-performance computing (or an episode therein)

  • +
  • Unix shell in a HPC context (or an episode therein)

  • +
  • A lesson you always wanted to teach

  • +
+
+
+
+

CodeRefinery teaching philosophies

+

In 02-teaching-philosophies.md:

+
+

Ice-breaker in groups (20 minutes)

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also +Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+

In 02-teaching-philosophies.md:

+
+

Anne Fouilloux

+

I regularly teach Carpentries workshops so I try to apply what I have learnt to CodeRefinery workshops. However, I know our target audience is very much different and that I need to adapt my teaching style. I am still trying to find what works best in which situations and this is why I like so much CodeRefinery workshops. We usually have a wider range of skills and very mixed backgrounds so we usually have to be more careful with the pace and time given for exercises.

+

Some considerations:

+
    +
  • I spend quite a lot of time reading the CodeRefinery material and practising myself exercises. I particularly like to read the instructor notes just before teaching: they usually highlight important aspects both for preparing and teaching.

  • +
  • I usually do not show too much in advance the material as I think it prevents asking questions. If you have less competent practitioners in the classroom, they can easily copy-paste to avoid slowing down the entire classroom.

  • +
  • Ideally, I’d like to give several exercises so anyone can work at its own pace. I find it is important that everybody gets something different from the workshop.

  • +
  • I love breaks as it gives us an opportunity to discuss with attendees on their research topics. I am especially interested to understand what software they write and how they plan to use what they learn during our workshops.

  • +
+
+

In 02-teaching-philosophies.md:

+
+

Bjørn Lindi

+

My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this “BLOB” (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the “BLOB”, to be able to share it with others.

+

In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic.

+

When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson.

+

Tools that I find useful in preparing a lesson is concept maps and Learner Personas, though I have develop to few them.

+ +
+

In 02-teaching-philosophies.md:

+
+

Thor Wikfeldt

+

I never want to leave any learner behind and I really don’t like seeing confused, blank faces in the classroom. +At the same time I sometimes worry about some participants getting bored if a lesson is progressing slowly. +This is always a difficult compromise and something I struggle with!

+

I try to focus on making concepts intuitive, to “make sense” to the learners. Of course this is usually +based on how I learned the topic myself and how it makes sense to me.

+

I try to establish connections between topics: “this thing here is similar to what we saw in the previous +lesson where we learned about X…”.

+

Before mastering a lesson by teaching in many times I try to “follow the script”. After becoming very +familiar with a lesson I start to improvise more and react more dynamically to questions, e.g. by taking a +detour to explain a confusing topic more clearly.

+

What I think I do too often: copy-paste code/text from lesson material. This can leave learners behind - +typing out the code and describing it is slower, but more learning takes place. More advanced learners +will hopefully “be compensated” by interesting advanced exercises which follow.

+
+

In 02-teaching-philosophies.md:

+
+

Stefan Negru

+

A lesson is a conversation, it is useful if both the trainer and the trainee are engaged. +For that reason I try to have, most of the time, a conversation with the classroom and +after we finish parts of a lesson, step back and see how we might use what we learned.

+

That brings me to another point I follow throughout the lessons, answering questions like:

+
    +
  • How can we apply in practice what we just learned?

  • +
  • Do you see yourself (the trainee) using that in practice, why or why not?

  • +
+

Most of the times those seem like open-ended questions to the trainees that just learned +something new, so I try to find examples, most of the times from personal experience.

+

Last thing is that analogies are important when I teach, I try to find analogies in order +to simplify a convoluted part of a lesson.

+
+

In 02-teaching-philosophies.md:

+
+

Radovan Bast

+

My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos.

+

My goal for a lesson is to spark curiosity to try things after the lesson, +both for the novices (“This looks like a useful tool, I want to try using it +after the workshop.”) and the more experienced participants (“Aha - I did not +know you could do this. I wonder whether I can make it work with X.”). I like +to start lessons with a question because this makes participants look up from +their browsers.

+

Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise.

+

For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate +the answer.

+

I try to avoid jargon and “war stories” from the professional developers’ +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid “customer”, +“production”, also a lot of Agile jargon is hard to relate to.

+

Less and clear is better than more and unclear. Simple examples are better +than complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +“simply”, “just”, “easy”. If participants take home one or two points from +a lesson, that’s for me success.

+

I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don’t want to +be surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or +slide. This allows me to skip and distill the essence and not read bullet +point by bullet point.

+

I try to never deviate from the script and if I do, be very explicit about +it.

+

A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel.

+

I find it very helpful if there is somebody else in the room who helps me +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson but when doing that to +others, I am often worried of interrupting their flow and timing too much.

+

A mistake I often do is to type too fast and in my mind I force myself +to slow down.

+
+

In 02-teaching-philosophies.md:

+
+

Sabry Razick

+

My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case.

+
+

In 02-teaching-philosophies.md:

+
+

Juho Lehtonen

+

I’m gradually realising the different ways to get a hint whether the workshop +participants are still following or perhaps bored. I assume it’s communicating +with the class, with exercises and simply by asking now and then. I also try +to remember to observe how people look like (puzzled, bored) while I teach, not +so obvious for me.

+

I believe that learners communicating with each other, in addition to with +instructors and helpers, really helps them to understand things faster. (At least +it helps me). So I try to make sure that no one sits or works alone at the workshops.

+
+

In 02-teaching-philosophies.md:

+
+

Richard Darst

+

Like many people, I’ve often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I’ve realized long ago that my most important lessons weren’t +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I’ve realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds.

+

My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I’m often start at the +very basics, because this is what I see missing most often.

+

When teaching, I like lots of audience questions and don’t mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don’t have to know everything perfectly, just show how +you’d approach a problem.

+
+

In 02-teaching-philosophies.md:

+
+

João M. da Silva

+

I started giving technical trainings twenty years ago, and hence my perspective +is perhaps more inclined towards the development of hands-on abilities and +capability to solve problems, independently or in a team.

+

But the development of hands-on practical skills, requires some essential +knowledge about the domain and some willingness to try different approaches +in case one gets stuck. Some call this the “KSA approach” +(“Knowledge-Skills-Attitude). Hence, I +try to impart the essential knowledge (and where to find out more) at my +trainings. And to encourage and challenge students in order to make them +overcome their self-perceived limits (e.g. “I’m a Humanist, I can’t use +Python virtualenv”).

+

I’ve been trying to study more about the Cognitive aspects of learning over the years, +and I should find out the time to return to that. There’s very interesting +research in Problem Solving, with Learning being a important component in that domain.

+

Storytelling: humans are neurologically made for paying attention to good +stories, and that’s something that I try to put into account: to give +a lesson like it would be a relevant narrative for the students, one that they +could relate to and help them in their work

+

I like to draw and be creative with that, but have to pay attention to +my handwriting during my trainings. I reckon that Architectural diagrams +help students to understand the big picture, so I should invest more on +those when development training material. I would also like to start looking into +Concept Maps and Semantic Trees in training.

+
+
+
+

Interactive teaching style

+

In 03-teaching-style.md:

+ +

In 03-teaching-style.md:

+
+

Give feedback on teaching (optional, 10 mn)

+

This exercise aims at learning to give feedback. It is optional as we have +similar exercises when practising teaching). +As a group, we will watch this video of teaching and +give feedback on two axes: positive vs. negative and content vs. presentation. Have each person in +the class add one point to a 2x2 grid on a whiteboard or in the shared notes (hackMD, etherpad, google doc) without duplicating any points. +For online instructor training event, use breakout room (4-5 persons per group) to facilitate discussion. Then each group reports to the shared notes. +You can use a rubric (used during The Carpentries teaching demos) to help you take notes. +What did other people see that you missed? What did they think that you strongly agree or disagree with?

+
+

In 03-teaching-style.md:

+
+

Exercise: How to identify learner profiles?

+
    +
  1. How to identify leaner profiles from surveys and during the class

  2. +
  3. Which types of learners should the leassons focus on

  4. +
+
+
+
+

Teaching practice and feedback

+

In teaching-practice.md:

+
+

Exercise

+
    +
  • We organize the breakout rooms to not only discuss one lesson/topic so that it is more interesting +to listen and also probably we will all get more useful feedback.

  • +
  • Give each other constructive verbal feedback on the teaching demos, for example +using this demo rubric.

  • +
  • Write down questions (in the collaborative document) that you would like to +discuss in the main room or interesting conclusions which you would like to +share with others.

  • +
+
+

In teaching-practice.md:

+
+

Exercise

+
    +
  • In the second round we distribute the rooms differently so that you can +present it to a new group of workshop participants and can receive new +feedback.

  • +
  • Ask for feedback and one/few point(s) you want to improve.

  • +
  • In your second trial check whether you feel the demonstration improved.

  • +
  • Share your lessons learned in the collaborative document.

  • +
  • Give us also feedback on this exercise format. Was it useful? What can we improve?

  • +
+
+

In teaching-practice.md:

+
+

Exercise

+

Teaching by live coding is a +performance art which requires practice. +This exercise highlights some typical pitfalls that most instructors +fall into sooner or later, and also shows how to avoid them. +Watch closely since we will be giving feedback!

+
    +
  • Watch these two videos: video 1 and +video 2

  • +
  • What was better in video 1 and what was better in video 2?

  • +
  • Please give feedback in the shared workshop document.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/future/index.html b/branch/community-teaching/future/index.html new file mode 100644 index 0000000..5e5f115 --- /dev/null +++ b/branch/community-teaching/future/index.html @@ -0,0 +1,248 @@ + + + + + + + Possibilities for Carpentries — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Possibilities for Carpentries

+
+

Keypoints

+
    +
  • Carpentries is currently designed around small workshops, so many of these ideas can’t directly apply

  • +
  • Yet many of these tools and also team teaching can still be used

  • +
  • You can run your own breakout room for any of our workshops

  • +
  • Join as observer if you want to see our workshop organization and tools in action

  • +
+
+

CodeRefinery workshops can be a good progression step after taking a +Carpentries workshop.

+

Helping out at a CodeRefinery workshop as exercise lead can be a good +progression step for those who have helped out at a Carpentries workshop or who +have taken the Carpentries instructor training.

+
+
+

CodeRefinery’s plans

+
+

Keypoints

+
    +
  • We are continuing to focus on online-first with local breakout rooms

  • +
  • We welcome people joining us, either individually or as an organization

  • +
  • Still interested in collaboration with Carpentries

  • +
  • We need to become better at marketing and outreach

  • +
+
+
+

Biggest open problems

+
    +
  • How to give helpers and contributors more credit and visibility

  • +
  • How to promote/engage new members

  • +
  • What are we? Non-profit? Institution collaboration network? Selling services?

  • +
  • Funding and sustainability (but we have ideas: collaboration network)

  • +
+
+
+

How you can join

+

Individual level:

+
    +
  • Join CodeRefinery +chat

  • +
  • Lead a team, co-teach, or help organize a workshop

  • +
  • Generally provide marketing and outreach

  • +
+

Organization level:

+
    +
  • Have your organization join CodeRefinery

  • +
  • Officially co-advertise and co-teach workshops

  • +
  • Run local breakout rooms and join a workshop as a team

  • +
  • Send an observer to a workshop

  • +
+
+
+

Aside: Nordic-RSE (research software engineers)

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/genindex/index.html b/branch/community-teaching/genindex/index.html new file mode 100644 index 0000000..ab831f7 --- /dev/null +++ b/branch/community-teaching/genindex/index.html @@ -0,0 +1,182 @@ + + + + + + Index — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/branch/community-teaching/guide/index.html b/branch/community-teaching/guide/index.html new file mode 100644 index 0000000..2f11701 --- /dev/null +++ b/branch/community-teaching/guide/index.html @@ -0,0 +1,194 @@ + + + + + + + Instructor’s guide — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Instructor’s guide

+

In a lesson that was further developed, this would include an +instructor’s guide that mentioned:

+
    +
  • Background of why the course is how it is

  • +
  • Recommendations of teaching it

  • +
  • Known pitfalls of teaching it, so that other instructors can avoid +them

  • +
  • Possibly how to contribute, long-term plans, etc.

  • +
+

For example, see git-intro’s instructor guide.

+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/hackmd/index.html b/branch/community-teaching/hackmd/index.html new file mode 100644 index 0000000..4427cc9 --- /dev/null +++ b/branch/community-teaching/hackmd/index.html @@ -0,0 +1,252 @@ + + + + + + + HackMD — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

HackMD

+

The name “HackMD” doesn’t do this concept justice, nor do the more +common descriptions of “shared notes” or “collaborative document”. It +is a full replacement for chat: perhaps it could be called random +access chat or parallel 2D chat ?

+

HackMD itself is a web service for collaborative documents in +Markdown. This isn’t special to HackMD, but we have used it for its +scalability, markdown support, and privacy in the “view” mode.

+
+

Primary articles

+ +
+
+

Advantages

+
    +
  • Synchronous questions, no disadvantage for quiet people.

  • +
  • Anonymous questions.

  • +
  • Parallel answers by a large number of helpers.

  • +
  • Easier to go back and review past questions during Q&A sessions +(compared to scrolling through chat), for example finding important +or unanswered questions.

  • +
  • The above can make a course feel much more interactive than it would +otherwise.

  • +
+
+
+

Disadvantages

+
    +
  • Overwhelming flood of information

    +
      +
    • But you wanted more interaction, right?

    • +
    • Co-teaching helps here, one person can focus on watching.

    • +
    • Students must be warned to be deliberate about where they focus +their attention (different learners have different interests).

    • +
    +
  • +
  • It is another tool to use

    +
      +
    • Not required for basic learners, learners can begin using when +they are comfortable.

    • +
    +
  • +
+
+
+

Exercise

+
+

Exercise

+
    +
  • Actively use HackMD during this course.

  • +
  • Observe how the instructors integrate it during the course +itself, and can immediately respond to the questions.

  • +
  • Observe how instructors occasionally mention and screenshare +HackMD to validate to the audience that it is being watched.

  • +
  • Keep HackMD open. Can you balance it and watching. Does it +increase or decrease engagement?

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/index.html b/branch/community-teaching/index.html new file mode 100644 index 0000000..8ee41cd --- /dev/null +++ b/branch/community-teaching/index.html @@ -0,0 +1,311 @@ + + + + + + + Community teaching training — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Community teaching training

+
+

Under development (mid 2022)

+

As of mid-2022, this material has been reworked for our summer workshop and +for the CarpentryCon 2022 workshop. The material will continue to be +improved before a longer training session in the autumn.

+

This material is the new version of our previous Instructor +training.

+
+
+

What this course covers

+

In 2020, we got farther from our offices but closer to each other. If +you could adapt to the circumstances, a huge number of possibilities +were opened - in particular with collaborative teaching. In this +training, you will learn how we use them. Teaching from 2019 is +almost obsolete - join us to learn more.

+
    +
  • Tools of teaching: how to make the most out of online (and +other) teaching.

  • +
  • Workshop organization, collaboratively: our vision of teaching +together outside of our silos.

  • +
  • Socio-technical factors: social and technical barriers to +learning, why you need to care, and what you can do about them.

  • +
  • Lesson development, collaboratively: how to design lessons and +teaching materials so that they can be open and shared.

  • +
+
+
+

Who is the course for?

+

Teaching is a profession, but also something that everyone needs to be +able to do to some degree, since everyone has their own personal +specialties they will either teach or mentor.

+

This course can be relevant for different learner personas:

+
    +
  • You run a practical teaching program at your institution (for example +as part of a research computing group) and would like to learn best +practices for collaborative teaching, so that you aren’t re-inventing +the same thing over and over again.

  • +
  • You are a technical specialist who is frustrated with the way you +currently try to teach others who need to use your software or +infrastructure. You can’t spend too much time to become a +professional, but you know you need something more than what you’ve +been doing. Thus, you would like to adopt some of the best practices of +designing and teaching interactive, hands-on workshops.

  • +
  • You’ve been teaching alone, but would like to join a collaboration +network for more co-teaching and to reduce the amount of duplication +of effort.

  • +
  • You are interested in teaching CodeRefinery lessons, and would like a +comprehensive kick-start to how CodeRefinery works, either to join us, +or teach its lessons with us or independently.

  • +
+
+

Preparation

+ +
+ + + + + +
+

Wrap-up, future, and getting involved

+ +
+ + +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/instructor-tech-setup/index.html b/branch/community-teaching/instructor-tech-setup/index.html new file mode 100644 index 0000000..2700969 --- /dev/null +++ b/branch/community-teaching/instructor-tech-setup/index.html @@ -0,0 +1,279 @@ + + + + + + + Instructor tech setup — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Instructor tech setup

+
+

Keypoints

+
    +
  • Screenshare: portrait layout instead of sharing entire screen

  • +
  • Prompt: adjust your prompt to make commands easy to read

  • +
  • Readability and beauty is important: adjust your setup for your audience

  • +
  • Share the history of your commands

  • +
  • Get set up a few days in advance and get an outside reviewer

  • +
+
+
+

Screenshare

+

Compare the following two screen-shares (you can find many more in +the coderefinery manuals:

+
+https://coderefinery.github.io/manuals/_images/screenshare-fullhd.png +
+

FullHD.

+
+
+
+https://coderefinery.github.io/manuals/_images/s10-kickstart-prompt-log.png +
+

Portrait, latest proposed best practices.

+
+
+

Share a portrait layout (left or right half of your screen) +instead of sharing entire screen.

+

Motivation:

+
    +
  • This makes it easier for you to look at some other notes or to coordinate +with other instructors at the same time +without distracting with too much information.

  • +
  • This makes it possible for participants to have something else open in the +other screen half: terminal or browser or notebook.

  • +
+
+
+

Adjust your prompt/configuration/colors

+

Adjust your prompt to make commands easy to read. What looks good for your own +work (many terminals, small font, extensions, shortcuts, color scheme) is +usually not the best for other people watching you. Adjust your setup for your +audience. Remove distractions.

+

You need to spend some time getting set up before you teach. 10 minutes +before the session starts is typically too late. Get set up a few days in +advance and get an outside reviewer.

+
+

Should instructors be forced to have a consistent screenshare?

+

There are pros and cons to all instructors using the same screenshare and prompt.

+
    +
  • What are the advantages?

  • +
  • What are the opportunities of instructors showing different setups?

  • +
  • How does it depend on the lesson and the experience of learners?

  • +
+
+
+
+

Share the history of your commands

+

Even if you type slowly it is almost impossible to follow every command. We +all get distracted or want to read up on something or while following a command +fails on the learner laptop while instructor gets no error.

+

Add pauses and share the commands that you have typed so that one can catch up.

+
+
+

More examples and how to set it up

+ +
+
+

Exercises

+
+

Evaluate screen captures

+

Evaluate screenshots within the instructor tech +setup lesson. +Use the collaborative document to make a list of the trade-offs of each one. +Which one do you prefer? Which are useful in each situation?

+
+
+

Set up your own environment

+

Set up your screen to teach something. Get some feedback from +another learner. We will discuss among the class.

+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/lesson.pdf b/branch/community-teaching/lesson.pdf new file mode 100644 index 0000000..f9ae156 Binary files /dev/null and b/branch/community-teaching/lesson.pdf differ diff --git a/branch/community-teaching/lessons-with-version-control/index.html b/branch/community-teaching/lessons-with-version-control/index.html new file mode 100644 index 0000000..6df222b --- /dev/null +++ b/branch/community-teaching/lessons-with-version-control/index.html @@ -0,0 +1,294 @@ + + + + + + + Lesson development with version control — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Lesson development with version control

+

So, we want to practically share. We have these minimum requirements:

+
    +
  • Someone can get the preferred form of modification, to improve +without limitation.

  • +
  • It is trivial to track differences and send the changes back to the +source, with little cost to the original maintainer.

  • +
+

Especially with the second of these, version control in an online +platform seems to be the only reasonable option.

+
+

Version control and static site generators

+

CodeRefinery and the Carpentries use git and Github to develop +lessons. The general procedure is this:

+
    +
  • Version control to store the raw files in text format

  • +
  • A static website compiler to convert them to HTML files

  • +
  • Serving to the public via Github Pages (but this could be replaced +with other systems)

  • +
+

This allows for true collaborative development and community +contributions.

+

Carpentries uses a custom website complierer based on R, CodeRefinery +uses the Sphinx documentation engine which is used in many different +projects for documentation. CodeRefinery’s use of a standard tool +allows us to build on a huge and growing ecosystem of extensions and +themes, and promotes local reuse.

+

The exact static website generator used isn’t so important, as long as +some form of version control is used.

+

A open-source license is the last bit to consider: without a license, +it can’t be reused and passed on, and there is little incentive for +someone to contribute.

+
+
+

CodeRefinery lesson tools

+

CodeRefinery uses the following tools to actually make its lessons +right now:

+
    +
  • Sphinx (a common documentation +generator, widely used in open source projects in general)

  • +
  • The sphinx-lesson, which is more of +a small collection of other extensions than new development itself.

  • +
  • Github for hosting lessons: https://github.com/coderefinery/

  • +
  • Github Actions and Github Pages for building and web serving our +lessons.

  • +
+
+
+

Exercises

+
+

Contribute to a sample lesson

+
    +
  • Open this very lesson in GitHub (it uses the same format as +typical CodeRefinery lessons): +https://github.com/coderefinery/community-teaching/

  • +
  • Browse the files and understand the general idea. Check out at +least these and use HackMD to record their functions:

    +
      +
    • .github/workflows/sphinx.yml

    • +
    • content/conf.py

    • +
    • content/index.rst

    • +
    • content/lessons-with-version-control.rst

    • +
    +
  • +
  • If you want, try to make a pull request to this lesson. It +doesn’t have to have any significant content, it can be a pure +test pull request.

  • +
+
+
+

(advanced) Create your own lesson

+

Use the +sphinx-lesson-template +to create a new lesson of your choice. Alternatively, use the current +Carpentries system, or some other system of your choice.

+
+
+
+

Recommendations and lessons learned

+
    +
  • Convert feedback about lessons and suggestions for improvements into issues +so that these don’t get lost.

  • +
  • Make your lesson citable: get a DOI.

  • +
  • Credit contributors (not only Git commits).

  • +
  • Instructor guide is essential for new instructors.

  • +
  • Lesson changes should be accompanied with instructor guide changes (it’s like +a documentation for the lesson material).

  • +
  • Apply and validate Backwards lesson design again and again.

  • +
  • Make it possible to try out new ideas (by making the lesson branch-able).

  • +
  • Before making larger changes, talk with somebody and discuss these changes.

  • +
  • For substantial changes we recommend to first open an issue and describe your +idea and collect feedback before you start with an extensive rewrite.

  • +
  • For things still under construction, open a draft pull request to collect +feedback and to signal to others what you are working on.

  • +
+
+
+

See also

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/livestreaming/index.html b/branch/community-teaching/livestreaming/index.html new file mode 100644 index 0000000..79dd1dd --- /dev/null +++ b/branch/community-teaching/livestreaming/index.html @@ -0,0 +1,274 @@ + + + + + + + Livestreaming — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Livestreaming

+

In a large lecture, in effect, you don’t interact with most people - +not even close. Yet, trying to force this limited interaction greatly +limits our possible reach, and keeps us in an awkward state of +expecting live interaction yet usually receiving minimal. When we try +this online, it forces a closed

+

Teaching via livestreaming allows us to:

+
    +
  • Reach a near-unlimited number of people

  • +
  • Fully embrace online tools for interaction, instead of asking people +to speak up. This equalizes the participation for shy or passive +participants.

  • +
  • By being large, be more efficient and use the extra resources for +meaningful interactions in small groups.

  • +
+
+

Primary articles

+ +
+
+

Summary

+
    +
  • There are actually three levels here.

    +
      +
    • In-person

    • +
    • Online meeting

    • +
    • Online livestream

    • +
    +
  • +
+
+https://coderefinery.github.io/manuals/_images/mooc-diagram.png +
+

The general presence and information flow within the MOOC strategy.

+
+
+
    +
  • CodeRefinery livestreams via Twitch, but Twitch is not an essential +aspect.

  • +
  • We can invite anyone in the world, no risk of disruptions from +trolls.

  • +
  • This has enabled us to fully embrace strategies such as HackMD and +co-teaching.

    +
      +
    • While we tried these in-person, they didn’t work well since the +loud, extroverted people would dominate.

    • +
    +
  • +
+
+

Tech details

+
    +
  • We stream by using OBS to capture a Zoom meeting. We can switch +between a gallery view, screenshare, and mixed.

  • +
  • Dedicated instructor Zoom meeting - no learners. Thus, no chance of +privacy violations.

    +
      +
    • Learners can attend different ways: a) independently online b) +in-person breakout room c) Zoom breakout rooms.

    • +
    +
  • +
  • We don’t have time to get into details here… see the linked +documents and also join us for in-person experience while we improve +our materials more.

  • +
+
+
+
+

Exercises

+
+

(advanced) Set up and install OBS as a livestreaming tool.

+

This exercise is open-ended.

+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/objects.inv b/branch/community-teaching/objects.inv new file mode 100644 index 0000000..e6a41e7 Binary files /dev/null and b/branch/community-teaching/objects.inv differ diff --git a/branch/community-teaching/other-resources/index.html b/branch/community-teaching/other-resources/index.html new file mode 100644 index 0000000..ffb3dfb --- /dev/null +++ b/branch/community-teaching/other-resources/index.html @@ -0,0 +1,207 @@ + + + + + + + Other resources — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Other resources

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/placeholder/index.html b/branch/community-teaching/placeholder/index.html new file mode 100644 index 0000000..2a483b4 --- /dev/null +++ b/branch/community-teaching/placeholder/index.html @@ -0,0 +1,184 @@ + + + + + + + Placeholder — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/branch/community-teaching/preparation/index.html b/branch/community-teaching/preparation/index.html new file mode 100644 index 0000000..aa2ddaf --- /dev/null +++ b/branch/community-teaching/preparation/index.html @@ -0,0 +1,229 @@ + + + + + + + Pre-workshop preparation — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Pre-workshop preparation

+

These things will help you get the most out of this workshop, by +giving you a broad overview at the beginning that you might only get +later on in the lesson.

+

Don’t worry if you don’t have time to do everything here. The most +important ones are listed first.

+
+

Read “How to help someone use a computer” (5 min)

+

How to help someone use a computer, by Phil +Agre. +Summary: Most of our teaching challenge is helping people to overcome bad user +interface design.

+
+
+

Browse a CodeRefinery lesson (5 min)

+

Please take 5 minutes and go through a CodeRefinery +lesson and understand the general +layout. Don’t go in-depth to any of the material (unless you want, +obviously). We would recommend +git-intro if you don’t +have a preference.

+
+
+

(optional) Watch “The future of teaching” (35 min content only, 45 min with Q&A, or 15 min reading)

+

The “The Future of Teaching” talk is a summary of many things in this +course. You could watch it as a preparation (or if you are reading on +your own, as a summary). This is low priority, since we will cover +most of these things in the course itself. +Watch it on YouTube +or read it if you prefer.

+
+
+

(optional) Read “The science of learning” (20 min)

+

Read this short paper The Science of +Learning +which provides a brief overview of some key evidence-based results in +teaching. This paper is also used by The +Carpentries for their Instructor Training +workshops.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/search/index.html b/branch/community-teaching/search/index.html new file mode 100644 index 0000000..88f4ca6 --- /dev/null +++ b/branch/community-teaching/search/index.html @@ -0,0 +1,196 @@ + + + + + + Search — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2020-, The contributors.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/branch/community-teaching/searchindex.js b/branch/community-teaching/searchindex.js new file mode 100644 index 0000000..a1e5ea9 --- /dev/null +++ b/branch/community-teaching/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"(advanced) Create your own lesson": [[7, "exercise-1"], [13, "exercise-1"]], "(advanced) Set up and install OBS as a livestreaming tool.": [[7, "exercise-0"], [14, "exercise-0"]], "(optional) Read \u201cThe science of learning\u201d (20 min)": [[17, "optional-read-the-science-of-learning-20-min"]], "(optional) Watch \u201cThe future of teaching\u201d (35 min content only, 45 min with Q&A, or 15 min reading)": [[17, "optional-watch-the-future-of-teaching-35-min-content-only-45-min-with-q-a-or-15-min-reading"]], "About the CodeRefinery project and CodeRefinery workshops": [[2, "about-the-coderefinery-project-and-coderefinery-workshops"]], "Adjust your prompt/configuration/colors": [[12, "adjust-your-prompt-configuration-colors"]], "Advantages": [[10, "advantages"], [27, "advantages"]], "Anne Fouilloux": [[0, "exercise-1"], [7, "exercise-1"]], "Aside: Nordic-RSE (research software engineers)": [[8, "aside-nordic-rse-research-software-engineers"]], "Backwards lesson design": [[3, "backwards-lesson-design"], [7, "backwards-lesson-design"]], "Backwards-design a lesson/topic": [[3, "exercise-0"], [7, "exercise-0"]], "Basic concepts": [[22, "basic-concepts"]], "Basic platform: Zoom": [[29, "basic-platform-zoom"]], "Basic preparation": [[29, "basic-preparation"]], "Benefits": [[21, "benefits"]], "Best software practices for whom?": [[2, "callout-2"]], "Biggest open problems": [[8, "biggest-open-problems"]], "Bj\u00f8rn Lindi": [[0, "exercise-2"], [7, "exercise-2"]], "Breakout rooms, bring your own team": [[29, "breakout-rooms-bring-your-own-team"]], "Broadcasting role and setup": [[24, "broadcasting-role-and-setup"]], "Browse a CodeRefinery lesson (5 min)": [[17, "browse-a-coderefinery-lesson-5-min"]], "Carpentries audience": [[2, "carpentries-audience"]], "Carpentries teaching principles": [[1, "carpentries-teaching-principles"]], "Case study: Mega-CodeRefinery and Finland HPC Kickstart": [[29, "case-study-mega-coderefinery-and-finland-hpc-kickstart"]], "Challenges and disadvantages": [[27, "challenges-and-disadvantages"]], "Co-teaching": [[21, null]], "Code of Conduct": [[25, "code-of-conduct"]], "CodeRefinery Curriculum and Reverse Instructional Design (with recommendations for HPC carpentries)": [[1, "coderefinery-curriculum-and-reverse-instructional-design-with-recommendations-for-hpc-carpentries"]], "CodeRefinery audience": [[2, "coderefinery-audience"]], "CodeRefinery lesson tools": [[13, "coderefinery-lesson-tools"]], "CodeRefinery online scaling strategy": [[29, "coderefinery-online-scaling-strategy"]], "CodeRefinery teaching philosophies": [[0, "coderefinery-teaching-philosophies"], [7, "coderefinery-teaching-philosophies"]], "CodeRefinery\u2019s plans": [[8, "coderefinery-s-plans"]], "Cognitive Development and Mental Models": [[1, "cognitive-development-and-mental-models"]], "Collaboration models": [[4, "collaboration-models"], [7, "collaboration-models"]], "Community teaching training": [[11, "community-teaching-training"]], "Competent practitioners": [[2, "callout-1"]], "Conclusion: what are we teaching, then?": [[26, "conclusion-what-are-we-teaching-then"]], "Contribute to a sample lesson": [[7, "exercise-0"], [13, "exercise-0"]], "Deep abstraction layers": [[26, "deep-abstraction-layers"]], "Disadvantages": [[10, "disadvantages"]], "Discussion": [[19, "discussion"], [20, "discussion-1"], [20, "discussion-2"]], "Discussion: Online vs in-person": [[29, "discussion-0"]], "Discussion: how to distribute this?": [[23, null]], "Discussion: what goes into a good shell share or demonstration?": [[20, "discussion-0"]], "Discussion: what makes a video easy to edit?": [[23, null]], "Discussion: what we actually do": [[22, "discussion-what-we-actually-do"]], "Distributed workshop organization": [[5, "distributed-workshop-organization"]], "Diversity and inclusion": [[6, "diversity-and-inclusion"], [7, "diversity-and-inclusion"]], "Editing-1: Get your sample video": [[7, "exercise-0"], [23, "exercise-0"]], "Editing-2: Run Whisper to generate raw subtitles and test video.": [[7, "exercise-1"], [23, "exercise-1"]], "Editing-3: Create the basic editlist.yaml file": [[7, "exercise-2"], [23, "exercise-2"]], "Editing-4: Run ffmpeg-editlist": [[7, "exercise-3"], [23, "exercise-3"]], "Editing-5: Add more features": [[7, "exercise-4"], [23, "exercise-4"]], "Editing-6: Subtitles": [[7, "exercise-5"], [7, "exercise-6"], [23, "exercise-5"], [23, "exercise-6"]], "Editing-7: Generate the final output file.": [[7, "exercise-7"], [23, "exercise-7"]], "Evaluate screen captures": [[7, "exercise-0"], [12, "exercise-0"]], "Example: designing an HPC Carpentry lesson": [[3, "discussion-0"]], "Exercise": [[7, "exercise-0"], [7, "exercise-0"], [7, "exercise-0"], [7, "exercise-0"], [7, "exercise-0"], [7, "exercise-1"], [7, "exercise-2"], [10, "exercise"], [10, "exercise-0"], [18, "exercise-0"], [19, "exercise-0"], [19, "exercise-1"], [19, "exercise-2"], [21, "exercise-0"], [26, "exercise-0"]], "Exercise A": [[23, "exercise-a"]], "Exercise B": [[23, "exercise-b"]], "Exercise list": [[7, "exercise-list"]], "Exercise: How to identify learner profiles?": [[1, "exercise-1"], [7, "exercise-1"]], "Exercises": [[3, "exercises"], [4, "exercises"], [6, "exercises"], [12, "exercises"], [13, "exercises"], [14, "exercises"], [21, "exercises"], [22, "exercises"], [23, "exercises"], [27, "exercises"], [28, "exercises"]], "Formative assessment": [[1, "callout-2"]], "General workshop arrangements": [[29, "general-workshop-arrangements"]], "Getting/giving feedback on learners\u2019 progress": [[1, "getting-giving-feedback-on-learners-progress"]], "Getting/giving feedback on teaching": [[1, "getting-giving-feedback-on-teaching"]], "Give feedback on teaching (optional, 10 mn)": [[1, "exercise-0"], [7, "exercise-0"]], "Giving confidence": [[25, "giving-confidence"]], "Goals for this instructor training": [[25, "discussion-1"]], "Goals for this workshop": [[25, "goals-for-this-workshop"]], "HackMD": [[7, "hackmd"], [10, "hackmd"], [29, "hackmd"]], "HackMD prototype": [[20, "output-0"]], "Helper training": [[29, "helper-training"]], "History": [[2, "discussion-0"]], "How many people teach in your workshops?": [[7, "exercise-0"], [28, "exercise-0"]], "How to help someone use a computer, by Phil Agre": [[26, null]], "How to teach online": [[20, "how-to-teach-online"]], "How you can join": [[8, "how-you-can-join"]], "How \u201cknowledge\u201d gets in the way": [[1, "how-knowledge-gets-in-the-way"]], "Ice-breaker in groups (20 minutes)": [[0, "exercise-0"], [7, "exercise-0"]], "Impact": [[2, "impact"]], "In-person": [[22, "in-person"]], "Initial reading": [[26, "initial-reading"]], "Installation time": [[29, "installation-time"]], "Instructor demo": [[19, "instructor-demo"]], "Instructor tech setup": [[7, "instructor-tech-setup"], [12, "instructor-tech-setup"]], "Instructor\u2019s guide": [[9, "instructor-s-guide"]], "Interactive teaching style": [[1, "interactive-teaching-style"], [7, "interactive-teaching-style"]], "Introduction": [[11, null]], "It is easier to join and follow than to start or lead": [[5, "it-is-easier-to-join-and-follow-than-to-start-or-lead"]], "Jo\u00e3o M. da Silva": [[0, "exercise-9"], [7, "exercise-9"]], "Juho Lehtonen": [[0, "exercise-7"], [7, "exercise-7"]], "Key principles": [[1, "key-principles"]], "Keypoints": [[2, "keypoints-0"], [5, "keypoints-0"], [8, "keypoints-0"], [8, "keypoints-1"], [12, "keypoints-0"], [24, "keypoints-0"]], "Lesson design and development": [[11, null]], "Lesson development with version control": [[7, "lesson-development-with-version-control"], [13, "lesson-development-with-version-control"]], "Lessons learned from organizing larger workshops": [[5, "discussion-0"]], "List successes and failures in collaborative teaching": [[4, "exercise-0"], [7, "exercise-0"]], "Livestreaming": [[7, "livestreaming"], [14, "livestreaming"]], "Main goals": [[2, "main-goals"]], "Main room discussion": [[19, "discussion-0"]], "Manuals link": [[29, "callout-1"]], "Meta-talk": [[20, "meta-talk"]], "Model: CodeRefinery": [[4, "model-coderefinery"]], "Model: Python for Scientific Computing": [[4, "model-python-for-scientific-computing"]], "More examples and how to set it up": [[12, "more-examples-and-how-to-set-it-up"]], "Novices": [[2, "callout-0"]], "Novices, competent practitioners and experts": [[1, "novices-competent-practitioners-and-experts"]], "Objectives": [[20, "objectives-0"]], "Old contents - we need to move/merge": [[11, null]], "On the importance of feedback": [[1, "on-the-importance-of-feedback"]], "Online": [[22, "online"]], "Online teaching discussion": [[29, "online-teaching-discussion"]], "Optional: feedback for two live-coding examples": [[19, "optional-feedback-for-two-live-coding-examples"]], "Other notes": [[29, "other-notes"]], "Other resources": [[15, "other-resources"]], "Placeholder": [[16, "placeholder"]], "Possibilities for Carpentries": [[8, "possibilities-for-carpentries"]], "Pre-workshop preparation": [[17, "pre-workshop-preparation"]], "Preparation": [[11, null]], "Primary article": [[21, "primary-article"]], "Primary articles": [[6, "primary-articles"], [10, "primary-articles"], [14, "primary-articles"], [22, "primary-articles"], [23, "primary-articles"], [28, "primary-articles"]], "Privacy is more important than any other factor": [[24, "privacy-is-more-important-than-any-other-factor"]], "Questions": [[20, "questions"]], "Radovan Bast": [[0, "exercise-5"], [7, "exercise-5"]], "Read \u201cHow to help someone use a computer\u201d (5 min)": [[17, "read-how-to-help-someone-use-a-computer-5-min"]], "Recommendations and lessons learned": [[13, "recommendations-and-lessons-learned"]], "Recommendations for co-teaching": [[4, "exercise-1"], [7, "exercise-1"]], "Recording and streaming": [[29, "recording-and-streaming"]], "Reference": [[11, null]], "Reflect on how your job can be defined to promote diversity.": [[6, "exercise-0"], [7, "exercise-0"]], "Revisiting Learning objectives": [[1, "revisiting-learning-objectives"]], "Richard Darst": [[0, "exercise-8"], [7, "exercise-8"]], "Running a workshop: online": [[29, "running-a-workshop-online"]], "Sabry Razick": [[0, "exercise-6"], [7, "exercise-6"]], "Screen sharing": [[20, "screen-sharing"]], "Screenshare": [[12, "screenshare"]], "See also": [[6, "see-also"], [13, "see-also"], [18, "see-also"], [20, "see-also"], [21, "see-also"], [23, "see-also"], [26, "see-also"], [27, "see-also"], [28, "see-also"]], "Set up your own environment": [[7, "exercise-1"], [12, "exercise-1"]], "Share the history of your commands": [[12, "share-the-history-of-your-commands"]], "Shell sharing": [[20, "shell-sharing"]], "Should instructors be forced to have a consistent screenshare?": [[12, "discussion-0"]], "Social-technical considerations": [[11, null]], "Solution": [[1, "solution-0"], [7, "solution-0"], [7, "solution-1"], [7, "solution-2"], [7, "solution-3"], [7, "solution-4"], [7, "solution-5"], [7, "solution-0"], [23, "solution-0"], [23, "solution-1"], [23, "solution-2"], [23, "solution-3"], [23, "solution-4"], [23, "solution-5"]], "Staff roles": [[29, "staff-roles"]], "Stefan Negru": [[0, "exercise-4"], [7, "exercise-4"]], "Strategies": [[21, "strategies"]], "Summary": [[14, "summary"], [23, "summary"], [28, "summary"]], "Summative Assessment": [[1, "callout-1"]], "Support services vs diversity": [[6, "support-services-vs-diversity"]], "Target audience": [[2, "target-audience"]], "Teach teaching": [[20, "teach-teaching"]], "Teaching demos part 1": [[19, "teaching-demos-part-1"]], "Teaching demos, part 2": [[19, "teaching-demos-part-2"]], "Teaching online": [[7, "teaching-online"], [18, "teaching-online"]], "Teaching practice": [[20, "teaching-practice"]], "Teaching practice and feedback": [[7, "teaching-practice-and-feedback"], [19, "teaching-practice-and-feedback"]], "Teaching tools": [[11, null]], "Team teaching": [[7, "team-teaching"], [21, "team-teaching"]], "Teams": [[7, "teams"], [7, "exercise-0"], [22, "teams"], [22, "exercise-0"]], "Tech details": [[14, "tech-details"]], "The Carpentries and CodeRefinery approaches to teaching": [[1, "the-carpentries-and-coderefinery-approaches-to-teaching"]], "The approach": [[3, "the-approach"]], "The process": [[3, "the-process"]], "This material": [[1, "callout-0"]], "Thor Wikfeldt": [[0, "exercise-3"], [7, "exercise-3"]], "Tools for this workshop": [[25, "tools-for-this-workshop"]], "Under development (mid 2022)": [[11, null]], "Usability": [[26, "usability"]], "Use ffmpeg-editlist to edit this sample video": [[7, "exercise-8"], [23, "exercise-8"]], "Using Bloom\u2019s Taxonomy to write effective learning objectives": [[1, "using-bloom-s-taxonomy-to-write-effective-learning-objectives"]], "Version control and static site generators": [[13, "version-control-and-static-site-generators"]], "Video editing": [[7, "video-editing"], [23, "video-editing"]], "Video recording": [[24, "video-recording"]], "Video recordings": [[0, "prerequisites-0"]], "Ways to teach together": [[27, "ways-to-teach-together"]], "We try to release videos on the same day": [[24, "we-try-to-release-videos-on-the-same-day"]], "Welcome and introduction": [[25, "welcome-and-introduction"]], "What are the top issues new instructors face?": [[1, "what-are-the-top-issues-new-instructors-face"]], "What do we want to get out of this workshop": [[25, "discussion-0"]], "What similarities do we have?": [[7, "exercise-0"], [27, "exercise-0"]], "What this course covers": [[11, "what-this-course-covers"]], "Who are the learners": [[1, "who-are-the-learners"]], "Who is the course for?": [[11, "who-is-the-course-for"]], "Why are computers hard?": [[7, "why-are-computers-hard"], [26, "why-are-computers-hard"]], "Why teach together?": [[7, "why-teach-together"], [27, "why-teach-together"]], "Why teaching mechanics matter": [[20, "why-teaching-mechanics-matter"]], "Working with learning objectives": [[1, "working-with-learning-objectives"]], "Workshop collaborations": [[29, "workshop-collaborations"]], "Workshop manuals": [[29, "callout-0"]], "Workshop organization": [[11, null]], "Workshop roles": [[7, "workshop-roles"], [28, "workshop-roles"]], "Wrap-up, future, and getting involved": [[11, null]]}, "docnames": ["02-teaching-philosophies", "03-teaching-style", "about-coderefinery", "backward-lesson-design", "collaboration-models", "distributed", "diversity-and-inclusion", "exercises", "future", "guide", "hackmd", "index", "instructor-tech-setup", "lessons-with-version-control", "livestreaming", "other-resources", "placeholder", "preparation", "teaching-online", "teaching-practice", "teaching-strategies", "team-teaching", "teams", "video-editing", "video-recording", "welcome", "why-are-computers-hard", "why-teach-together", "workshop-roles", "workshops-online"], "envversion": {"sphinx": 61, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["02-teaching-philosophies.md", "03-teaching-style.md", "about-coderefinery.md", "backward-lesson-design.md", "collaboration-models.rst", "distributed.md", "diversity-and-inclusion.rst", "exercises.rst", "future.md", "guide.rst", "hackmd.rst", "index.rst", "instructor-tech-setup.md", "lessons-with-version-control.md", "livestreaming.rst", "other-resources.md", "placeholder.rst", "preparation.md", "teaching-online.md", "teaching-practice.md", "teaching-strategies.md", "team-teaching.rst", "teams.rst", "video-editing.rst", "video-recording.md", "welcome.md", "why-are-computers-hard.rst", "why-teach-together.rst", "workshop-roles.rst", "workshops-online.md"], "indexentries": {}, "objects": {}, "objnames": {}, "objtypes": {}, "terms": {"": [0, 3, 7, 11, 13, 18, 19, 20, 21, 23, 25, 26, 27, 29], "00": [7, 23], "02": 7, "03": [4, 7, 10, 23], "04": [7, 23], "05": [7, 23], "07": [7, 23], "1": [21, 27], "10": [2, 12, 23, 29], "100": 29, "11": [7, 23], "12": [7, 23], "14": 29, "15": [1, 7, 15, 23], "16": [7, 23], "180": [0, 7, 29], "19": [4, 27], "1st": 3, "1vqkzomfi5sfnx69d4qrq_3n": 6, "2": 1, "20": [23, 29], "2014": 2, "2015": 2, "2016": 2, "2019": 11, "2020": [11, 29], "2021": 4, "2022": [2, 4, 8, 10], "2023": [7, 23], "2025": 2, "22": [4, 10], "24": [7, 23], "25": [7, 23], "250": 29, "2d": 10, "2pacx": 6, "2x2": [1, 7], "3": [2, 10, 21, 29], "31": [7, 23], "35": [7, 15, 23], "37": [7, 23], "4": [1, 19], "40": [4, 29], "43": [7, 23], "45": [0, 7, 15, 23], "4965": 26, "5": [1, 19, 20, 21, 22, 29], "50": [7, 19, 23], "6": [2, 3, 29], "7nhx": 0, "90": [3, 29], "A": [0, 1, 2, 3, 4, 5, 7, 10, 13, 15, 20, 22], "And": [0, 7, 20, 23, 25], "As": [1, 3, 7, 11, 18, 26, 28], "At": [0, 7], "Be": [7, 23, 25, 29], "But": [0, 1, 7, 10, 20, 22, 25, 27], "By": [2, 14, 23, 24], "For": [0, 1, 3, 7, 9, 13, 18, 22, 23, 24, 25], "If": [0, 4, 5, 7, 11, 13, 20, 23, 24, 25, 27], "In": [0, 1, 2, 3, 5, 7, 9, 11, 14, 18, 19, 20, 21, 24, 29], "It": [0, 1, 2, 3, 7, 10, 13, 19, 20, 23, 25, 27, 29], "No": 23, "Not": [1, 7, 10], "Of": [0, 7, 26], "One": [1, 2, 5, 20, 21, 22], "Or": [1, 6, 7], "That": [0, 1, 7], "The": [0, 2, 7, 10, 11, 13, 14, 15, 18, 19, 20, 21, 22, 23, 25, 26, 29], "Then": [1, 3, 7, 29], "There": [0, 1, 7, 12, 14, 20, 23], "These": [1, 2, 17, 23], "To": [1, 23, 29], "With": [0, 7, 20], "_cobn": 23, "aalto": [4, 7, 23, 29], "aaltoscicomp": [4, 7, 23], "abil": [0, 6, 7, 26], "abl": [0, 1, 3, 7, 11, 13, 21, 23, 26, 29], "about": [0, 1, 3, 7, 10, 11, 13, 15, 20, 23, 24, 25, 27, 29], "abov": [7, 10, 23, 26, 29], "abstract": 7, "academ": [0, 2, 7], "acceler": 1, "accept": [1, 2, 29], "access": [3, 6, 10, 11, 29], "accid": [23, 24], "accommod": 1, "accompani": 13, "accomplish": [1, 7, 20], "account": [0, 7, 19], "accur": [1, 23], "achiev": [0, 1, 7], "acquir": 1, "acquisit": [1, 3], "across": 29, "act": 21, "action": [8, 13], "activ": [1, 2, 3, 7, 10, 21], "actual": [2, 7, 13, 14, 23, 29], "adapt": [0, 1, 7, 11, 26], "add": [1, 12, 24, 27], "addit": [0, 1, 3, 5, 7], "address": [1, 2], "adjust": [7, 22, 23], "adopt": [2, 11], "advanc": [0, 1, 12, 20], "advantag": [7, 12, 18, 20, 29], "advertis": [8, 28, 29], "advoc": 23, "affect": [1, 25], "after": [0, 1, 2, 4, 7, 8, 10, 22, 23, 24], "afterward": 24, "again": [11, 13], "agil": [0, 7], "ago": [0, 2, 3, 7], "agr": [15, 17], "agre": [1, 7], "aha": [0, 7], "ahead": 1, "aim": [1, 2, 7], "aka": 22, "align": [7, 23], "all": [0, 1, 2, 3, 5, 7, 12, 18, 19, 22, 23, 24, 29], "allow": [0, 1, 3, 7, 13, 14, 20, 22, 23, 29], "almost": [0, 3, 7, 11, 12, 20, 22, 26], "alon": [0, 7, 11, 22, 25, 27], "along": [0, 1, 3, 7, 19, 20, 22, 23, 28], "alreadi": [1, 2, 3, 4, 7], "also": [0, 1, 2, 4, 5, 7, 8, 11, 14, 17, 19, 24, 25, 29], "altern": [7, 13], "alwai": [0, 3, 7, 20, 24, 28], "am": [0, 3, 7], "among": [1, 6, 7, 12, 27, 28], "amount": [1, 3, 4, 11, 28], "an": [0, 1, 2, 4, 5, 7, 8, 9, 12, 13, 14, 18, 21, 23, 24, 29], "analogi": [0, 1, 7], "analyz": 3, "ani": [0, 1, 2, 3, 4, 7, 8, 13, 17, 20, 21, 23, 25, 29], "announc": [4, 29], "anonym": [10, 20, 29], "anoth": [0, 3, 5, 7, 10, 12, 21], "answer": [0, 2, 3, 7, 10, 20, 21, 25, 27, 29], "anticip": 1, "anymor": [0, 7, 29], "anyon": [0, 1, 4, 7, 14, 23], "anyth": [20, 23, 24], "anywai": [7, 21, 27, 29], "appear": [0, 7, 23, 24, 29], "appli": [0, 1, 2, 3, 7, 8, 13, 20, 23, 25], "appreci": [0, 7], "approach": [0, 2, 4, 7, 11], "appropri": 3, "ar": [0, 2, 3, 5, 6, 8, 10, 11, 12, 13, 14, 15, 17, 20, 21, 22, 23, 24, 25, 27, 28, 29], "architectur": [0, 7], "archiv": 29, "area": 23, "aren": [1, 7, 11, 23, 27], "aris": 3, "around": [1, 4, 8, 29], "arrang": 22, "art": [7, 19], "articul": [1, 2], "asc": [4, 23], "ask": [0, 1, 2, 3, 7, 14, 19, 20, 21, 25, 29], "asoci": 6, "aspect": [0, 2, 3, 7, 14, 19], "assess": [3, 21], "assign": [1, 22, 29], "assum": [0, 1, 2, 7, 20, 26], "attempt": 4, "attend": [2, 3, 7, 14, 23, 24, 25, 28, 29], "attende": [0, 7, 22], "attent": [0, 7, 10], "attitud": [0, 7], "audienc": [0, 1, 3, 5, 7, 10, 12, 21, 23, 24, 26, 27, 29], "audio": [23, 24], "autom": 1, "automat": 7, "autumn": 11, "avail": [3, 4, 7, 20, 23, 25, 29], "averag": [1, 4], "avoid": [0, 2, 3, 7, 9, 19, 27, 29], "awar": 2, "awkward": 14, "ax": [1, 7], "b": 14, "back": [0, 1, 7, 10, 13, 23, 24, 29], "background": [0, 3, 6, 7, 9], "backward": [11, 13], "bad": [15, 17, 19, 20, 26, 29], "balanc": [7, 10], "bank": 25, "barrier": [11, 27], "base": [0, 1, 2, 3, 7, 13, 15, 17, 20, 22, 23], "bash": 1, "basic": [0, 3, 10, 20], "beauti": 12, "becaus": [0, 1, 2, 3, 7, 23, 29], "becom": [0, 1, 2, 3, 7, 8, 11, 20, 23], "been": [0, 1, 3, 7, 11, 21, 23, 29], "befor": [0, 1, 4, 7, 11, 12, 13, 23, 28, 29], "begin": [0, 7, 10, 17, 23], "behind": [0, 7], "being": [0, 7, 10, 14, 22], "beings": 1, "belief": 1, "believ": [0, 1, 7, 18], "below": [0, 1, 24, 29], "benefici": 0, "benefit": [1, 5, 7, 20, 25, 27, 29], "benner": 1, "best": [0, 1, 3, 7, 11, 12, 22, 25, 27], "better": [0, 2, 3, 7, 8, 18, 19, 20, 21], "between": [0, 1, 3, 6, 7, 14, 20, 21, 29], "beyond": 2, "bi": [1, 8], "bias": 3, "big": [0, 7], "binari": [0, 7], "bit": [0, 1, 3, 7, 13, 22, 29], "black": [7, 23], "blank": [0, 7], "blob": [0, 7], "block": [0, 7, 23], "board": 27, "book": [1, 3, 15, 24], "bore": [0, 7], "borrow": 1, "both": [0, 1, 7, 19, 20, 27, 28], "bottom": [1, 7, 21], "box": 3, "brainstorm": [3, 7, 18], "branch": 13, "break": [0, 1, 7, 20, 23, 25, 29], "breakout": [1, 4, 5, 7, 8, 14, 19, 22, 23, 24, 28], "breath": 1, "brief": [15, 17, 23], "bring": [0, 1, 7, 20, 22], "british": 1, "broad": 17, "broadcast": [14, 28], "broaden": [0, 7], "broadli": 1, "broken": 1, "brows": [7, 13], "browser": [0, 7, 12], "build": [1, 2, 13, 25], "built": [1, 26], "bullet": [0, 7], "busi": [0, 7], "c": [14, 27], "call": [0, 1, 7, 10, 20], "came": [4, 19], "can": [0, 1, 2, 3, 4, 5, 9, 10, 11, 12, 13, 14, 19, 20, 21, 22, 23, 24, 25, 27, 29], "cannot": [1, 3], "capabl": [0, 3, 7, 22], "capentri": 1, "capit": 1, "captur": 14, "car": 1, "care": [0, 7, 11, 27], "carefulli": 1, "carpentri": [0, 6, 7, 11, 13, 15, 17], "carpentrycon": 11, "case": [0, 1, 3, 7, 24], "catch": [12, 20, 23, 24], "categori": 1, "center": 1, "central": 24, "centric": [0, 7], "certain": [0, 7, 29], "challeng": [0, 1, 7, 15, 17, 21], "chanc": 14, "chang": [0, 1, 7, 13, 19, 27], "chapter": [7, 23], "chat": [8, 10, 20, 21, 28, 29], "check": [0, 1, 3, 7, 13, 19, 23], "choic": [1, 7, 13, 19, 23], "choos": [1, 3, 7, 21], "chunk": 23, "circumst": [1, 11], "citabl": 13, "citi": 1, "clarif": 1, "clarifi": 3, "class": [0, 1, 7, 12, 20], "classroom": [0, 1, 7, 21, 25], "cleanli": 23, "clear": [0, 3, 7, 20, 23, 29], "clearli": [0, 1, 2, 7, 20, 23, 29], "climat": [1, 3], "close": [7, 14, 19, 20], "closer": 11, "cluster": [1, 3], "cmp": 24, "co": [0, 5, 8, 10, 11, 14, 27, 28], "code": [0, 1, 2, 3, 7, 23], "coderefineri": [3, 10, 11, 12, 14, 15, 18, 20, 21, 22, 23, 24, 25, 28], "cognit": [0, 7], "collabor": [2, 5, 8, 10, 11, 12, 13, 18, 19, 20, 25, 27], "colleagu": [2, 3, 4, 7, 29], "collect": [1, 2, 7, 13, 20, 23, 25], "columbia": 1, "com": [0, 6, 7, 13, 23, 29], "combin": [0, 4, 7, 27, 29], "come": [0, 1, 3, 7, 20, 22, 23, 24, 29], "comfort": 10, "command": [3, 7, 23], "comment": [20, 25], "commentari": 20, "commit": 13, "common": [2, 7, 10, 13, 21, 28], "commun": [0, 2, 3, 7, 13, 25, 27, 28, 29], "compar": [1, 4, 10, 12, 20, 29], "compens": [0, 7, 18], "compet": [0, 7], "compil": 13, "complement": [0, 7, 21], "complet": [1, 2, 25], "complex": [1, 3], "complic": [0, 7], "complier": 13, "compon": [0, 7], "comprehens": 11, "compress": 3, "compromis": [0, 7], "comput": [0, 1, 2, 3, 6, 11, 15, 23, 29], "con": 12, "concept": [0, 1, 7, 10, 20, 21], "conceptu": 2, "concern": 1, "conclus": [7, 19], "concret": 3, "condens": 29, "condition_on_previous_text": [7, 23], "conduct": 1, "conf": [7, 13], "confid": [0, 1, 2, 7], "configur": [1, 6, 7], "confus": [0, 7, 25], "connect": [0, 1, 6, 7], "consciou": [0, 7], "consequ": 3, "consid": [0, 7, 13, 22], "consider": [0, 7], "constitut": 1, "constrict": 20, "construct": [7, 13, 19], "contain": [7, 23, 29], "content": [1, 4, 7, 13, 15, 23, 29], "context": [0, 1, 3, 6, 7], "continu": [1, 8, 11, 29], "contradict": 1, "contrast": [1, 29], "contribut": 9, "contributor": [2, 8, 13], "control": [2, 11, 25], "convei": [0, 7], "convers": [0, 7], "convert": 13, "convinc": 2, "convolut": [0, 7], "cool": 3, "coordin": [5, 12, 20, 22, 27, 28, 29], "copi": [0, 3, 7, 20, 23], "core": 3, "correct": [0, 1, 7], "correctli": 1, "cost": [5, 13, 24], "could": [0, 1, 4, 7, 10, 11, 13, 17, 22, 23, 24], "countri": [1, 2, 5, 29], "cours": [0, 1, 2, 3, 4, 5, 7, 9, 10, 14, 17, 18, 20, 21, 22, 23, 24, 27, 29], "cover": [7, 17], "covid": [4, 27], "cpu": 3, "crash": 14, "creat": [0, 1, 3, 22, 24], "creation": 1, "creativ": [0, 7], "credit": [1, 8, 13], "critic": [3, 6, 26], "crowd": 22, "crowdsourc": 23, "cuda": [7, 23], "curios": [0, 7], "current": [1, 3, 7, 8, 11, 13, 23, 27], "curriculum": 15, "cursor": 23, "custom": [0, 7, 13, 29], "cut": [1, 7, 23], "d": [0, 6, 7], "dai": [1, 7, 12, 22, 23, 27, 28, 29], "daili": 1, "darst": 6, "darstr1": [7, 23], "data": [3, 7, 23, 27], "dataset": 3, "date": 4, "day1": [7, 23], "dead": [7, 23], "deal": 22, "decid": [1, 4], "decreas": [7, 10], "dedic": [14, 29], "deepli": 1, "defin": [2, 3, 5, 23, 29], "definit": [3, 7, 23], "degre": [0, 7, 11], "deleg": 22, "deliber": 10, "deliv": [1, 5, 7], "demo": [0, 1, 7, 20, 21, 23], "demograph": [1, 6], "demonstr": [7, 19, 23, 29], "demotiv": 6, "demystifi": [0, 7], "depend": [1, 7, 12, 23], "depth": [1, 17], "deriv": [1, 2], "describ": [0, 1, 3, 7, 13], "descript": [7, 10, 14, 22, 23, 24], "design": [2, 8, 13, 15, 17, 19, 29], "desir": [7, 23], "desktop": 3, "despit": 27, "detail": 1, "detect": [0, 7], "determin": [1, 26], "detour": [0, 7], "develop": [0, 2, 3, 5, 9, 15, 27], "deviat": [0, 7], "devic": [7, 23], "diagram": [0, 7], "did": [0, 1, 7, 29], "didn": [7, 14, 23, 29], "differ": [0, 1, 2, 3, 5, 6, 7, 10, 11, 12, 13, 14, 19, 20, 21, 22, 24, 28, 29], "difficult": [0, 1, 7, 24], "difficulti": [2, 20, 22, 26, 27], "direct": [1, 2], "directli": [1, 7, 8, 18, 23, 24, 29], "director": 28, "directori": [1, 7, 23], "disadvantag": [7, 18, 20, 22, 29], "disagre": [1, 7], "disciplin": 2, "disclaim": [23, 24], "discret": [1, 2], "discuss": [0, 1, 3, 7, 12, 13, 18], "displai": 20, "disproportion": 25, "disrupt": 14, "distil": [0, 7], "distinct": [1, 3], "distinguish": 1, "distract": [12, 20], "distribut": [3, 7, 11, 19], "divers": [3, 11, 25, 29], "divid": [7, 21], "divis": 21, "do": [0, 1, 2, 3, 5, 10, 11, 12, 17, 20, 21, 23, 24, 26, 29], "doc": [1, 6, 7], "document": [0, 2, 3, 7, 10, 12, 13, 14, 15, 19, 24, 29], "doe": [1, 2, 7, 10, 12, 21, 29], "doesn": [1, 7, 10, 13, 20, 22, 29], "doi": 13, "domain": [0, 1, 7], "domin": 14, "don": [0, 1, 3, 7, 13, 14, 17, 20, 21, 22, 23, 24, 25, 27, 29], "done": [0, 1, 7, 22, 23, 27], "down": [0, 1, 7, 19, 20], "download": [7, 23], "draft": 13, "draw": [0, 7], "dreyfu": 1, "drive": 1, "driven": 3, "driver": 1, "drop": 22, "dual": 29, "due": 3, "dump": 18, "duplic": [1, 7, 11, 27], "dure": [0, 1, 3, 4, 5, 6, 7, 10, 19, 21, 22, 28, 29], "duti": 5, "dynam": [0, 3, 7], "e": [0, 1, 2, 6, 7, 23], "each": [0, 1, 3, 4, 5, 7, 11, 12, 18, 19, 20, 21, 22, 23, 25, 26, 28, 29], "earlier": 3, "easi": [0, 7, 12, 20, 24, 26, 29], "easier": [2, 10, 12, 20, 24, 27], "easiest": 1, "easili": [0, 1, 5, 7], "ecologist": 3, "economi": 1, "ecosystem": 13, "edit": [11, 24, 28, 29], "editor": [7, 23, 28], "educ": [1, 3, 21], "effect": [2, 14, 20, 21], "effici": 14, "effort": [0, 1, 4, 7, 11, 24, 27], "either": [1, 3, 8, 11, 21, 22], "elabor": 18, "element": 3, "els": [0, 7, 12, 22, 23, 26, 29], "email": 29, "embrac": [0, 2, 7, 14], "emphas": [3, 29], "emphazis": 27, "en": [7, 23], "enabl": 14, "encod": [7, 23], "encourag": [0, 1, 7, 22], "end": [0, 1, 3, 7, 14, 20, 23], "engag": [0, 3, 7, 8, 10, 27], "engin": [1, 2, 13], "enough": [1, 3, 20, 22, 23, 25, 29], "ensur": 22, "entir": [0, 1, 6, 7, 12], "environ": [1, 23, 25, 26], "episod": [0, 1, 3, 7, 20, 23, 29], "equal": [6, 7, 14, 23], "equat": 3, "equiti": 6, "error": [0, 1, 7, 12], "especi": [0, 1, 3, 7, 13, 23, 24, 25], "essenc": [0, 7], "essenti": [0, 1, 7, 13, 14], "establish": [0, 1, 2, 7], "etc": [2, 3, 9, 12, 23, 28, 29], "etherpad": [1, 7], "ethic": 29, "evalu": [3, 19], "even": [0, 1, 3, 4, 7, 12, 14, 18, 21, 23], "event": [1, 7, 22, 24, 27], "eventu": 27, "ever": 1, "everi": [1, 12, 29], "everybodi": [0, 1, 7, 25], "everydai": 1, "everyon": [1, 4, 7, 11, 22, 23], "everyth": [0, 1, 4, 7, 17, 20, 23, 25, 29], "evid": [1, 15, 17], "exact": 13, "exam": 1, "exampl": [0, 1, 2, 7, 9, 10, 11, 20, 23, 25], "excerpt": [7, 23], "excit": 3, "execut": 1, "exercis": [0, 2, 5, 8, 11, 20, 29], "exist": [1, 3, 5, 7], "expect": [1, 3, 7, 14, 20, 21, 23, 24, 26, 29], "experi": [0, 1, 2, 3, 4, 5, 7, 12, 14, 20, 29], "experienc": [0, 3, 4, 7], "expert": [0, 5, 7, 28, 29], "explain": [0, 1, 2, 3, 7, 20], "explicit": [0, 7, 22], "explicitli": 22, "expos": 3, "express": [3, 7], "extens": [3, 12, 13, 21, 27], "extern": [7, 23], "extra": [14, 27, 29], "extrovert": 14, "ey": 28, "face": [0, 7], "facilit": [1, 7], "fact": [0, 1, 3, 7, 22], "factor": [11, 23], "factual": 1, "fail": [1, 12, 29], "fair": 27, "fall": [1, 7, 19], "fals": [7, 23], "familiar": [0, 3, 7, 29], "fanci": 1, "far": [3, 27], "farther": 11, "fashion": [0, 7], "fast": [0, 1, 7, 23, 27, 29], "faster": [0, 7, 20, 29], "fault": 26, "favor": 2, "favorit": [3, 7], "featur": 29, "februari": 2, "feedback": [0, 2, 11, 12, 13, 20, 21, 29], "feel": [0, 1, 7, 10, 19], "felt": [0, 7], "few": [0, 1, 3, 5, 7, 12, 19, 20, 23, 24], "fi": [4, 7, 23], "field": [3, 22, 29], "figur": [1, 3, 7, 29], "file": [1, 3, 13], "filesystem": 3, "fill": [6, 26], "find": [0, 7, 10, 12, 23, 27, 29], "finish": [0, 7], "finit": 3, "firmli": 1, "first": [1, 3, 4, 7, 8, 13, 17, 23, 29], "firstnam": 29, "fit": 1, "five": [20, 29], "fix": [7, 23], "flaw": 18, "flood": 10, "flow": [0, 7, 14, 20, 28], "flowchat": 23, "fluid": 3, "focu": [0, 1, 7, 8, 10, 20, 21], "focus": [15, 20, 29], "follow": [0, 1, 3, 7, 12, 13, 19, 20, 22, 23, 25, 26], "font": [12, 20, 25], "forc": [0, 7, 14], "forget": [20, 23], "forgotten": 26, "form": [2, 3, 13, 22, 25], "formal": 1, "format": [2, 4, 7, 13, 19, 25, 28], "former": 29, "found": 1, "four": [0, 7, 23], "frame": [7, 23], "framework": 1, "free": 2, "freeli": 25, "frequent": 1, "friend": [0, 7], "from": [0, 1, 2, 3, 4, 6, 7, 11, 12, 14, 15, 20, 22, 23, 24, 25, 27, 29], "frustrat": 11, "full": [7, 10, 23], "fullhd": 12, "fulli": [1, 14], "fun": [0, 7, 29], "function": [7, 13], "fund": [2, 8], "fundament": 1, "further": [1, 9], "futur": [0, 1, 2, 7, 15, 23], "g": [0, 7, 23], "galleri": [14, 29], "gap": 3, "garbl": [7, 23], "gave": [25, 27], "gcjexwc8cf": 0, "gener": [2, 5, 8, 12, 14, 15, 17, 21, 25], "get": [0, 2, 3, 12, 13, 14, 17, 19, 20, 22, 24, 27, 29], "git": [2, 9, 13, 17], "github": [4, 7, 10, 12, 13, 14, 18, 21, 22, 23, 24, 28, 29], "give": [0, 2, 3, 8, 17, 19, 20, 21, 29], "given": [0, 1, 2, 5, 7], "global": 3, "go": [0, 1, 3, 7, 10, 17, 20, 23, 25, 29], "goal": [0, 3, 7, 19], "goe": 1, "gone": 1, "good": [0, 1, 2, 6, 7, 8, 12, 19, 21, 23, 24, 26, 29], "googl": [1, 6, 7], "got": [0, 7, 11, 25], "gpu": 3, "grad": 2, "grade": 1, "gradual": [0, 7, 15], "great": [0, 4, 5, 7, 20, 21, 24, 25], "greatli": [14, 29], "grew": 2, "grid": [1, 7], "gritti": [0, 7], "gromac": 3, "ground": [0, 7, 28], "group": [1, 3, 6, 11, 14, 19, 20, 21, 22, 25], "grow": [1, 13], "growth": 1, "guarante": [23, 24, 29], "guesswork": 1, "guid": [0, 1, 7, 11, 13, 20, 21, 25, 28, 29], "h": 29, "ha": [0, 1, 2, 3, 7, 11, 14, 20, 21, 29], "hackmd": [1, 4, 11, 13, 14, 18, 21, 23, 25, 27, 28], "had": [0, 2, 3, 7, 29], "half": [12, 20], "hand": [0, 2, 7, 11, 25, 29], "handbook": 15, "handl": [1, 29], "handwrit": [0, 7], "happen": [1, 3, 4, 5, 22, 23, 24], "hard": [0, 1, 6, 11, 23], "harder": [20, 22, 29], "hardest": 1, "hardli": 1, "have": [0, 1, 2, 3, 4, 5, 8, 10, 13, 14, 17, 19, 20, 21, 22, 23, 25, 28, 29], "haven": 29, "he": [1, 3], "head": [0, 7], "headless": 1, "heard": 1, "heavili": 27, "help": [0, 1, 3, 4, 5, 6, 7, 8, 10, 15, 22, 23, 24, 25, 27, 29], "helper": [0, 5, 7, 8, 10, 15, 20, 22, 25, 27, 28], "henc": [0, 7], "her": [1, 3], "here": [0, 1, 7, 10, 14, 17, 18, 23, 29], "hi": 3, "hierarch": 1, "hierarchi": 1, "high": [2, 3, 4, 7, 23], "higher": 22, "highlight": [0, 1, 7, 19, 22], "hint": [0, 7, 14, 20, 23], "histogram": [7, 28], "histori": [1, 7, 20], "hole": [0, 7], "home": [0, 7], "hopefulli": [0, 7], "host": [2, 4, 13, 28, 29], "hour": [10, 23, 24], "hover": 23, "how": [0, 2, 3, 9, 10, 11, 15, 19, 25, 27, 29], "howev": [0, 1, 7, 21], "hpc": [7, 23], "html": 13, "http": [0, 2, 4, 6, 7, 10, 12, 13, 14, 18, 21, 22, 23, 24, 26, 28, 29], "huge": [11, 13], "human": [0, 1, 7], "humanist": [0, 7], "humour": [0, 7], "hundr": 29, "hypothesi": 23, "i": [0, 1, 2, 3, 6, 7, 8, 9, 10, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 25, 26, 27, 29], "idea": [1, 2, 3, 7, 8, 13, 20, 24], "ideal": [0, 7], "ident": [1, 25], "imag": 1, "imbal": 6, "immedi": [1, 7, 10, 23, 24, 29], "impart": [0, 7], "imped": 1, "implement": [2, 22, 26], "import": [0, 3, 7, 10, 12, 13, 17, 20, 23, 25, 28, 29], "imposs": [7, 12, 22, 26], "impost": 25, "impress": 25, "improv": [1, 2, 7, 11, 13, 14, 19, 29], "improvemest": 21, "improvis": [0, 7], "inaccur": 1, "incent": [13, 23, 24], "inclin": [0, 7], "includ": [0, 1, 7, 9, 19, 23, 29], "inclus": [1, 11, 25], "incomplet": 1, "incorpor": 1, "increas": [1, 7, 10, 29], "increment": 3, "independ": [0, 2, 3, 5, 7, 11, 14, 21, 25, 27], "index": [7, 13], "indic": [1, 23], "indico": 22, "indirectli": 25, "individu": [0, 1, 8], "info": [7, 18, 23], "inform": [0, 1, 3, 7, 10, 12, 14, 20, 22, 23, 25, 28, 29], "infrastructur": [0, 2, 7, 11], "ing": 24, "inherit": 1, "initi": [1, 4, 7, 23], "initial_prompt": [7, 23], "input": [7, 23], "inspir": 25, "instal": [1, 3, 23], "instanc": 1, "instant": [4, 24, 29], "instead": [3, 5, 7, 12, 14, 20, 23, 27, 29], "institut": [2, 3, 8, 11, 29], "instruct": [7, 20, 21, 23, 24, 28, 29], "instructor": [0, 2, 3, 4, 5, 6, 8, 10, 11, 13, 14, 15, 17, 20, 21, 24, 27, 28, 29], "instrument": 1, "integr": [7, 10], "intend": [0, 1, 2, 7], "intens": [5, 15], "intent": [0, 7], "interact": [0, 4, 10, 11, 14, 18, 20, 21, 22, 23, 24, 25, 27, 29], "interest": [0, 3, 4, 7, 8, 10, 11, 19, 20, 27], "interfac": [15, 17, 26], "intermedi": 2, "interpret": 1, "interrupt": [0, 7, 20], "interview": 21, "intro": [1, 7, 9, 13, 14, 15, 17, 23, 29], "introduc": [20, 28, 29], "introduct": [3, 7, 20, 23, 29], "intructor": 1, "intuit": [0, 7], "invent": [5, 7, 11, 23], "invest": [0, 7], "investig": 3, "invit": [4, 14], "involv": [6, 15, 22], "io": [4, 7, 10, 12, 14, 18, 21, 22, 23, 24, 28], "isn": [0, 7, 10, 13, 25], "issu": [0, 3, 7, 13], "item": [7, 27], "iter": [2, 27], "its": [0, 1, 2, 7, 10, 11, 13, 23], "itself": [7, 10, 13, 17, 26], "jargon": [0, 7], "jessica": 3, "job": [0, 1, 3, 25], "join": [3, 11, 14, 29], "judg": 1, "jump": 23, "jupyt": 2, "just": [0, 3, 7, 20, 21, 23, 29], "justic": 10, "keen": 3, "keep": [0, 1, 2, 3, 7, 10, 14, 20, 29], "kei": [7, 15, 17, 23], "kept": 4, "kick": [11, 27], "kickstart": [7, 23], "kind": [25, 29], "know": [0, 1, 2, 3, 7, 11, 20, 22, 24, 25], "knowledg": [0, 2, 3, 7, 25], "known": [0, 2, 7, 9, 29], "ksa": [0, 7], "kth": 2, "labor": 21, "lack": [1, 3], "landmark": 1, "lang": [7, 23], "languag": [0, 2, 3, 7], "laptop": [3, 12], "larg": [0, 1, 4, 7, 10, 14, 20, 22, 24, 25, 27, 29], "larger": [3, 4, 13, 21], "last": [0, 7, 13, 27], "lastnam": 29, "late": [12, 23], "later": [1, 5, 7, 17, 19, 20, 23, 24, 29], "latest": 12, "latex": [3, 7], "layer": 7, "layout": [12, 17, 20], "lead": [7, 8, 23, 25, 27], "leader": [6, 22, 27, 28], "leaner": [1, 7], "learn": [0, 2, 3, 6, 7, 11, 15, 19, 20, 21, 22, 23, 25, 26, 28, 29], "learner": [0, 2, 3, 5, 10, 11, 12, 14, 20, 21, 22, 23, 24, 28, 29], "learnt": [0, 7, 25], "leasson": [1, 7], "least": [0, 1, 7, 13, 29], "leav": [0, 7, 23, 24], "lectur": [0, 7, 14, 20, 21, 29], "led": 27, "left": [7, 12, 18, 22, 23], "less": [0, 1, 3, 7, 20, 21, 25, 27, 29], "lesson": [0, 1, 2, 4, 9, 12, 19, 20, 21, 23, 28, 29], "let": [3, 20, 22, 23, 25, 27], "level": [1, 2, 3, 8, 14, 28], "librari": 3, "librarian": 26, "licens": 13, "life": [0, 7], "like": [0, 1, 3, 4, 7, 11, 13, 19, 20, 23], "limit": [0, 3, 7, 13, 14, 20, 22, 29], "line": [3, 7, 12, 23], "link": [14, 25], "linux": [3, 7, 23], "list": [0, 11, 12, 17, 23, 27, 28], "listen": [7, 19, 20], "littl": [5, 13, 25, 29], "live": [0, 1, 4, 5, 7, 14, 24, 25], "livestream": [4, 5, 11, 22, 23, 24, 28], "ll": 1, "local": [3, 4, 5, 7, 8, 13, 22, 27, 29], "locat": [1, 4, 22], "log": 29, "logic": [3, 7], "login": [1, 3], "long": [0, 1, 7, 9, 13, 20, 23, 24, 29], "longer": [11, 21], "look": [0, 1, 7, 12, 20, 23, 24], "lose": 29, "loss": 29, "lost": [7, 13, 23, 24], "lot": [0, 7, 20, 22, 28], "loud": 14, "love": [0, 2, 7], "low": [17, 24, 25], "lower": 28, "luci": 25, "machin": 3, "made": [0, 7, 22, 26, 28, 29], "mai": [0, 1, 3, 7, 22, 23, 25, 27], "mail": 22, "main": [0, 3, 7, 20, 22, 23, 29], "mainli": [7, 20], "maintain": [2, 13, 27, 29], "major": [1, 2, 6, 25], "make": [0, 1, 2, 3, 5, 7, 10, 11, 12, 13, 19, 20, 21, 22, 24, 26, 27, 28, 29], "manag": [1, 7, 10, 22, 28, 29], "mani": [0, 1, 3, 5, 8, 12, 13, 17, 18, 20, 21, 24, 25, 26, 27, 29], "manifest": 25, "manner": 22, "manual": [10, 12, 14, 15, 18, 20, 21, 22, 23, 24, 28], "manula": 20, "map": [0, 7], "march": 29, "markdown": 10, "market": 8, "mass": 27, "massiv": 28, "master": [0, 3, 7], "masteri": 1, "match": [1, 7, 20, 21], "materi": [0, 2, 3, 4, 7, 11, 13, 14, 17, 27], "max": 29, "maximum": 4, "mayb": 3, "mctigh": 1, "md": 7, "me": [0, 7], "mean": [0, 7, 21, 23, 28], "meaning": 14, "meant": 3, "measur": 2, "mechan": [1, 10, 25, 29], "meet": [1, 4, 8, 14, 24, 29], "member": 8, "memori": 3, "mention": [7, 9, 10], "mentor": [5, 6, 11], "mentorship": [0, 6, 7], "mesh": 3, "messag": 22, "met": 1, "method": [1, 3], "might": [0, 1, 7, 17, 23, 24, 27], "min": [7, 15, 21], "mind": [0, 1, 7, 20, 21], "minim": [0, 7, 14, 20, 23, 27], "minimum": [1, 3, 7, 13, 29], "minut": [1, 3, 12, 17, 19, 20, 29], "misconcept": 1, "miss": [0, 1, 7, 20, 23, 24, 29], "mistak": [0, 7, 23, 24, 26], "mix": [0, 7, 14, 21], "mixtur": 1, "mkv": [7, 23], "mode": [1, 10, 23, 29], "model": [3, 5, 11, 21, 27], "modern": [6, 25], "modif": 13, "modifi": [7, 23], "modular": 2, "monitor": 29, "month": [2, 3], "mooc": 14, "more": [0, 1, 2, 3, 5, 6, 8, 10, 11, 13, 14, 15, 18, 19, 20, 21, 22, 25, 26, 27, 29], "most": [0, 1, 3, 6, 7, 11, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 26, 29], "mostli": [3, 29], "motion": 1, "motiv": [0, 5, 6, 7, 12, 29], "mous": 23, "move": [1, 3, 21, 23], "mtcv7gubpzd4a6uypekzumgk0fl5w0rsse6alzxv1ne635yl1gpyckk": 6, "much": [0, 1, 3, 5, 7, 10, 11, 12, 18, 20, 21, 22, 23, 27, 29], "multi": [3, 29], "multipl": [1, 20, 29], "multiprocess": 3, "music": 1, "must": [1, 3, 7, 10, 20, 23], "my": [0, 3, 7], "myself": [0, 7], "mysteri": [0, 7], "n": [22, 29], "n2ak": 23, "name": [10, 22, 23, 29], "narr": [0, 7], "natuar": 22, "natur": [0, 7, 22], "navier": 3, "nearbi": 22, "necessari": [7, 23], "necessarili": 1, "need": [0, 1, 2, 3, 5, 7, 8, 12, 20, 21, 22, 23, 24, 25, 27, 29], "neg": [1, 7], "negoti": [1, 7], "neic": 2, "nest": 3, "net": 26, "network": [2, 3, 8, 11, 25, 29], "neural": 3, "neurolog": [0, 7], "neurosci": 3, "never": [0, 1, 3, 7, 23, 29], "new": [0, 2, 3, 7, 8, 11, 13, 18, 19, 20, 21, 23, 27, 29], "next": [0, 2, 7, 20, 23, 29], "nitti": [0, 7], "node": 3, "non": [3, 4, 7, 8], "none": [6, 21, 26, 28], "nor": 10, "nordic": [2, 4], "normal": [1, 29], "note": [0, 1, 7, 10, 12, 20, 25], "notebook": 12, "notic": [0, 7, 19, 23, 25], "notion": 3, "novic": [0, 7], "now": [0, 3, 4, 7, 13, 15, 18, 20, 22, 23], "nu": 2, "number": [3, 10, 11, 14, 20, 21, 22, 25, 29], "numer": 3, "nurs": 1, "o": [3, 6, 7, 23], "ob": 23, "object": [0, 7, 24], "observ": [0, 5, 7, 8, 10], "obsolet": 11, "obtain": 3, "obviou": [0, 7, 20, 23, 29], "obvious": 17, "occasion": [7, 10], "octob": 2, "off": [0, 7, 12, 18, 23, 24], "offens": [0, 7], "offer": [0, 7], "offic": 11, "offici": 8, "often": [0, 1, 2, 3, 6, 7, 20, 21, 22, 25, 28], "ok": [1, 7, 23], "old": [1, 15, 20, 29], "onboard": [21, 28], "onc": [0, 3, 7, 26, 29], "one": [0, 1, 3, 7, 10, 12, 19, 20, 21, 22, 23, 24, 25, 29], "ones": 17, "onli": [0, 1, 5, 7, 13, 15, 19, 20, 23, 24, 25, 29], "onlin": [1, 2, 8, 11, 12, 13, 14, 21, 25], "open": [0, 2, 4, 7, 10, 11, 12, 13, 14, 27], "oper": 3, "opinion": 1, "opportun": [0, 2, 3, 7, 12, 18], "opposit": [0, 7], "optim": 1, "optimis": 3, "option": [13, 20, 22, 23], "order": [0, 1, 3, 7, 19, 24], "ordinari": 1, "organ": [1, 4, 7, 8, 18, 19, 21, 22, 28], "organiz": 15, "orient": 20, "origin": [7, 13, 23], "oslo": 3, "other": [0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 12, 13, 18, 19, 20, 21, 22, 23, 25, 27], "otherwis": [7, 10, 23, 26], "our": [0, 1, 2, 5, 6, 7, 8, 11, 13, 14, 15, 17, 19, 21, 22, 23, 24, 25, 26, 27, 29], "ourselv": 29, "out": [0, 1, 2, 3, 7, 8, 11, 13, 17, 20, 22, 23, 27, 29], "outcom": [0, 1, 3, 7], "output": 3, "output_format": [7, 23], "outreach": [8, 28], "outsid": [7, 11, 12, 23], "over": [0, 4, 7, 11, 20, 23, 29], "overal": [2, 3, 23], "overcom": [0, 7, 15, 17], "overflow": 25, "overlap": 29, "overload": [20, 27], "overview": [1, 2, 15, 17, 25, 28, 29], "overwhelm": [0, 7, 10, 29], "own": [0, 1, 2, 3, 8, 11, 17, 22, 24, 27], "pace": [0, 1, 7], "page": [4, 7, 13, 21, 23], "pai": [0, 7], "paint": [3, 7], "paper": [3, 7, 17], "paradigm": 3, "parallel": [1, 3, 10, 23, 27], "part": [0, 1, 4, 7, 11, 20, 21, 23, 25], "part1": [7, 23], "particip": [0, 2, 4, 7, 12, 14, 19, 23, 24, 25, 29], "particular": [1, 3, 11, 21], "particularli": [0, 7], "partner": [2, 5, 27], "partwai": 22, "pass": [1, 13], "passiv": 14, "past": [0, 2, 7, 10, 23], "path": [7, 23], "pathwai": 15, "patricia": 1, "pattern": 1, "paus": 12, "pedagogi": 18, "peopl": [0, 1, 2, 4, 5, 6, 8, 10, 12, 14, 15, 17, 18, 20, 22, 23, 24, 25, 26, 27, 29], "per": [1, 4, 7, 22, 23, 29], "perceiv": [0, 7], "perfect": 23, "perfectli": [0, 7, 21, 27], "perform": [3, 7, 19], "perhap": [0, 7, 10, 23, 24, 25], "period": [0, 5, 7], "person": [0, 1, 4, 5, 7, 10, 11, 14, 18, 19, 20, 21, 25, 28], "persona": [0, 3, 7, 11], "perspect": [0, 7], "phd": 3, "phil": [15, 17], "philosophi": 11, "physic": [4, 22, 29], "pick": [3, 7, 19], "pictur": [0, 7, 20], "piec": [1, 3, 24], "pip": [7, 23], "pitfal": [7, 9, 19], "place": [0, 1, 4, 5, 7, 23, 29], "placehold": 11, "plai": 1, "plan": [0, 2, 3, 4, 7, 9, 11, 20, 21, 28, 29], "planet": 1, "platform": [13, 24], "playlist": [0, 7, 23], "pleas": [0, 7, 17, 19], "plplblyhczjaahf89p": 0, "plzlvms9rf3nmkr2jmglan4su3ojwtwmvw": [7, 23], "point": [0, 1, 3, 7, 19, 20, 22, 23, 26], "poll": 1, "port": 2, "portion": [1, 7], "portrait": 12, "posit": [1, 7], "possibl": [0, 1, 2, 7, 11, 12, 13, 14, 20, 24, 29], "possibli": [5, 6, 7, 9, 20, 27, 29], "post": [1, 2], "postdoc": 3, "potenti": 3, "power": 29, "practic": [0, 1, 11, 12, 13, 21, 25, 29], "practis": [0, 1, 7], "practition": [0, 7], "pre": [1, 2, 11, 22, 29], "precis": [0, 7, 20], "prefer": [3, 7, 12, 13, 15, 17, 19, 24], "prep": [20, 29], "prepar": [0, 1, 4, 7, 20, 21, 24, 27], "prerequisit": [1, 7, 23], "presenc": 14, "present": [1, 2, 4, 6, 7, 19, 20, 23, 27, 29], "press": 3, "pressur": [20, 24], "prevent": [0, 7, 25], "previou": [0, 7, 11], "previous": 27, "primari": 29, "primarili": 21, "principl": 23, "prior": [1, 2], "prioriti": [17, 23], "privaci": [10, 14, 23, 29], "pro": 12, "probabl": [1, 2, 7, 19, 23], "problem": [0, 1, 2, 3, 7, 25, 29], "procedur": [1, 13], "process": [1, 5, 7, 23], "produc": [2, 7, 20, 23], "product": [0, 7], "profess": 11, "profession": [0, 7, 11], "profit": 8, "program": [0, 1, 2, 3, 7, 11, 15], "progress": [0, 3, 5, 7, 8], "project": [1, 3, 11, 13], "promis": [1, 4], "promot": [8, 13, 25], "prompt": [7, 23], "proper": 3, "properti": [20, 22], "propos": [2, 12], "provid": [1, 2, 3, 5, 7, 8, 15, 17, 20, 23, 24, 25], "pub": 6, "public": [13, 27], "publicli": 2, "publish": [10, 28], "pull": [0, 7, 13, 23], "punctuat": [7, 23], "pure": [7, 13, 29], "purpos": [1, 20], "put": [0, 1, 4, 7, 29], "puzzl": [0, 7], "py": [7, 13], "python": [0, 7, 23, 29], "pyyaml": [7, 23], "q": [10, 15], "qualifi": 2, "qualiti": [2, 23], "quantifi": 2, "question": [0, 1, 2, 3, 7, 10, 18, 19, 21, 22, 28, 29], "queue": 1, "quick": [7, 23, 29], "quicker": 21, "quickli": [6, 7, 21, 22, 23, 28, 29], "quiet": [10, 20, 29], "quit": [0, 1, 6, 7, 22], "r": 13, "rabbit": [0, 7], "rais": [0, 2, 7, 29], "ran": 3, "random": 10, "rang": [0, 7], "rapid": 29, "rare": [0, 7], "rather": 3, "raw": [13, 24], "re": [0, 5, 7, 11, 22, 23], "reach": [1, 14], "react": [0, 7, 21], "read": [0, 1, 6, 7, 12, 15, 24], "readabl": 12, "reader": [7, 23], "readi": [1, 3, 7, 23, 29], "real": [0, 1, 7, 23], "realis": [0, 7], "realiti": 21, "realiz": [0, 7], "realli": [0, 3, 7, 29], "reason": [0, 1, 3, 7, 13, 26, 29], "receiv": [7, 14, 19, 27, 28], "recent": [0, 3, 20], "reckon": [0, 7], "recogn": 1, "recommend": [0, 9, 17, 29], "record": [7, 11, 13, 23], "recruit": 29, "reduc": [3, 11, 20, 27, 29], "reencod": [7, 23], "refer": 7, "refin": 4, "refocu": 1, "region": 1, "regist": [4, 29], "registr": [4, 5, 22, 28, 29], "regular": [3, 7], "regularli": [0, 7], "reinforc": 1, "relat": [0, 1, 7, 18, 26], "relationship": 1, "releas": [23, 27], "relev": [0, 1, 3, 5, 7, 11, 25, 27], "reli": [1, 7, 21], "remain": 1, "rememb": [0, 1, 3, 7, 23], "remot": [1, 3, 7, 23], "remov": [12, 18, 23, 24], "renam": 22, "repeat": [0, 1, 7], "replac": [10, 13, 15], "replai": [4, 24], "repli": [20, 29], "report": [1, 7], "repositori": [2, 29], "repres": 25, "reproduc": 2, "request": [0, 1, 7, 13, 22], "requir": [0, 3, 7, 10, 13, 19, 20, 27, 28, 29], "research": [0, 1, 2, 3, 6, 7, 11], "reserv": [1, 5, 7], "resid": 1, "resourc": [1, 3, 11, 14, 25], "respect": 1, "respond": [1, 7, 10], "rest": [1, 7, 18, 23], "result": [1, 2, 4, 7, 15, 17, 23], "return": [0, 7], "reus": 13, "reusabl": 2, "reveal": 18, "revert": 27, "review": [1, 7, 10, 12, 23, 24], "reward": 5, "rewind": 20, "rework": 11, "rewrit": 13, "richard": 6, "right": [0, 7, 10, 12, 13, 18, 23, 27, 29], "risk": [5, 14, 23, 24], "road": 1, "robert": 3, "role": [5, 6, 10, 11, 14, 22, 23, 26], "room": [0, 1, 3, 4, 5, 7, 8, 14, 20, 22, 23, 24, 28], "rotat": [28, 29], "rough": 3, "round": [7, 19], "rst": [7, 13], "rubric": [1, 7, 19], "run": [1, 3, 5, 8, 11, 20, 28], "ruptur": 3, "s1": 20, "s2": 20, "s3": 20, "s4": 20, "sad": [1, 7], "safe": 1, "sai": [23, 24, 25, 27], "said": [7, 23, 26], "same": [0, 1, 3, 7, 11, 12, 13, 19, 20, 21, 22, 23, 27, 28, 29], "save": 20, "saw": [0, 7], "scalabl": 10, "scale": [1, 3, 4, 20, 21], "scan": [1, 7, 21], "scari": 27, "schedul": [3, 4, 7, 23, 28], "scheme": 12, "scicomp": [4, 7, 23], "scicompintro": [7, 23], "scienc": [7, 15, 23, 27], "scientif": [2, 7, 23, 29], "scientist": 3, "scip": [4, 7, 23], "scratch": [1, 24], "screen": [1, 3, 19, 23], "screenshar": [7, 10, 14], "screenshot": [7, 12], "script": [0, 1, 2, 3, 7], "scroll": [10, 23], "second": [7, 13, 19, 23], "section": [1, 2, 3, 6, 7, 18, 19, 21, 23], "see": [0, 1, 5, 7, 8, 9, 14, 24, 29], "seem": [0, 1, 7, 13, 21], "segment": [7, 19, 23], "select": [22, 29], "self": [0, 7, 22, 25], "sell": 8, "semant": [0, 7], "send": [0, 7, 8, 13, 29], "sens": [0, 2, 7], "sensit": [0, 7], "sentenc": [0, 7, 23], "separ": [0, 7, 20, 23, 24], "sequenc": [3, 23], "serial": [0, 3, 7], "serv": [6, 13, 28, 29], "servic": [2, 8, 10], "sese": 2, "session": [0, 1, 2, 5, 7, 10, 11, 12, 19, 20, 23, 25, 29], "set": [0, 1, 20, 22, 29], "setup": [1, 11, 19, 20], "sever": [0, 2, 4, 6, 7, 20, 23], "share": [0, 1, 2, 3, 5, 7, 10, 11, 13, 19, 23, 24, 25], "she": [1, 3], "shell": [1, 3, 7, 19], "ship": 2, "short": [1, 2, 5, 7, 17, 21, 23, 29], "shortcut": 12, "shortli": 29, "should": [0, 1, 2, 3, 5, 6, 7, 13, 19, 20, 22, 23, 25, 29], "shouldn": 29, "show": [0, 2, 3, 7, 12, 19, 20], "shy": 14, "side": 20, "sign": [0, 1, 7, 22], "signal": [0, 7, 13], "signific": [7, 13, 21], "signpost": 25, "silent": 25, "silo": 11, "similar": [0, 1, 15, 20, 22, 23], "simpl": [0, 1, 3, 7, 23, 24, 29], "simpler": 3, "simpli": [0, 1, 7], "simplifi": [0, 1, 7, 26], "simul": [3, 7, 23], "sinc": [0, 7, 11, 14, 17, 19, 21, 23, 24, 25, 29], "singl": 7, "sit": [0, 7, 22], "situat": [0, 1, 7, 12, 21], "six": 10, "size": [4, 22, 25, 29], "skill": [0, 1, 3, 7, 21, 22], "skip": [0, 1, 7], "slice": [7, 23], "slide": [0, 7], "slow": [0, 1, 7, 20, 23], "slower": [0, 1, 7, 29], "slowli": [0, 1, 7, 12], "small": [3, 4, 8, 12, 13, 14, 20, 27, 28], "smaller": [20, 25], "so": [0, 1, 3, 5, 7, 8, 9, 11, 12, 13, 19, 20, 21, 22, 23, 25, 27, 29], "social": [1, 6], "societi": 1, "socio": 11, "softwar": [0, 1, 3, 7, 11, 14, 29], "solut": 0, "solv": [0, 1, 2, 3, 7, 24], "some": [0, 1, 3, 4, 6, 7, 11, 12, 13, 15, 17, 18, 19, 20, 23, 24, 25, 28, 29], "somebodi": [0, 7, 13], "somehow": [18, 22], "someon": [1, 3, 7, 13, 15, 20, 23, 25], "someth": [0, 1, 3, 7, 11, 12, 20, 23, 25, 26], "sometim": [0, 7, 28], "sonya": 3, "soon": 24, "sooner": [7, 19], "sort": 1, "sound": [0, 1, 7], "sourc": 13, "space": 22, "spare": [28, 29], "spark": [0, 7], "speak": [1, 14, 21, 23], "special": [1, 7, 10, 29], "specialist": 11, "specialti": 11, "specif": [0, 1, 2, 3, 7], "speed": [1, 2, 3, 7], "spend": [0, 7, 11, 12], "spent": [0, 7], "sphinx": [7, 13], "spike": 3, "split": [23, 24, 28], "spot": 23, "spotlight": 29, "srt": [7, 23], "stack": 25, "staff": [4, 6, 22, 23, 25, 27], "stage": 1, "stai": [22, 29], "standard": 13, "start": [0, 1, 2, 3, 7, 11, 12, 13, 20, 23, 25, 29], "state": [1, 3, 14, 20], "static": 29, "stax": 26, "step": [0, 1, 7, 8, 20, 23, 29], "sth": 24, "stick": 23, "still": [0, 1, 3, 4, 7, 8, 13, 27, 29], "stockholm": 2, "stoke": 3, "stop": [0, 7, 23], "storag": [7, 23], "store": 13, "stori": [0, 7], "storytel": [0, 7], "strategi": [3, 14, 18, 20, 27], "stream": [5, 7, 14, 23, 24, 25], "streamer": 29, "strength": 21, "stress": 29, "strictli": 21, "strong": 21, "strongli": [1, 7, 22], "structur": [0, 7], "struggl": [0, 7], "stuck": [0, 7, 20], "student": [0, 2, 3, 7, 10, 20, 21, 25, 27, 29], "studi": [0, 1, 6, 7], "stuff": [1, 2, 7], "style": [0, 2, 11], "sub": 28, "submit": [1, 2, 3], "subset": 7, "substanti": 13, "success": [0, 3], "successfulli": 5, "suffer": [18, 25], "suffici": [0, 1, 2, 7], "suggest": [2, 3, 7, 13], "suitabl": [1, 27], "sum": [0, 7], "summ": 3, "summari": [6, 15, 17], "summer": [7, 11, 23], "superfici": 1, "support": [0, 2, 3, 7, 10, 28], "sure": [0, 1, 7, 20, 23, 24, 29], "surpris": [0, 6, 7], "survei": [1, 2, 7], "sustain": [2, 8, 25], "switch": 14, "sync": 27, "synchron": 10, "syndrom": 25, "system": [1, 3, 6, 7, 13, 20, 22, 29], "t": [0, 1, 3, 7, 8, 10, 11, 13, 14, 17, 18, 20, 21, 22, 23, 24, 25, 27, 29], "tabl": [7, 22, 23], "take": [0, 1, 3, 6, 7, 8, 17, 19, 20, 21, 23, 24, 29], "taken": 8, "talk": [1, 7, 13, 17, 23], "target": [0, 1, 3, 7], "task": [1, 3, 7, 19], "taught": [0, 1, 4, 7, 27, 29], "teach": [2, 3, 5, 6, 8, 9, 10, 12, 13, 14, 15, 23, 25], "teacher": [0, 1, 7, 21, 25, 26, 27, 28], "team": [0, 3, 5, 8, 11, 20, 27, 28], "tech": [3, 11, 15, 20], "technic": [0, 3, 6, 7], "techniqu": [4, 7, 18], "techniquess": 29, "technologi": [3, 6, 7, 26], "tell": 1, "templat": [7, 13, 29], "tend": [0, 7], "term": [1, 9], "termin": [1, 7, 12], "terribl": 26, "terrifi": 3, "test": [3, 13], "text": [0, 7, 13, 23, 26], "than": [0, 1, 3, 7, 10, 11, 13, 18, 20, 21, 23, 26, 27, 29], "thei": [0, 1, 2, 3, 5, 7, 10, 11, 14, 20, 22, 23, 24, 26, 29], "them": [0, 1, 2, 3, 5, 7, 9, 11, 13, 19, 22, 29], "theme": [2, 13], "themselv": [22, 29], "theoret": 2, "therefor": 1, "therein": [3, 7], "thesi": 3, "thi": [0, 2, 3, 5, 6, 9, 10, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 24, 27, 29], "thing": [0, 3, 4, 7, 11, 13, 17, 20, 21, 23, 25, 26, 27, 29], "think": [0, 1, 3, 7, 18, 20, 26, 27], "those": [0, 1, 7, 8, 21], "though": [0, 2, 3, 7], "thousand": 1, "thread": [3, 20], "three": [0, 1, 3, 7, 14, 21, 29], "through": [1, 2, 3, 7, 10, 17, 20, 22, 23], "throughout": [0, 7], "thrown": [0, 7], "thu": [11, 14, 21, 22], "thvmntbjg2y": 23, "time": [0, 1, 3, 4, 5, 7, 11, 12, 14, 17, 20, 21, 23, 26], "timestamp": [7, 23], "tip": [3, 20], "titl": [7, 23], "todai": [0, 7], "togeth": [1, 3, 4, 11, 15, 20, 22, 25, 29], "toler": 29, "tomorrow": 20, "too": [0, 1, 2, 3, 7, 11, 12, 20, 22, 23, 24, 27, 29], "tool": [0, 1, 2, 3, 6, 8, 10, 18, 23, 26], "toolbox": 2, "top": 28, "topic": [0, 1, 4, 6, 15, 19, 20, 21, 23, 25], "total": 29, "toward": [0, 2, 7], "track": [4, 13], "trade": [7, 12, 18], "tradit": [0, 7], "train": [0, 1, 2, 3, 4, 6, 7, 8, 15, 17, 21, 23, 28], "traine": [0, 7], "trainer": [0, 7], "transcript": [7, 23], "transit": [2, 22, 23], "translat": [3, 7, 18, 23], "transmiss": [0, 7], "travel": 4, "tree": [0, 7], "tri": [2, 3, 5, 14, 18], "trial": [7, 19, 20], "trick": [0, 4, 7, 29], "trivial": 13, "troll": 14, "true": [1, 13], "try": [0, 1, 3, 4, 5, 7, 11, 13, 14, 20, 22, 23, 29], "tune": 27, "turn": 20, "tutori": [0, 7, 25], "tv": 29, "twenti": [0, 7], "twist": [0, 7], "twitch": [14, 29], "two": [0, 1, 2, 3, 4, 7, 12, 20, 21, 22, 23, 27, 29], "txt": [7, 23], "type": [0, 1, 3, 7, 12, 20, 21], "typic": [2, 3, 7, 12, 13, 19, 28, 29], "typo": [0, 7], "u": [0, 1, 2, 5, 7, 8, 11, 13, 14, 19, 23, 24, 25, 27], "un": 6, "unansw": 10, "uncertainti": 21, "unclear": [0, 7], "unconfer": 8, "under": [1, 13, 25, 28, 29], "underli": [7, 26], "understand": [0, 1, 2, 3, 7, 13, 17, 20, 26, 27], "unexpect": 21, "unfamiliar": 20, "unfortun": 6, "uniqu": 1, "unit": 1, "univers": [1, 2, 5, 29], "unix": [3, 7], "unless": 17, "unlimit": 14, "unnecessari": 20, "unprocess": [23, 24], "until": [2, 20], "up": [0, 1, 2, 3, 4, 19, 20, 21, 22, 23, 24, 29], "updat": [28, 29], "uptak": 22, "us": [0, 2, 3, 4, 8, 10, 11, 12, 13, 14, 15, 18, 19, 20, 22, 24, 25, 27, 28, 29], "usabl": 11, "usag": 2, "user": [7, 15, 17, 23, 26], "usual": [0, 1, 2, 3, 6, 7, 12, 14, 18, 21, 26, 27, 28, 29], "v": [1, 7, 23, 24], "valid": [1, 7, 10, 13], "valu": [0, 27], "vancouv": 1, "vanderbilt": 1, "varieti": 28, "variou": [3, 20], "ve": [0, 7, 11, 26, 29], "verbal": [7, 19], "veri": [0, 1, 2, 3, 6, 7, 13, 20, 21, 23, 27, 29], "verif": 29, "verifi": [1, 29], "version": [2, 3, 4, 11], "vertic": 20, "via": [4, 5, 13, 14, 25, 28, 29], "video": [1, 11, 19, 28, 29], "view": [10, 14, 29], "viewer": 29, "violat": 14, "virtual": [7, 21, 23], "virtualenv": [0, 7], "visibl": 8, "vision": [4, 11, 27], "voic": [21, 24, 29], "volum": 25, "wa": [0, 1, 2, 3, 4, 7, 9, 19, 23, 29], "wai": [0, 3, 6, 7, 11, 14, 18, 20, 21, 23, 26, 29], "want": [0, 1, 2, 3, 4, 5, 7, 8, 10, 12, 13, 17, 19, 20, 22, 23, 24, 29], "war": [0, 7], "warn": [10, 20], "watch": [0, 1, 4, 5, 6, 7, 10, 12, 15, 19, 20, 21, 22, 23, 24, 28, 29], "we": [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 13, 14, 17, 18, 19, 20, 23, 28, 29], "weather": 1, "web": [10, 13], "webpag": [7, 23, 29], "websit": 13, "week": [0, 7, 29], "weekli": 8, "weird": 20, "welcom": [7, 8, 11, 23], "well": [0, 1, 5, 7, 14, 25, 29], "wen": 29, "went": [4, 29], "were": [4, 11, 23, 29], "weren": [0, 7], "whallei": 25, "what": [0, 2, 3, 4, 6, 8, 12, 13, 15, 19, 29], "whatev": 20, "whelm": 29, "when": [0, 1, 3, 6, 7, 10, 14, 20, 22, 23, 24, 26, 29], "whenev": [0, 2, 7], "where": [0, 1, 3, 7, 10, 20, 23, 25], "whether": [0, 1, 7, 19, 23], "which": [0, 1, 3, 5, 7, 12, 13, 17, 18, 19, 20, 23, 25, 27, 29], "while": [0, 1, 5, 7, 12, 14, 20, 23, 29], "whiteboard": [1, 7], "who": [0, 3, 4, 7, 8, 22, 23, 25, 29], "whole": [20, 22, 23, 24, 29], "why": [0, 1, 3, 9, 11, 25, 29], "wide": [13, 21], "wider": [0, 7], "widespread": 3, "wiggin": 1, "wikipedia": 21, "willing": [0, 7], "window": 20, "wire": [0, 7], "wish": [2, 5], "within": [1, 7, 12, 14, 21, 22, 23, 24], "without": [1, 7, 12, 13, 22], "won": [1, 3, 7, 18, 23], "wonder": [0, 7], "word": [0, 1, 3, 7, 23], "work": [0, 2, 3, 7, 11, 12, 13, 14, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29], "workflow": [2, 7, 13, 23], "workload": [4, 21], "workshop": [0, 1, 3, 4, 6, 8, 10, 18, 19, 20, 22, 23, 24], "world": [0, 1, 4, 7, 14, 25], "worri": [0, 7, 17, 20], "wors": [18, 20], "worth": 23, "worthwhil": [0, 7], "would": [0, 1, 2, 3, 4, 7, 9, 10, 11, 14, 17, 19, 22, 24, 26, 27], "write": [0, 2, 3, 7, 19], "written": 29, "wrong": [1, 7], "www": [0, 6, 7, 23, 26], "x": [0, 3, 7], "year": [0, 1, 2, 3, 4, 7], "yet": [1, 2, 6, 7, 8, 14, 21, 22, 23, 26, 28], "yml": [7, 13], "you": [0, 1, 3, 4, 7, 10, 11, 12, 13, 14, 15, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "young": 3, "your": [0, 1, 3, 8, 11, 17, 19, 20, 22, 24, 27], "yourself": [0, 7, 20], "youtub": [0, 6, 7, 15, 17, 23], "z1vs1wlen": 6, "zoom": [14, 20, 22, 24, 25]}, "titles": ["CodeRefinery teaching philosophies", "Interactive teaching style", "About the CodeRefinery project and CodeRefinery workshops", "Backwards lesson design", "Collaboration models", "Distributed workshop organization", "Diversity and inclusion", "Exercise list", "Possibilities for Carpentries", "Instructor\u2019s guide", "HackMD", "Community teaching training", "Instructor tech setup", "Lesson development with version control", "Livestreaming", "Other resources", "Placeholder", "Pre-workshop preparation", "Teaching online", "Teaching practice and feedback", "How to teach online", "Team teaching", "Teams", "Video editing", "Video recording", "Welcome and introduction", "Why are computers hard?", "Why teach together?", "Workshop roles", "Running a workshop: online"], "titleterms": {"": [1, 8, 9], "1": [7, 19, 23], "10": [1, 7], "15": 17, "2": [7, 19, 23], "20": [0, 7, 17], "2022": 11, "3": [7, 23], "35": 17, "4": [7, 23], "45": 17, "5": [7, 17, 23], "6": [7, 23], "7": [7, 23], "A": [17, 23], "In": 22, "It": 5, "On": 1, "The": [1, 3, 17], "about": 2, "abstract": 26, "actual": 22, "add": [7, 23], "adjust": 12, "advanc": [7, 13, 14], "advantag": [10, 27], "agr": 26, "also": [6, 13, 18, 20, 21, 23, 26, 27, 28], "an": 3, "ani": 24, "ann": [0, 7], "approach": [1, 3], "ar": [1, 7, 26], "arrang": 29, "articl": [6, 10, 14, 21, 22, 23, 28], "asid": 8, "assess": 1, "audienc": 2, "b": 23, "backward": [3, 7], "basic": [7, 22, 23, 29], "bast": [0, 7], "benefit": 21, "best": 2, "biggest": 8, "bj\u00f8rn": [0, 7], "bloom": 1, "breaker": [0, 7], "breakout": 29, "bring": 29, "broadcast": 24, "brows": 17, "can": [6, 7, 8], "captur": [7, 12], "carpentri": [1, 2, 3, 8], "case": 29, "challeng": 27, "co": [4, 7, 21], "code": [19, 25], "coderefineri": [0, 1, 2, 4, 7, 8, 13, 17, 29], "cognit": 1, "collabor": [4, 7, 29], "color": 12, "command": 12, "commun": 11, "compet": [1, 2], "comput": [4, 7, 17, 26], "concept": 22, "conclus": 26, "conduct": 25, "confid": 25, "configur": 12, "consider": 11, "consist": 12, "content": [11, 17], "contribut": [7, 13], "control": [7, 13], "cours": 11, "cover": 11, "creat": [7, 13, 23], "curriculum": 1, "da": [0, 7], "dai": 24, "darst": [0, 7], "deep": 26, "defin": [6, 7], "demo": 19, "demonstr": 20, "design": [1, 3, 7, 11], "detail": 14, "develop": [1, 7, 11, 13], "disadvantag": [10, 27], "discuss": [19, 20, 22, 23, 29], "distribut": [5, 23], "divers": [6, 7], "do": [7, 22, 25, 27], "easi": 23, "easier": 5, "edit": [7, 23], "editlist": [7, 23], "effect": 1, "engin": 8, "environ": [7, 12], "evalu": [7, 12], "exampl": [3, 12, 19], "exercis": [1, 3, 4, 6, 7, 10, 12, 13, 14, 18, 19, 21, 22, 23, 26, 27, 28], "expert": 1, "face": 1, "factor": 24, "failur": [4, 7], "featur": [7, 23], "feedback": [1, 7, 19], "ffmpeg": [7, 23], "file": [7, 23], "final": [7, 23], "finland": 29, "follow": 5, "forc": 12, "form": 1, "fouilloux": [0, 7], "from": 5, "futur": [11, 17], "gener": [7, 13, 23, 29], "get": [1, 7, 11, 23, 25], "give": [1, 7, 25], "goal": [2, 25], "goe": 20, "good": 20, "group": [0, 7], "guid": 9, "hackmd": [7, 10, 20, 29], "hard": [7, 26], "have": [7, 12, 27], "help": [17, 26], "helper": 29, "histori": [2, 12], "how": [1, 6, 7, 8, 12, 17, 20, 23, 26, 28], "hpc": [1, 3, 29], "i": [5, 11, 24], "ic": [0, 7], "identifi": [1, 7], "impact": 2, "import": [1, 24], "inclus": [6, 7], "initi": 26, "instal": [7, 14, 29], "instruct": 1, "instructor": [1, 7, 9, 12, 19, 25], "interact": [1, 7], "introduct": [11, 25], "involv": 11, "issu": 1, "job": [6, 7], "join": [5, 8], "jo\u00e3o": [0, 7], "juho": [0, 7], "kei": 1, "keypoint": [2, 5, 8, 12, 24], "kickstart": 29, "knowledg": 1, "larger": 5, "layer": 26, "lead": 5, "learn": [1, 5, 13, 17], "learner": [1, 7], "lehtonen": [0, 7], "lesson": [3, 5, 7, 11, 13, 17], "lindi": [0, 7], "link": 29, "list": [4, 7], "live": 19, "livestream": [7, 14], "m": [0, 7], "main": [2, 19], "make": 23, "mani": [7, 28], "manual": 29, "materi": 1, "matter": 20, "mechan": 20, "mega": 29, "mental": 1, "merg": 11, "meta": 20, "mid": 11, "min": 17, "minut": [0, 7], "mn": [1, 7], "model": [1, 4, 7], "more": [7, 12, 23, 24], "move": 11, "need": 11, "negru": [0, 7], "new": 1, "nordic": 8, "note": 29, "novic": [1, 2], "ob": [7, 14], "object": [1, 20], "old": 11, "onli": 17, "onlin": [7, 18, 20, 22, 29], "open": 8, "option": [1, 7, 17, 19], "organ": [5, 11], "other": [15, 24, 29], "out": 25, "output": [7, 23], "own": [7, 12, 13, 29], "part": 19, "peopl": [7, 28], "person": [22, 29], "phil": 26, "philosophi": [0, 7], "placehold": 16, "plan": 8, "platform": 29, "possibl": 8, "practic": [2, 7, 19, 20], "practition": [1, 2], "pre": 17, "prepar": [11, 17, 29], "primari": [6, 10, 14, 21, 22, 23, 28], "principl": 1, "privaci": 24, "problem": 8, "process": 3, "profil": [1, 7], "progress": 1, "project": 2, "promot": [6, 7], "prompt": 12, "prototyp": 20, "python": 4, "q": 17, "question": 20, "radovan": [0, 7], "raw": [7, 23], "razick": [0, 7], "read": [17, 26], "recommend": [1, 4, 7, 13], "record": [0, 24, 29], "refer": 11, "reflect": [6, 7], "releas": 24, "research": 8, "resourc": 15, "revers": 1, "revisit": 1, "richard": [0, 7], "role": [7, 24, 28, 29], "room": [19, 29], "rse": 8, "run": [7, 23, 29], "sabri": [0, 7], "same": 24, "sampl": [7, 13, 23], "scale": 29, "scienc": 17, "scientif": 4, "screen": [7, 12, 20], "screenshar": 12, "see": [6, 13, 18, 20, 21, 23, 26, 27, 28], "servic": 6, "set": [7, 12, 14], "setup": [7, 12, 24], "share": [12, 20], "shell": 20, "should": 12, "silva": [0, 7], "similar": [7, 27], "site": 13, "social": 11, "softwar": [2, 8], "solut": [1, 7, 23], "someon": [17, 26], "staff": 29, "start": 5, "static": 13, "stefan": [0, 7], "strategi": [21, 29], "stream": 29, "studi": 29, "style": [1, 7], "subtitl": [7, 23], "success": [4, 7], "summ": 1, "summari": [14, 23, 28], "support": 6, "talk": 20, "target": 2, "taxonomi": 1, "teach": [0, 1, 4, 7, 11, 17, 18, 19, 20, 21, 26, 27, 28, 29], "team": [7, 21, 22, 29], "tech": [7, 12, 14], "technic": 11, "test": [7, 23], "than": [5, 24], "thi": [1, 7, 11, 23, 25], "thor": [0, 7], "time": 29, "togeth": [7, 27], "tool": [7, 11, 13, 14, 25], "top": 1, "topic": [3, 7], "train": [11, 25, 29], "try": 24, "two": 19, "under": 11, "up": [7, 11, 12, 14], "us": [1, 7, 17, 23, 26], "usabl": 26, "v": [6, 29], "version": [7, 13], "video": [0, 7, 23, 24], "wai": [1, 27], "want": 25, "watch": 17, "we": [7, 11, 22, 24, 25, 26, 27], "welcom": 25, "what": [1, 7, 11, 20, 22, 23, 25, 26, 27], "whisper": [7, 23], "who": [1, 11], "whom": 2, "why": [7, 20, 26, 27], "wikfeldt": [0, 7], "work": 1, "workshop": [2, 5, 7, 11, 17, 25, 28, 29], "wrap": 11, "write": 1, "yaml": [7, 23], "you": 8, "your": [6, 7, 12, 13, 23, 28, 29], "zoom": 29}}) \ No newline at end of file diff --git a/branch/community-teaching/singlehtml/_static/_sphinx_javascript_frameworks_compat.js b/branch/community-teaching/singlehtml/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 0000000..8141580 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/branch/community-teaching/singlehtml/_static/basic.css b/branch/community-teaching/singlehtml/_static/basic.css new file mode 100644 index 0000000..f316efc --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/branch/community-teaching/singlehtml/_static/check-solid.svg b/branch/community-teaching/singlehtml/_static/check-solid.svg new file mode 100644 index 0000000..92fad4b --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/branch/community-teaching/singlehtml/_static/clipboard.min.js b/branch/community-teaching/singlehtml/_static/clipboard.min.js new file mode 100644 index 0000000..54b3c46 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/branch/community-teaching/singlehtml/_static/copybutton.css b/branch/community-teaching/singlehtml/_static/copybutton.css new file mode 100644 index 0000000..f1916ec --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/branch/community-teaching/singlehtml/_static/copybutton.js b/branch/community-teaching/singlehtml/_static/copybutton.js new file mode 100644 index 0000000..2ea7ff3 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/branch/community-teaching/singlehtml/_static/copybutton_funcs.js b/branch/community-teaching/singlehtml/_static/copybutton_funcs.js new file mode 100644 index 0000000..dbe1aaa --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/branch/community-teaching/singlehtml/_static/css/badge_only.css b/branch/community-teaching/singlehtml/_static/css/badge_only.css new file mode 100644 index 0000000..c718cee --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/branch/community-teaching/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff b/branch/community-teaching/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/branch/community-teaching/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff2 b/branch/community-teaching/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/branch/community-teaching/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff b/branch/community-teaching/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/branch/community-teaching/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff2 b/branch/community-teaching/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/branch/community-teaching/singlehtml/_static/css/fonts/fontawesome-webfont.eot b/branch/community-teaching/singlehtml/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/branch/community-teaching/singlehtml/_static/css/fonts/fontawesome-webfont.svg b/branch/community-teaching/singlehtml/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/branch/community-teaching/singlehtml/_static/css/fonts/fontawesome-webfont.ttf b/branch/community-teaching/singlehtml/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/branch/community-teaching/singlehtml/_static/css/fonts/fontawesome-webfont.woff b/branch/community-teaching/singlehtml/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/branch/community-teaching/singlehtml/_static/css/fonts/fontawesome-webfont.woff2 b/branch/community-teaching/singlehtml/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/branch/community-teaching/singlehtml/_static/css/fonts/lato-bold-italic.woff b/branch/community-teaching/singlehtml/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/css/fonts/lato-bold-italic.woff differ diff --git a/branch/community-teaching/singlehtml/_static/css/fonts/lato-bold-italic.woff2 b/branch/community-teaching/singlehtml/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/branch/community-teaching/singlehtml/_static/css/fonts/lato-bold.woff b/branch/community-teaching/singlehtml/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/css/fonts/lato-bold.woff differ diff --git a/branch/community-teaching/singlehtml/_static/css/fonts/lato-bold.woff2 b/branch/community-teaching/singlehtml/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/css/fonts/lato-bold.woff2 differ diff --git a/branch/community-teaching/singlehtml/_static/css/fonts/lato-normal-italic.woff b/branch/community-teaching/singlehtml/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/css/fonts/lato-normal-italic.woff differ diff --git a/branch/community-teaching/singlehtml/_static/css/fonts/lato-normal-italic.woff2 b/branch/community-teaching/singlehtml/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/branch/community-teaching/singlehtml/_static/css/fonts/lato-normal.woff b/branch/community-teaching/singlehtml/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/css/fonts/lato-normal.woff differ diff --git a/branch/community-teaching/singlehtml/_static/css/fonts/lato-normal.woff2 b/branch/community-teaching/singlehtml/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/css/fonts/lato-normal.woff2 differ diff --git a/branch/community-teaching/singlehtml/_static/css/theme.css b/branch/community-teaching/singlehtml/_static/css/theme.css new file mode 100644 index 0000000..19a446a --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/branch/community-teaching/singlehtml/_static/doctools.js b/branch/community-teaching/singlehtml/_static/doctools.js new file mode 100644 index 0000000..4d67807 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/branch/community-teaching/singlehtml/_static/documentation_options.js b/branch/community-teaching/singlehtml/_static/documentation_options.js new file mode 100644 index 0000000..89003c6 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'singlehtml', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/branch/community-teaching/singlehtml/_static/file.png b/branch/community-teaching/singlehtml/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/file.png differ diff --git a/branch/community-teaching/singlehtml/_static/jquery.js b/branch/community-teaching/singlehtml/_static/jquery.js new file mode 100644 index 0000000..c4c6022 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!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(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=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,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).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 w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\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(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.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,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){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 H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.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--)b.attrHandle[n[r]]=t}function pe(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 de(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 d=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")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.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}},b.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[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.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},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),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(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.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},j=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)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(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==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(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?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{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 G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.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("(^|"+M+")"+e+"("+M+"|$)"))&&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:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.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 S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(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").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.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),m(t)&&(t=t.call(e,n,S.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)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.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"===S.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"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.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)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.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?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.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)}}),S.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){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/community-teaching/singlehtml/_static/js/html5shiv.min.js b/branch/community-teaching/singlehtml/_static/js/html5shiv.min.js new file mode 100644 index 0000000..cd1c674 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/community-teaching/singlehtml/_static/js/theme.js b/branch/community-teaching/singlehtml/_static/js/theme.js new file mode 100644 index 0000000..1fddb6e --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/branch/community-teaching/singlehtml/_static/minipres.js b/branch/community-teaching/singlehtml/_static/minipres.js new file mode 100644 index 0000000..ad11c87 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/minipres.js @@ -0,0 +1,223 @@ +// Add goTo method to elements +// http://stackoverflow.com/questions/4801655/how-to-go-to-a-specific-element-on-page +(function($) { + $.fn.goTo = function() { + $('html, body').animate({ + scrollTop: $(this).offset().top //+ 'px' + }, 'fast'); + return this; // for chaining... + } +})(jQuery); + +// NO good way to do this!. Copy a hack from here +// https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript +// https://stackoverflow.com/a/2880929 +var urlParams; +(window.onpopstate = function () { + var match, + pl = /\+/g, // Regex for replacing addition symbol with a space + search = /([^&=]+)=?([^&]*)/g, + decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, + query = window.location.search.substring(1); + urlParams = {}; + while (match = search.exec(query)) + urlParams[decode(match[1])] = decode(match[2]); +})(); + +// Select heading levels +var maxHeading = urlParams['h'] +if (maxHeading === undefined) maxHeading = 2 +var headingLevels = []; +for (h=2 ; h (sections.length-1) ) { + // if we would scroll past bottom, or above top, do nothing + return; + } + + console.log('xxxxxx'); + var targetSection = sections[targetPos]; + console.log(targetSection, typeof(targetSection)); + + // Return targetSection top and height + var secProperties = section_top_and_height(targetSection); + var top = secProperties['top']; + var height = secProperties['height'] + var win_height = window.innerHeight; + //console.info(top, height, win_height) + + var scroll_to = 0; + if (height >= win_height || height == 0) { + scroll_to = top; + } else { + scroll_to = top - (win_height-height)/3.; + } + //console.info(top, height, win_height, scroll_to) + + $('html, body').animate({ + scrollTop: scroll_to //+ 'px' + }, 'fast'); + +} + + +function minipres() { + /* Enable the minipres mode: + - call the hide() function + - set up the scrolling listener + */ + document.addEventListener('keydown', function (event) { + switch(event.which) { + case 37: // left + switch_slide(-1); + event.preventDefault(); + return false; + break; + //case 38: // up + case 39: // right + switch_slide(+1); + event.preventDefault(); + return false; + break; + //case 40: // down + default: + return; // exit this handler for other keys + } + }, true) + + hide() + + // Increase space between sections + //$("div .section").css('margin-bottom', '50%'); + $(sectionSelector).css('margin-top', '50%'); + + // Reduce size/color of other sections + if (hiddenSectionSelector.length > 0) { + var hideNodes = $(hiddenSectionSelector); + console.log(typeof hideNodes, hideNodes); + for (node in hideNodes) { + console.log("a", typeof node, node); + node = hideNodes[node]; // what's right way to iterate values? + console.log("b", typeof node, node); + if (node.parentNode && node.parentNode.className == "section") { + node = node.parentNode; + console.log("c", typeof node, node); + //node.css['transform'] = 'scale(.5)'; + //node.css['transform-origin'] = 'top center'; + $(node).css('color', 'lightgrey'); + //$(node).css('font-size', '20%'); + //$(node).css('visibility', 'collapse'); + //ntahousnatouhasno; + } + } + } +} + +function hide() { + /* Hide all non-essential elements on the page + */ + + // This is for sphinx_rst_theme and readthedocs + $(".wy-nav-side").remove(); + $(".wy-nav-content-wrap").css('margin-left', 0); + $('.rst-versions').remove(); // readthedocs version selector + + // Add other formats here. +} + + +var slideshow = minipres; + +if (window.location.search.match(/[?&](minipres|slideshow|pres)([=&]|$)/) ) { + //minipres() + window.addEventListener("load", minipres); +} else if (window.location.search.match(/[?&](plain)([=&]|$)/) ) { + window.addEventListener("load", hide); +} diff --git a/branch/community-teaching/singlehtml/_static/minus.png b/branch/community-teaching/singlehtml/_static/minus.png new file mode 100644 index 0000000..d96755f Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/minus.png differ diff --git a/branch/community-teaching/singlehtml/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css b/branch/community-teaching/singlehtml/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css new file mode 100644 index 0000000..3356631 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css @@ -0,0 +1,2342 @@ +/* Variables */ +:root { + --mystnb-source-bg-color: #f7f7f7; + --mystnb-stdout-bg-color: #fcfcfc; + --mystnb-stderr-bg-color: #fdd; + --mystnb-traceback-bg-color: #fcfcfc; + --mystnb-source-border-color: #ccc; + --mystnb-source-margin-color: green; + --mystnb-stdout-border-color: #f7f7f7; + --mystnb-stderr-border-color: #f7f7f7; + --mystnb-traceback-border-color: #ffd6d6; + --mystnb-hide-prompt-opacity: 70%; + --mystnb-source-border-radius: .4em; + --mystnb-source-border-width: 1px; +} + +/* Whole cell */ +div.container.cell { + padding-left: 0; + margin-bottom: 1em; +} + +/* Removing all background formatting so we can control at the div level */ +.cell_input div.highlight, +.cell_output pre, +.cell_input pre, +.cell_output .output { + border: none; + box-shadow: none; +} + +.cell_output .output pre, +.cell_input pre { + margin: 0px; +} + +/* Input cells */ +div.cell div.cell_input, +div.cell details.above-input>summary { + padding-left: 0em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + background-color: var(--mystnb-source-bg-color); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; + border-radius: var(--mystnb-source-border-radius); +} + +div.cell_input>div, +div.cell_output div.output>div.highlight { + margin: 0em !important; + border: none !important; +} + +/* All cell outputs */ +.cell_output { + padding-left: 1em; + padding-right: 0em; + margin-top: 1em; +} + +/* Text outputs from cells */ +.cell_output .output.text_plain, +.cell_output .output.traceback, +.cell_output .output.stream, +.cell_output .output.stderr { + margin-top: 1em; + margin-bottom: 0em; + box-shadow: none; +} + +.cell_output .output.text_plain, +.cell_output .output.stream { + background: var(--mystnb-stdout-bg-color); + border: 1px solid var(--mystnb-stdout-border-color); +} + +.cell_output .output.stderr { + background: var(--mystnb-stderr-bg-color); + border: 1px solid var(--mystnb-stderr-border-color); +} + +.cell_output .output.traceback { + background: var(--mystnb-traceback-bg-color); + border: 1px solid var(--mystnb-traceback-border-color); +} + +/* Collapsible cell content */ +div.cell details.above-input div.cell_input { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-top: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; +} + +div.cell div.cell_input.above-output-prompt { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +div.cell details.above-input>summary { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; + padding-left: 1em; + margin-bottom: 0; +} + +div.cell details.above-output>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.below-input>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-top: none; + border-bottom-left-radius: var(--mystnb-source-border-radius); + border-bottom-right-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.hide>summary>span { + opacity: var(--mystnb-hide-prompt-opacity); +} + +div.cell details.hide[open]>summary>span.collapsed { + display: none; +} + +div.cell details.hide:not([open])>summary>span.expanded { + display: none; +} + +@keyframes collapsed-fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} +div.cell details.hide[open]>summary~* { + -moz-animation: collapsed-fade-in 0.3s ease-in-out; + -webkit-animation: collapsed-fade-in 0.3s ease-in-out; + animation: collapsed-fade-in 0.3s ease-in-out; +} + +/* Math align to the left */ +.cell_output .MathJax_Display { + text-align: left !important; +} + +/* Pandas tables. Pulled from the Jupyter / nbsphinx CSS */ +div.cell_output table { + border: none; + border-collapse: collapse; + border-spacing: 0; + color: black; + font-size: 1em; + table-layout: fixed; +} + +div.cell_output thead { + border-bottom: 1px solid black; + vertical-align: bottom; +} + +div.cell_output tr, +div.cell_output th, +div.cell_output td { + text-align: right; + vertical-align: middle; + padding: 0.5em 0.5em; + line-height: normal; + white-space: normal; + max-width: none; + border: none; +} + +div.cell_output th { + font-weight: bold; +} + +div.cell_output tbody tr:nth-child(odd) { + background: #f5f5f5; +} + +div.cell_output tbody tr:hover { + background: rgba(66, 165, 245, 0.2); +} + +/** source code line numbers **/ +span.linenos { + opacity: 0.5; +} + +/* Inline text from `paste` operation */ + +span.pasted-text { + font-weight: bold; +} + +span.pasted-inline img { + max-height: 2em; +} + +tbody span.pasted-inline img { + max-height: none; +} + +/* Font colors for translated ANSI escape sequences +Color values are copied from Jupyter Notebook +https://github.com/jupyter/notebook/blob/52581f8eda9b319eb0390ac77fe5903c38f81e3e/notebook/static/notebook/less/ansicolors.less#L14-L21 +Background colors from +https://nbsphinx.readthedocs.io/en/latest/code-cells.html#ANSI-Colors +*/ +div.highlight .-Color-Bold { + font-weight: bold; +} + +div.highlight .-Color[class*=-Black] { + color: #3E424D +} + +div.highlight .-Color[class*=-Red] { + color: #E75C58 +} + +div.highlight .-Color[class*=-Green] { + color: #00A250 +} + +div.highlight .-Color[class*=-Yellow] { + color: #DDB62B +} + +div.highlight .-Color[class*=-Blue] { + color: #208FFB +} + +div.highlight .-Color[class*=-Magenta] { + color: #D160C4 +} + +div.highlight .-Color[class*=-Cyan] { + color: #60C6C8 +} + +div.highlight .-Color[class*=-White] { + color: #C5C1B4 +} + +div.highlight .-Color[class*=-BGBlack] { + background-color: #3E424D +} + +div.highlight .-Color[class*=-BGRed] { + background-color: #E75C58 +} + +div.highlight .-Color[class*=-BGGreen] { + background-color: #00A250 +} + +div.highlight .-Color[class*=-BGYellow] { + background-color: #DDB62B +} + +div.highlight .-Color[class*=-BGBlue] { + background-color: #208FFB +} + +div.highlight .-Color[class*=-BGMagenta] { + background-color: #D160C4 +} + +div.highlight .-Color[class*=-BGCyan] { + background-color: #60C6C8 +} + +div.highlight .-Color[class*=-BGWhite] { + background-color: #C5C1B4 +} + +/* Font colors for 8-bit ANSI */ + +div.highlight .-Color[class*=-C0] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC0] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C1] { + color: #800000 +} + +div.highlight .-Color[class*=-BGC1] { + background-color: #800000 +} + +div.highlight .-Color[class*=-C2] { + color: #008000 +} + +div.highlight .-Color[class*=-BGC2] { + background-color: #008000 +} + +div.highlight .-Color[class*=-C3] { + color: #808000 +} + +div.highlight .-Color[class*=-BGC3] { + background-color: #808000 +} + +div.highlight .-Color[class*=-C4] { + color: #000080 +} + +div.highlight .-Color[class*=-BGC4] { + background-color: #000080 +} + +div.highlight .-Color[class*=-C5] { + color: #800080 +} + +div.highlight .-Color[class*=-BGC5] { + background-color: #800080 +} + +div.highlight .-Color[class*=-C6] { + color: #008080 +} + +div.highlight .-Color[class*=-BGC6] { + background-color: #008080 +} + +div.highlight .-Color[class*=-C7] { + color: #C0C0C0 +} + +div.highlight .-Color[class*=-BGC7] { + background-color: #C0C0C0 +} + +div.highlight .-Color[class*=-C8] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC8] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C9] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC9] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C10] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC10] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C11] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC11] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C12] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC12] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C13] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC13] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C14] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC14] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C15] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC15] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C16] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC16] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C17] { + color: #00005F +} + +div.highlight .-Color[class*=-BGC17] { + background-color: #00005F +} + +div.highlight .-Color[class*=-C18] { + color: #000087 +} + +div.highlight .-Color[class*=-BGC18] { + background-color: #000087 +} + +div.highlight .-Color[class*=-C19] { + color: #0000AF +} + +div.highlight .-Color[class*=-BGC19] { + background-color: #0000AF +} + +div.highlight .-Color[class*=-C20] { + color: #0000D7 +} + +div.highlight .-Color[class*=-BGC20] { + background-color: #0000D7 +} + +div.highlight .-Color[class*=-C21] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC21] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C22] { + color: #005F00 +} + +div.highlight .-Color[class*=-BGC22] { + background-color: #005F00 +} + +div.highlight .-Color[class*=-C23] { + color: #005F5F +} + +div.highlight .-Color[class*=-BGC23] { + background-color: #005F5F +} + +div.highlight .-Color[class*=-C24] { + color: #005F87 +} + +div.highlight .-Color[class*=-BGC24] { + background-color: #005F87 +} + +div.highlight .-Color[class*=-C25] { + color: #005FAF +} + +div.highlight .-Color[class*=-BGC25] { + background-color: #005FAF +} + +div.highlight .-Color[class*=-C26] { + color: #005FD7 +} + +div.highlight .-Color[class*=-BGC26] { + background-color: #005FD7 +} + +div.highlight .-Color[class*=-C27] { + color: #005FFF +} + +div.highlight .-Color[class*=-BGC27] { + background-color: #005FFF +} + +div.highlight .-Color[class*=-C28] { + color: #008700 +} + +div.highlight .-Color[class*=-BGC28] { + background-color: #008700 +} + +div.highlight .-Color[class*=-C29] { + color: #00875F +} + +div.highlight .-Color[class*=-BGC29] { + background-color: #00875F +} + +div.highlight .-Color[class*=-C30] { + color: #008787 +} + +div.highlight .-Color[class*=-BGC30] { + background-color: #008787 +} + +div.highlight .-Color[class*=-C31] { + color: #0087AF +} + +div.highlight .-Color[class*=-BGC31] { + background-color: #0087AF +} + +div.highlight .-Color[class*=-C32] { + color: #0087D7 +} + +div.highlight .-Color[class*=-BGC32] { + background-color: #0087D7 +} + +div.highlight .-Color[class*=-C33] { + color: #0087FF +} + +div.highlight .-Color[class*=-BGC33] { + background-color: #0087FF +} + +div.highlight .-Color[class*=-C34] { + color: #00AF00 +} + +div.highlight .-Color[class*=-BGC34] { + background-color: #00AF00 +} + +div.highlight .-Color[class*=-C35] { + color: #00AF5F +} + +div.highlight .-Color[class*=-BGC35] { + background-color: #00AF5F +} + +div.highlight .-Color[class*=-C36] { + color: #00AF87 +} + +div.highlight .-Color[class*=-BGC36] { + background-color: #00AF87 +} + +div.highlight .-Color[class*=-C37] { + color: #00AFAF +} + +div.highlight .-Color[class*=-BGC37] { + background-color: #00AFAF +} + +div.highlight .-Color[class*=-C38] { + color: #00AFD7 +} + +div.highlight .-Color[class*=-BGC38] { + background-color: #00AFD7 +} + +div.highlight .-Color[class*=-C39] { + color: #00AFFF +} + +div.highlight .-Color[class*=-BGC39] { + background-color: #00AFFF +} + +div.highlight .-Color[class*=-C40] { + color: #00D700 +} + +div.highlight .-Color[class*=-BGC40] { + background-color: #00D700 +} + +div.highlight .-Color[class*=-C41] { + color: #00D75F +} + +div.highlight .-Color[class*=-BGC41] { + background-color: #00D75F +} + +div.highlight .-Color[class*=-C42] { + color: #00D787 +} + +div.highlight .-Color[class*=-BGC42] { + background-color: #00D787 +} + +div.highlight .-Color[class*=-C43] { + color: #00D7AF +} + +div.highlight .-Color[class*=-BGC43] { + background-color: #00D7AF +} + +div.highlight .-Color[class*=-C44] { + color: #00D7D7 +} + +div.highlight .-Color[class*=-BGC44] { + background-color: #00D7D7 +} + +div.highlight .-Color[class*=-C45] { + color: #00D7FF +} + +div.highlight .-Color[class*=-BGC45] { + background-color: #00D7FF +} + +div.highlight .-Color[class*=-C46] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC46] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C47] { + color: #00FF5F +} + +div.highlight .-Color[class*=-BGC47] { + background-color: #00FF5F +} + +div.highlight .-Color[class*=-C48] { + color: #00FF87 +} + +div.highlight .-Color[class*=-BGC48] { + background-color: #00FF87 +} + +div.highlight .-Color[class*=-C49] { + color: #00FFAF +} + +div.highlight .-Color[class*=-BGC49] { + background-color: #00FFAF +} + +div.highlight .-Color[class*=-C50] { + color: #00FFD7 +} + +div.highlight .-Color[class*=-BGC50] { + background-color: #00FFD7 +} + +div.highlight .-Color[class*=-C51] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC51] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C52] { + color: #5F0000 +} + +div.highlight .-Color[class*=-BGC52] { + background-color: #5F0000 +} + +div.highlight .-Color[class*=-C53] { + color: #5F005F +} + +div.highlight .-Color[class*=-BGC53] { + background-color: #5F005F +} + +div.highlight .-Color[class*=-C54] { + color: #5F0087 +} + +div.highlight .-Color[class*=-BGC54] { + background-color: #5F0087 +} + +div.highlight .-Color[class*=-C55] { + color: #5F00AF +} + +div.highlight .-Color[class*=-BGC55] { + background-color: #5F00AF +} + +div.highlight .-Color[class*=-C56] { + color: #5F00D7 +} + +div.highlight .-Color[class*=-BGC56] { + background-color: #5F00D7 +} + +div.highlight .-Color[class*=-C57] { + color: #5F00FF +} + +div.highlight .-Color[class*=-BGC57] { + background-color: #5F00FF +} + +div.highlight .-Color[class*=-C58] { + color: #5F5F00 +} + +div.highlight .-Color[class*=-BGC58] { + background-color: #5F5F00 +} + +div.highlight .-Color[class*=-C59] { + color: #5F5F5F +} + +div.highlight .-Color[class*=-BGC59] { + background-color: #5F5F5F +} + +div.highlight .-Color[class*=-C60] { + color: #5F5F87 +} + +div.highlight .-Color[class*=-BGC60] { + background-color: #5F5F87 +} + +div.highlight .-Color[class*=-C61] { + color: #5F5FAF +} + +div.highlight .-Color[class*=-BGC61] { + background-color: #5F5FAF +} + +div.highlight .-Color[class*=-C62] { + color: #5F5FD7 +} + +div.highlight .-Color[class*=-BGC62] { + background-color: #5F5FD7 +} + +div.highlight .-Color[class*=-C63] { + color: #5F5FFF +} + +div.highlight .-Color[class*=-BGC63] { + background-color: #5F5FFF +} + +div.highlight .-Color[class*=-C64] { + color: #5F8700 +} + +div.highlight .-Color[class*=-BGC64] { + background-color: #5F8700 +} + +div.highlight .-Color[class*=-C65] { + color: #5F875F +} + +div.highlight .-Color[class*=-BGC65] { + background-color: #5F875F +} + +div.highlight .-Color[class*=-C66] { + color: #5F8787 +} + +div.highlight .-Color[class*=-BGC66] { + background-color: #5F8787 +} + +div.highlight .-Color[class*=-C67] { + color: #5F87AF +} + +div.highlight .-Color[class*=-BGC67] { + background-color: #5F87AF +} + +div.highlight .-Color[class*=-C68] { + color: #5F87D7 +} + +div.highlight .-Color[class*=-BGC68] { + background-color: #5F87D7 +} + +div.highlight .-Color[class*=-C69] { + color: #5F87FF +} + +div.highlight .-Color[class*=-BGC69] { + background-color: #5F87FF +} + +div.highlight .-Color[class*=-C70] { + color: #5FAF00 +} + +div.highlight .-Color[class*=-BGC70] { + background-color: #5FAF00 +} + +div.highlight .-Color[class*=-C71] { + color: #5FAF5F +} + +div.highlight .-Color[class*=-BGC71] { + background-color: #5FAF5F +} + +div.highlight .-Color[class*=-C72] { + color: #5FAF87 +} + +div.highlight .-Color[class*=-BGC72] { + background-color: #5FAF87 +} + +div.highlight .-Color[class*=-C73] { + color: #5FAFAF +} + +div.highlight .-Color[class*=-BGC73] { + background-color: #5FAFAF +} + +div.highlight .-Color[class*=-C74] { + color: #5FAFD7 +} + +div.highlight .-Color[class*=-BGC74] { + background-color: #5FAFD7 +} + +div.highlight .-Color[class*=-C75] { + color: #5FAFFF +} + +div.highlight .-Color[class*=-BGC75] { + background-color: #5FAFFF +} + +div.highlight .-Color[class*=-C76] { + color: #5FD700 +} + +div.highlight .-Color[class*=-BGC76] { + background-color: #5FD700 +} + +div.highlight .-Color[class*=-C77] { + color: #5FD75F +} + +div.highlight .-Color[class*=-BGC77] { + background-color: #5FD75F +} + +div.highlight .-Color[class*=-C78] { + color: #5FD787 +} + +div.highlight .-Color[class*=-BGC78] { + background-color: #5FD787 +} + +div.highlight .-Color[class*=-C79] { + color: #5FD7AF +} + +div.highlight .-Color[class*=-BGC79] { + background-color: #5FD7AF +} + +div.highlight .-Color[class*=-C80] { + color: #5FD7D7 +} + +div.highlight .-Color[class*=-BGC80] { + background-color: #5FD7D7 +} + +div.highlight .-Color[class*=-C81] { + color: #5FD7FF +} + +div.highlight .-Color[class*=-BGC81] { + background-color: #5FD7FF +} + +div.highlight .-Color[class*=-C82] { + color: #5FFF00 +} + +div.highlight .-Color[class*=-BGC82] { + background-color: #5FFF00 +} + +div.highlight .-Color[class*=-C83] { + color: #5FFF5F +} + +div.highlight .-Color[class*=-BGC83] { + background-color: #5FFF5F +} + +div.highlight .-Color[class*=-C84] { + color: #5FFF87 +} + +div.highlight .-Color[class*=-BGC84] { + background-color: #5FFF87 +} + +div.highlight .-Color[class*=-C85] { + color: #5FFFAF +} + +div.highlight .-Color[class*=-BGC85] { + background-color: #5FFFAF +} + +div.highlight .-Color[class*=-C86] { + color: #5FFFD7 +} + +div.highlight .-Color[class*=-BGC86] { + background-color: #5FFFD7 +} + +div.highlight .-Color[class*=-C87] { + color: #5FFFFF +} + +div.highlight .-Color[class*=-BGC87] { + background-color: #5FFFFF +} + +div.highlight .-Color[class*=-C88] { + color: #870000 +} + +div.highlight .-Color[class*=-BGC88] { + background-color: #870000 +} + +div.highlight .-Color[class*=-C89] { + color: #87005F +} + +div.highlight .-Color[class*=-BGC89] { + background-color: #87005F +} + +div.highlight .-Color[class*=-C90] { + color: #870087 +} + +div.highlight .-Color[class*=-BGC90] { + background-color: #870087 +} + +div.highlight .-Color[class*=-C91] { + color: #8700AF +} + +div.highlight .-Color[class*=-BGC91] { + background-color: #8700AF +} + +div.highlight .-Color[class*=-C92] { + color: #8700D7 +} + +div.highlight .-Color[class*=-BGC92] { + background-color: #8700D7 +} + +div.highlight .-Color[class*=-C93] { + color: #8700FF +} + +div.highlight .-Color[class*=-BGC93] { + background-color: #8700FF +} + +div.highlight .-Color[class*=-C94] { + color: #875F00 +} + +div.highlight .-Color[class*=-BGC94] { + background-color: #875F00 +} + +div.highlight .-Color[class*=-C95] { + color: #875F5F +} + +div.highlight .-Color[class*=-BGC95] { + background-color: #875F5F +} + +div.highlight .-Color[class*=-C96] { + color: #875F87 +} + +div.highlight .-Color[class*=-BGC96] { + background-color: #875F87 +} + +div.highlight .-Color[class*=-C97] { + color: #875FAF +} + +div.highlight .-Color[class*=-BGC97] { + background-color: #875FAF +} + +div.highlight .-Color[class*=-C98] { + color: #875FD7 +} + +div.highlight .-Color[class*=-BGC98] { + background-color: #875FD7 +} + +div.highlight .-Color[class*=-C99] { + color: #875FFF +} + +div.highlight .-Color[class*=-BGC99] { + background-color: #875FFF +} + +div.highlight .-Color[class*=-C100] { + color: #878700 +} + +div.highlight .-Color[class*=-BGC100] { + background-color: #878700 +} + +div.highlight .-Color[class*=-C101] { + color: #87875F +} + +div.highlight .-Color[class*=-BGC101] { + background-color: #87875F +} + +div.highlight .-Color[class*=-C102] { + color: #878787 +} + +div.highlight .-Color[class*=-BGC102] { + background-color: #878787 +} + +div.highlight .-Color[class*=-C103] { + color: #8787AF +} + +div.highlight .-Color[class*=-BGC103] { + background-color: #8787AF +} + +div.highlight .-Color[class*=-C104] { + color: #8787D7 +} + +div.highlight .-Color[class*=-BGC104] { + background-color: #8787D7 +} + +div.highlight .-Color[class*=-C105] { + color: #8787FF +} + +div.highlight .-Color[class*=-BGC105] { + background-color: #8787FF +} + +div.highlight .-Color[class*=-C106] { + color: #87AF00 +} + +div.highlight .-Color[class*=-BGC106] { + background-color: #87AF00 +} + +div.highlight .-Color[class*=-C107] { + color: #87AF5F +} + +div.highlight .-Color[class*=-BGC107] { + background-color: #87AF5F +} + +div.highlight .-Color[class*=-C108] { + color: #87AF87 +} + +div.highlight .-Color[class*=-BGC108] { + background-color: #87AF87 +} + +div.highlight .-Color[class*=-C109] { + color: #87AFAF +} + +div.highlight .-Color[class*=-BGC109] { + background-color: #87AFAF +} + +div.highlight .-Color[class*=-C110] { + color: #87AFD7 +} + +div.highlight .-Color[class*=-BGC110] { + background-color: #87AFD7 +} + +div.highlight .-Color[class*=-C111] { + color: #87AFFF +} + +div.highlight .-Color[class*=-BGC111] { + background-color: #87AFFF +} + +div.highlight .-Color[class*=-C112] { + color: #87D700 +} + +div.highlight .-Color[class*=-BGC112] { + background-color: #87D700 +} + +div.highlight .-Color[class*=-C113] { + color: #87D75F +} + +div.highlight .-Color[class*=-BGC113] { + background-color: #87D75F +} + +div.highlight .-Color[class*=-C114] { + color: #87D787 +} + +div.highlight .-Color[class*=-BGC114] { + background-color: #87D787 +} + +div.highlight .-Color[class*=-C115] { + color: #87D7AF +} + +div.highlight .-Color[class*=-BGC115] { + background-color: #87D7AF +} + +div.highlight .-Color[class*=-C116] { + color: #87D7D7 +} + +div.highlight .-Color[class*=-BGC116] { + background-color: #87D7D7 +} + +div.highlight .-Color[class*=-C117] { + color: #87D7FF +} + +div.highlight .-Color[class*=-BGC117] { + background-color: #87D7FF +} + +div.highlight .-Color[class*=-C118] { + color: #87FF00 +} + +div.highlight .-Color[class*=-BGC118] { + background-color: #87FF00 +} + +div.highlight .-Color[class*=-C119] { + color: #87FF5F +} + +div.highlight .-Color[class*=-BGC119] { + background-color: #87FF5F +} + +div.highlight .-Color[class*=-C120] { + color: #87FF87 +} + +div.highlight .-Color[class*=-BGC120] { + background-color: #87FF87 +} + +div.highlight .-Color[class*=-C121] { + color: #87FFAF +} + +div.highlight .-Color[class*=-BGC121] { + background-color: #87FFAF +} + +div.highlight .-Color[class*=-C122] { + color: #87FFD7 +} + +div.highlight .-Color[class*=-BGC122] { + background-color: #87FFD7 +} + +div.highlight .-Color[class*=-C123] { + color: #87FFFF +} + +div.highlight .-Color[class*=-BGC123] { + background-color: #87FFFF +} + +div.highlight .-Color[class*=-C124] { + color: #AF0000 +} + +div.highlight .-Color[class*=-BGC124] { + background-color: #AF0000 +} + +div.highlight .-Color[class*=-C125] { + color: #AF005F +} + +div.highlight .-Color[class*=-BGC125] { + background-color: #AF005F +} + +div.highlight .-Color[class*=-C126] { + color: #AF0087 +} + +div.highlight .-Color[class*=-BGC126] { + background-color: #AF0087 +} + +div.highlight .-Color[class*=-C127] { + color: #AF00AF +} + +div.highlight .-Color[class*=-BGC127] { + background-color: #AF00AF +} + +div.highlight .-Color[class*=-C128] { + color: #AF00D7 +} + +div.highlight .-Color[class*=-BGC128] { + background-color: #AF00D7 +} + +div.highlight .-Color[class*=-C129] { + color: #AF00FF +} + +div.highlight .-Color[class*=-BGC129] { + background-color: #AF00FF +} + +div.highlight .-Color[class*=-C130] { + color: #AF5F00 +} + +div.highlight .-Color[class*=-BGC130] { + background-color: #AF5F00 +} + +div.highlight .-Color[class*=-C131] { + color: #AF5F5F +} + +div.highlight .-Color[class*=-BGC131] { + background-color: #AF5F5F +} + +div.highlight .-Color[class*=-C132] { + color: #AF5F87 +} + +div.highlight .-Color[class*=-BGC132] { + background-color: #AF5F87 +} + +div.highlight .-Color[class*=-C133] { + color: #AF5FAF +} + +div.highlight .-Color[class*=-BGC133] { + background-color: #AF5FAF +} + +div.highlight .-Color[class*=-C134] { + color: #AF5FD7 +} + +div.highlight .-Color[class*=-BGC134] { + background-color: #AF5FD7 +} + +div.highlight .-Color[class*=-C135] { + color: #AF5FFF +} + +div.highlight .-Color[class*=-BGC135] { + background-color: #AF5FFF +} + +div.highlight .-Color[class*=-C136] { + color: #AF8700 +} + +div.highlight .-Color[class*=-BGC136] { + background-color: #AF8700 +} + +div.highlight .-Color[class*=-C137] { + color: #AF875F +} + +div.highlight .-Color[class*=-BGC137] { + background-color: #AF875F +} + +div.highlight .-Color[class*=-C138] { + color: #AF8787 +} + +div.highlight .-Color[class*=-BGC138] { + background-color: #AF8787 +} + +div.highlight .-Color[class*=-C139] { + color: #AF87AF +} + +div.highlight .-Color[class*=-BGC139] { + background-color: #AF87AF +} + +div.highlight .-Color[class*=-C140] { + color: #AF87D7 +} + +div.highlight .-Color[class*=-BGC140] { + background-color: #AF87D7 +} + +div.highlight .-Color[class*=-C141] { + color: #AF87FF +} + +div.highlight .-Color[class*=-BGC141] { + background-color: #AF87FF +} + +div.highlight .-Color[class*=-C142] { + color: #AFAF00 +} + +div.highlight .-Color[class*=-BGC142] { + background-color: #AFAF00 +} + +div.highlight .-Color[class*=-C143] { + color: #AFAF5F +} + +div.highlight .-Color[class*=-BGC143] { + background-color: #AFAF5F +} + +div.highlight .-Color[class*=-C144] { + color: #AFAF87 +} + +div.highlight .-Color[class*=-BGC144] { + background-color: #AFAF87 +} + +div.highlight .-Color[class*=-C145] { + color: #AFAFAF +} + +div.highlight .-Color[class*=-BGC145] { + background-color: #AFAFAF +} + +div.highlight .-Color[class*=-C146] { + color: #AFAFD7 +} + +div.highlight .-Color[class*=-BGC146] { + background-color: #AFAFD7 +} + +div.highlight .-Color[class*=-C147] { + color: #AFAFFF +} + +div.highlight .-Color[class*=-BGC147] { + background-color: #AFAFFF +} + +div.highlight .-Color[class*=-C148] { + color: #AFD700 +} + +div.highlight .-Color[class*=-BGC148] { + background-color: #AFD700 +} + +div.highlight .-Color[class*=-C149] { + color: #AFD75F +} + +div.highlight .-Color[class*=-BGC149] { + background-color: #AFD75F +} + +div.highlight .-Color[class*=-C150] { + color: #AFD787 +} + +div.highlight .-Color[class*=-BGC150] { + background-color: #AFD787 +} + +div.highlight .-Color[class*=-C151] { + color: #AFD7AF +} + +div.highlight .-Color[class*=-BGC151] { + background-color: #AFD7AF +} + +div.highlight .-Color[class*=-C152] { + color: #AFD7D7 +} + +div.highlight .-Color[class*=-BGC152] { + background-color: #AFD7D7 +} + +div.highlight .-Color[class*=-C153] { + color: #AFD7FF +} + +div.highlight .-Color[class*=-BGC153] { + background-color: #AFD7FF +} + +div.highlight .-Color[class*=-C154] { + color: #AFFF00 +} + +div.highlight .-Color[class*=-BGC154] { + background-color: #AFFF00 +} + +div.highlight .-Color[class*=-C155] { + color: #AFFF5F +} + +div.highlight .-Color[class*=-BGC155] { + background-color: #AFFF5F +} + +div.highlight .-Color[class*=-C156] { + color: #AFFF87 +} + +div.highlight .-Color[class*=-BGC156] { + background-color: #AFFF87 +} + +div.highlight .-Color[class*=-C157] { + color: #AFFFAF +} + +div.highlight .-Color[class*=-BGC157] { + background-color: #AFFFAF +} + +div.highlight .-Color[class*=-C158] { + color: #AFFFD7 +} + +div.highlight .-Color[class*=-BGC158] { + background-color: #AFFFD7 +} + +div.highlight .-Color[class*=-C159] { + color: #AFFFFF +} + +div.highlight .-Color[class*=-BGC159] { + background-color: #AFFFFF +} + +div.highlight .-Color[class*=-C160] { + color: #D70000 +} + +div.highlight .-Color[class*=-BGC160] { + background-color: #D70000 +} + +div.highlight .-Color[class*=-C161] { + color: #D7005F +} + +div.highlight .-Color[class*=-BGC161] { + background-color: #D7005F +} + +div.highlight .-Color[class*=-C162] { + color: #D70087 +} + +div.highlight .-Color[class*=-BGC162] { + background-color: #D70087 +} + +div.highlight .-Color[class*=-C163] { + color: #D700AF +} + +div.highlight .-Color[class*=-BGC163] { + background-color: #D700AF +} + +div.highlight .-Color[class*=-C164] { + color: #D700D7 +} + +div.highlight .-Color[class*=-BGC164] { + background-color: #D700D7 +} + +div.highlight .-Color[class*=-C165] { + color: #D700FF +} + +div.highlight .-Color[class*=-BGC165] { + background-color: #D700FF +} + +div.highlight .-Color[class*=-C166] { + color: #D75F00 +} + +div.highlight .-Color[class*=-BGC166] { + background-color: #D75F00 +} + +div.highlight .-Color[class*=-C167] { + color: #D75F5F +} + +div.highlight .-Color[class*=-BGC167] { + background-color: #D75F5F +} + +div.highlight .-Color[class*=-C168] { + color: #D75F87 +} + +div.highlight .-Color[class*=-BGC168] { + background-color: #D75F87 +} + +div.highlight .-Color[class*=-C169] { + color: #D75FAF +} + +div.highlight .-Color[class*=-BGC169] { + background-color: #D75FAF +} + +div.highlight .-Color[class*=-C170] { + color: #D75FD7 +} + +div.highlight .-Color[class*=-BGC170] { + background-color: #D75FD7 +} + +div.highlight .-Color[class*=-C171] { + color: #D75FFF +} + +div.highlight .-Color[class*=-BGC171] { + background-color: #D75FFF +} + +div.highlight .-Color[class*=-C172] { + color: #D78700 +} + +div.highlight .-Color[class*=-BGC172] { + background-color: #D78700 +} + +div.highlight .-Color[class*=-C173] { + color: #D7875F +} + +div.highlight .-Color[class*=-BGC173] { + background-color: #D7875F +} + +div.highlight .-Color[class*=-C174] { + color: #D78787 +} + +div.highlight .-Color[class*=-BGC174] { + background-color: #D78787 +} + +div.highlight .-Color[class*=-C175] { + color: #D787AF +} + +div.highlight .-Color[class*=-BGC175] { + background-color: #D787AF +} + +div.highlight .-Color[class*=-C176] { + color: #D787D7 +} + +div.highlight .-Color[class*=-BGC176] { + background-color: #D787D7 +} + +div.highlight .-Color[class*=-C177] { + color: #D787FF +} + +div.highlight .-Color[class*=-BGC177] { + background-color: #D787FF +} + +div.highlight .-Color[class*=-C178] { + color: #D7AF00 +} + +div.highlight .-Color[class*=-BGC178] { + background-color: #D7AF00 +} + +div.highlight .-Color[class*=-C179] { + color: #D7AF5F +} + +div.highlight .-Color[class*=-BGC179] { + background-color: #D7AF5F +} + +div.highlight .-Color[class*=-C180] { + color: #D7AF87 +} + +div.highlight .-Color[class*=-BGC180] { + background-color: #D7AF87 +} + +div.highlight .-Color[class*=-C181] { + color: #D7AFAF +} + +div.highlight .-Color[class*=-BGC181] { + background-color: #D7AFAF +} + +div.highlight .-Color[class*=-C182] { + color: #D7AFD7 +} + +div.highlight .-Color[class*=-BGC182] { + background-color: #D7AFD7 +} + +div.highlight .-Color[class*=-C183] { + color: #D7AFFF +} + +div.highlight .-Color[class*=-BGC183] { + background-color: #D7AFFF +} + +div.highlight .-Color[class*=-C184] { + color: #D7D700 +} + +div.highlight .-Color[class*=-BGC184] { + background-color: #D7D700 +} + +div.highlight .-Color[class*=-C185] { + color: #D7D75F +} + +div.highlight .-Color[class*=-BGC185] { + background-color: #D7D75F +} + +div.highlight .-Color[class*=-C186] { + color: #D7D787 +} + +div.highlight .-Color[class*=-BGC186] { + background-color: #D7D787 +} + +div.highlight .-Color[class*=-C187] { + color: #D7D7AF +} + +div.highlight .-Color[class*=-BGC187] { + background-color: #D7D7AF +} + +div.highlight .-Color[class*=-C188] { + color: #D7D7D7 +} + +div.highlight .-Color[class*=-BGC188] { + background-color: #D7D7D7 +} + +div.highlight .-Color[class*=-C189] { + color: #D7D7FF +} + +div.highlight .-Color[class*=-BGC189] { + background-color: #D7D7FF +} + +div.highlight .-Color[class*=-C190] { + color: #D7FF00 +} + +div.highlight .-Color[class*=-BGC190] { + background-color: #D7FF00 +} + +div.highlight .-Color[class*=-C191] { + color: #D7FF5F +} + +div.highlight .-Color[class*=-BGC191] { + background-color: #D7FF5F +} + +div.highlight .-Color[class*=-C192] { + color: #D7FF87 +} + +div.highlight .-Color[class*=-BGC192] { + background-color: #D7FF87 +} + +div.highlight .-Color[class*=-C193] { + color: #D7FFAF +} + +div.highlight .-Color[class*=-BGC193] { + background-color: #D7FFAF +} + +div.highlight .-Color[class*=-C194] { + color: #D7FFD7 +} + +div.highlight .-Color[class*=-BGC194] { + background-color: #D7FFD7 +} + +div.highlight .-Color[class*=-C195] { + color: #D7FFFF +} + +div.highlight .-Color[class*=-BGC195] { + background-color: #D7FFFF +} + +div.highlight .-Color[class*=-C196] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC196] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C197] { + color: #FF005F +} + +div.highlight .-Color[class*=-BGC197] { + background-color: #FF005F +} + +div.highlight .-Color[class*=-C198] { + color: #FF0087 +} + +div.highlight .-Color[class*=-BGC198] { + background-color: #FF0087 +} + +div.highlight .-Color[class*=-C199] { + color: #FF00AF +} + +div.highlight .-Color[class*=-BGC199] { + background-color: #FF00AF +} + +div.highlight .-Color[class*=-C200] { + color: #FF00D7 +} + +div.highlight .-Color[class*=-BGC200] { + background-color: #FF00D7 +} + +div.highlight .-Color[class*=-C201] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC201] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C202] { + color: #FF5F00 +} + +div.highlight .-Color[class*=-BGC202] { + background-color: #FF5F00 +} + +div.highlight .-Color[class*=-C203] { + color: #FF5F5F +} + +div.highlight .-Color[class*=-BGC203] { + background-color: #FF5F5F +} + +div.highlight .-Color[class*=-C204] { + color: #FF5F87 +} + +div.highlight .-Color[class*=-BGC204] { + background-color: #FF5F87 +} + +div.highlight .-Color[class*=-C205] { + color: #FF5FAF +} + +div.highlight .-Color[class*=-BGC205] { + background-color: #FF5FAF +} + +div.highlight .-Color[class*=-C206] { + color: #FF5FD7 +} + +div.highlight .-Color[class*=-BGC206] { + background-color: #FF5FD7 +} + +div.highlight .-Color[class*=-C207] { + color: #FF5FFF +} + +div.highlight .-Color[class*=-BGC207] { + background-color: #FF5FFF +} + +div.highlight .-Color[class*=-C208] { + color: #FF8700 +} + +div.highlight .-Color[class*=-BGC208] { + background-color: #FF8700 +} + +div.highlight .-Color[class*=-C209] { + color: #FF875F +} + +div.highlight .-Color[class*=-BGC209] { + background-color: #FF875F +} + +div.highlight .-Color[class*=-C210] { + color: #FF8787 +} + +div.highlight .-Color[class*=-BGC210] { + background-color: #FF8787 +} + +div.highlight .-Color[class*=-C211] { + color: #FF87AF +} + +div.highlight .-Color[class*=-BGC211] { + background-color: #FF87AF +} + +div.highlight .-Color[class*=-C212] { + color: #FF87D7 +} + +div.highlight .-Color[class*=-BGC212] { + background-color: #FF87D7 +} + +div.highlight .-Color[class*=-C213] { + color: #FF87FF +} + +div.highlight .-Color[class*=-BGC213] { + background-color: #FF87FF +} + +div.highlight .-Color[class*=-C214] { + color: #FFAF00 +} + +div.highlight .-Color[class*=-BGC214] { + background-color: #FFAF00 +} + +div.highlight .-Color[class*=-C215] { + color: #FFAF5F +} + +div.highlight .-Color[class*=-BGC215] { + background-color: #FFAF5F +} + +div.highlight .-Color[class*=-C216] { + color: #FFAF87 +} + +div.highlight .-Color[class*=-BGC216] { + background-color: #FFAF87 +} + +div.highlight .-Color[class*=-C217] { + color: #FFAFAF +} + +div.highlight .-Color[class*=-BGC217] { + background-color: #FFAFAF +} + +div.highlight .-Color[class*=-C218] { + color: #FFAFD7 +} + +div.highlight .-Color[class*=-BGC218] { + background-color: #FFAFD7 +} + +div.highlight .-Color[class*=-C219] { + color: #FFAFFF +} + +div.highlight .-Color[class*=-BGC219] { + background-color: #FFAFFF +} + +div.highlight .-Color[class*=-C220] { + color: #FFD700 +} + +div.highlight .-Color[class*=-BGC220] { + background-color: #FFD700 +} + +div.highlight .-Color[class*=-C221] { + color: #FFD75F +} + +div.highlight .-Color[class*=-BGC221] { + background-color: #FFD75F +} + +div.highlight .-Color[class*=-C222] { + color: #FFD787 +} + +div.highlight .-Color[class*=-BGC222] { + background-color: #FFD787 +} + +div.highlight .-Color[class*=-C223] { + color: #FFD7AF +} + +div.highlight .-Color[class*=-BGC223] { + background-color: #FFD7AF +} + +div.highlight .-Color[class*=-C224] { + color: #FFD7D7 +} + +div.highlight .-Color[class*=-BGC224] { + background-color: #FFD7D7 +} + +div.highlight .-Color[class*=-C225] { + color: #FFD7FF +} + +div.highlight .-Color[class*=-BGC225] { + background-color: #FFD7FF +} + +div.highlight .-Color[class*=-C226] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC226] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C227] { + color: #FFFF5F +} + +div.highlight .-Color[class*=-BGC227] { + background-color: #FFFF5F +} + +div.highlight .-Color[class*=-C228] { + color: #FFFF87 +} + +div.highlight .-Color[class*=-BGC228] { + background-color: #FFFF87 +} + +div.highlight .-Color[class*=-C229] { + color: #FFFFAF +} + +div.highlight .-Color[class*=-BGC229] { + background-color: #FFFFAF +} + +div.highlight .-Color[class*=-C230] { + color: #FFFFD7 +} + +div.highlight .-Color[class*=-BGC230] { + background-color: #FFFFD7 +} + +div.highlight .-Color[class*=-C231] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC231] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C232] { + color: #080808 +} + +div.highlight .-Color[class*=-BGC232] { + background-color: #080808 +} + +div.highlight .-Color[class*=-C233] { + color: #121212 +} + +div.highlight .-Color[class*=-BGC233] { + background-color: #121212 +} + +div.highlight .-Color[class*=-C234] { + color: #1C1C1C +} + +div.highlight .-Color[class*=-BGC234] { + background-color: #1C1C1C +} + +div.highlight .-Color[class*=-C235] { + color: #262626 +} + +div.highlight .-Color[class*=-BGC235] { + background-color: #262626 +} + +div.highlight .-Color[class*=-C236] { + color: #303030 +} + +div.highlight .-Color[class*=-BGC236] { + background-color: #303030 +} + +div.highlight .-Color[class*=-C237] { + color: #3A3A3A +} + +div.highlight .-Color[class*=-BGC237] { + background-color: #3A3A3A +} + +div.highlight .-Color[class*=-C238] { + color: #444444 +} + +div.highlight .-Color[class*=-BGC238] { + background-color: #444444 +} + +div.highlight .-Color[class*=-C239] { + color: #4E4E4E +} + +div.highlight .-Color[class*=-BGC239] { + background-color: #4E4E4E +} + +div.highlight .-Color[class*=-C240] { + color: #585858 +} + +div.highlight .-Color[class*=-BGC240] { + background-color: #585858 +} + +div.highlight .-Color[class*=-C241] { + color: #626262 +} + +div.highlight .-Color[class*=-BGC241] { + background-color: #626262 +} + +div.highlight .-Color[class*=-C242] { + color: #6C6C6C +} + +div.highlight .-Color[class*=-BGC242] { + background-color: #6C6C6C +} + +div.highlight .-Color[class*=-C243] { + color: #767676 +} + +div.highlight .-Color[class*=-BGC243] { + background-color: #767676 +} + +div.highlight .-Color[class*=-C244] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC244] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C245] { + color: #8A8A8A +} + +div.highlight .-Color[class*=-BGC245] { + background-color: #8A8A8A +} + +div.highlight .-Color[class*=-C246] { + color: #949494 +} + +div.highlight .-Color[class*=-BGC246] { + background-color: #949494 +} + +div.highlight .-Color[class*=-C247] { + color: #9E9E9E +} + +div.highlight .-Color[class*=-BGC247] { + background-color: #9E9E9E +} + +div.highlight .-Color[class*=-C248] { + color: #A8A8A8 +} + +div.highlight .-Color[class*=-BGC248] { + background-color: #A8A8A8 +} + +div.highlight .-Color[class*=-C249] { + color: #B2B2B2 +} + +div.highlight .-Color[class*=-BGC249] { + background-color: #B2B2B2 +} + +div.highlight .-Color[class*=-C250] { + color: #BCBCBC +} + +div.highlight .-Color[class*=-BGC250] { + background-color: #BCBCBC +} + +div.highlight .-Color[class*=-C251] { + color: #C6C6C6 +} + +div.highlight .-Color[class*=-BGC251] { + background-color: #C6C6C6 +} + +div.highlight .-Color[class*=-C252] { + color: #D0D0D0 +} + +div.highlight .-Color[class*=-BGC252] { + background-color: #D0D0D0 +} + +div.highlight .-Color[class*=-C253] { + color: #DADADA +} + +div.highlight .-Color[class*=-BGC253] { + background-color: #DADADA +} + +div.highlight .-Color[class*=-C254] { + color: #E4E4E4 +} + +div.highlight .-Color[class*=-BGC254] { + background-color: #E4E4E4 +} + +div.highlight .-Color[class*=-C255] { + color: #EEEEEE +} + +div.highlight .-Color[class*=-BGC255] { + background-color: #EEEEEE +} diff --git a/branch/community-teaching/singlehtml/_static/plus.png b/branch/community-teaching/singlehtml/_static/plus.png new file mode 100644 index 0000000..7107cec Binary files /dev/null and b/branch/community-teaching/singlehtml/_static/plus.png differ diff --git a/branch/community-teaching/singlehtml/_static/pygments.css b/branch/community-teaching/singlehtml/_static/pygments.css new file mode 100644 index 0000000..84ab303 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/branch/community-teaching/singlehtml/_static/searchtools.js b/branch/community-teaching/singlehtml/_static/searchtools.js new file mode 100644 index 0000000..92da3f8 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/searchtools.js @@ -0,0 +1,619 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlinks", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + let score = Math.round(100 * queryLower.length / title.length) + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/branch/community-teaching/singlehtml/_static/sphinx_highlight.js b/branch/community-teaching/singlehtml/_static/sphinx_highlight.js new file mode 100644 index 0000000..8a96c69 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/branch/community-teaching/singlehtml/_static/sphinx_lesson.css b/branch/community-teaching/singlehtml/_static/sphinx_lesson.css new file mode 100644 index 0000000..14b20c6 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/sphinx_lesson.css @@ -0,0 +1,51 @@ +/* sphinx_lesson.css */ + +body.wy-body-for-nav img.with-border { + border: 2px solid; +} + +.rst-content .admonition-no-content { + padding-bottom: 0px; +} + +.rst-content .demo > .admonition-title::before { + content: "\01F440"; /* Eyes */ } +.rst-content .type-along > .admonition-title::before { + content: "\02328\0FE0F"; /* Keyboard */ } +.rst-content .exercise > .admonition-title::before { + content: "\0270D\0FE0F"; /* Hand */ } +.rst-content .solution > .admonition-title::before { + content: "\02714\0FE0E"; /* Check mark */ } +.rst-content .homework > .admonition-title::before { + content: "\01F4DD"; /* Memo */ } +.rst-content .discussion > .admonition-title::before { + content: "\01F4AC"; /* Speech balloon */ } +.rst-content .questions > .admonition-title::before { + content: "\02753\0FE0E"; /* Question mark */ } +.rst-content .prerequisites > .admonition-title::before { + content: "\02699"; /* Gear */ } +.rst-content .seealso > .admonition-title::before { + content: "\027A1\0FE0E"; /* Question mark */ } + + +/* instructor-note */ +.rst-content .instructor-note { + background: #e7e7e7; +} +.rst-content .instructor-note > .admonition-title { + background: #6a6a6a; +} +.rst-content .instructor-note > .admonition-title::before { + content: ""; +} + + +/* sphinx_toggle_button, make the font white */ +.rst-content .toggle.admonition button.toggle-button { + color: white; +} + +/* sphinx-togglebutton, remove underflow when toggled to hidden mode */ +.rst-content .admonition.toggle-hidden { + padding-bottom: 0px; +} diff --git a/branch/community-teaching/singlehtml/_static/sphinx_rtd_theme_ext_color_contrast.css b/branch/community-teaching/singlehtml/_static/sphinx_rtd_theme_ext_color_contrast.css new file mode 100644 index 0000000..e68feb8 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/sphinx_rtd_theme_ext_color_contrast.css @@ -0,0 +1,47 @@ +/* The following are for web accessibility of sphinx_rtd_theme: they + * solve some of the most frequent contrast issues. Remove when this + * solved: + * https://github.com/readthedocs/sphinx_rtd_theme/issues/971 + */ +/* background: #fcfcfc, note boxes #E7F2FA */ +a { color: #2573A7; } /* original #2980B9, #1F5C84; */ +body { color: #242424; } /* original #404040, #383838 */ +.wy-side-nav-search>a, .wy-side-nav-search .wy-dropdown>a { + color: #ffffff; +} /* original #fcfcfc */ +footer { color: #737373; } /* original gray=#808080*/ +footer span.commit code, footer span.commit .rst-content tt, .rst-content footer span.commit tt { + color: #737373; +} /* original gray=#808080*/ +.rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal { + color: #AB2314; +} +/* Sidebar background */ +.wy-side-nav-search { background-color: #277CB4;} + +/* Same, but for pygments */ +.highlight .ch { color: #3E7A89; } /* #! line */ +.highlight .c1 { color: #3E7A89; } /* also comments */ +.highlight .nv { color: #AD3ECC; } /* variable */ +.highlight .gp { color: #B45608; } /* prompt character, $*/ +.highlight .si { color: #3975B1; } /* ${} variable text */ +.highlight .nc { color: #0C78A7; } + +/* Sphinx admonitions */ +/* warning */ +.wy-alert.wy-alert-warning .wy-alert-title, .rst-content .wy-alert-warning.note .wy-alert-title, .rst-content .attention .wy-alert-title, .rst-content .caution .wy-alert-title, .rst-content .wy-alert-warning.danger .wy-alert-title, .rst-content .wy-alert-warning.error .wy-alert-title, .rst-content .wy-alert-warning.hint .wy-alert-title, .rst-content .wy-alert-warning.important .wy-alert-title, .rst-content .wy-alert-warning.tip .wy-alert-title, .rst-content .warning .wy-alert-title, .rst-content .wy-alert-warning.seealso .wy-alert-title, .rst-content .admonition-todo .wy-alert-title, .rst-content .wy-alert-warning.admonition .wy-alert-title, .wy-alert.wy-alert-warning .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-warning .admonition-title, .rst-content .wy-alert-warning.note .admonition-title, .rst-content .attention .admonition-title, .rst-content .caution .admonition-title, .rst-content .wy-alert-warning.danger .admonition-title, .rst-content .wy-alert-warning.error .admonition-title, .rst-content .wy-alert-warning.hint .admonition-title, .rst-content .wy-alert-warning.important .admonition-title, .rst-content .wy-alert-warning.tip .admonition-title, .rst-content .warning .admonition-title, .rst-content .wy-alert-warning.seealso .admonition-title, .rst-content .admonition-todo .admonition-title, .rst-content .wy-alert-warning.admonition .admonition-title { + background: #B15E16; } +/* important */ +.wy-alert.wy-alert-success .wy-alert-title, .rst-content .wy-alert-success.note .wy-alert-title, .rst-content .wy-alert-success.attention .wy-alert-title, .rst-content .wy-alert-success.caution .wy-alert-title, .rst-content .wy-alert-success.danger .wy-alert-title, .rst-content .wy-alert-success.error .wy-alert-title, .rst-content .hint .wy-alert-title, .rst-content .important .wy-alert-title, .rst-content .tip .wy-alert-title, .rst-content .wy-alert-success.warning .wy-alert-title, .rst-content .wy-alert-success.seealso .wy-alert-title, .rst-content .wy-alert-success.admonition-todo .wy-alert-title, .rst-content .wy-alert-success.admonition .wy-alert-title, .wy-alert.wy-alert-success .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-success .admonition-title, .rst-content .wy-alert-success.note .admonition-title, .rst-content .wy-alert-success.attention .admonition-title, .rst-content .wy-alert-success.caution .admonition-title, .rst-content .wy-alert-success.danger .admonition-title, .rst-content .wy-alert-success.error .admonition-title, .rst-content .hint .admonition-title, .rst-content .important .admonition-title, .rst-content .tip .admonition-title, .rst-content .wy-alert-success.warning .admonition-title, .rst-content .wy-alert-success.seealso .admonition-title, .rst-content .wy-alert-success.admonition-todo .admonition-title, .rst-content .wy-alert-success.admonition .admonition-title { + background: #12826C; } +/* seealso, note, etc */ +.wy-alert.wy-alert-info .wy-alert-title, .rst-content .note .wy-alert-title, .rst-content .wy-alert-info.attention .wy-alert-title, .rst-content .wy-alert-info.caution .wy-alert-title, .rst-content .wy-alert-info.danger .wy-alert-title, .rst-content .wy-alert-info.error .wy-alert-title, .rst-content .wy-alert-info.hint .wy-alert-title, .rst-content .wy-alert-info.important .wy-alert-title, .rst-content .wy-alert-info.tip .wy-alert-title, .rst-content .wy-alert-info.warning .wy-alert-title, .rst-content .seealso .wy-alert-title, .rst-content .wy-alert-info.admonition-todo .wy-alert-title, .rst-content .wy-alert-info.admonition .wy-alert-title, .wy-alert.wy-alert-info .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-info .admonition-title, .rst-content .note .admonition-title, .rst-content .wy-alert-info.attention .admonition-title, .rst-content .wy-alert-info.caution .admonition-title, .rst-content .wy-alert-info.danger .admonition-title, .rst-content .wy-alert-info.error .admonition-title, .rst-content .wy-alert-info.hint .admonition-title, .rst-content .wy-alert-info.important .admonition-title, .rst-content .wy-alert-info.tip .admonition-title, .rst-content .wy-alert-info.warning .admonition-title, .rst-content .seealso .admonition-title, .rst-content .wy-alert-info.admonition-todo .admonition-title, .rst-content .wy-alert-info.admonition .admonition-title { + background: #277CB4; } +/* error, danger */ +.rst-content .danger .admonition-title, .rst-content .danger .wy-alert-title, .rst-content .error .admonition-title, .rst-content .error .wy-alert-title, .rst-content .wy-alert-danger.admonition-todo .admonition-title, .rst-content .wy-alert-danger.admonition-todo .wy-alert-title, .rst-content .wy-alert-danger.admonition .admonition-title, .rst-content .wy-alert-danger.admonition .wy-alert-title, .rst-content .wy-alert-danger.attention .admonition-title, .rst-content .wy-alert-danger.attention .wy-alert-title, .rst-content .wy-alert-danger.caution .admonition-title, .rst-content .wy-alert-danger.caution .wy-alert-title, .rst-content .wy-alert-danger.hint .admonition-title, .rst-content .wy-alert-danger.hint .wy-alert-title, .rst-content .wy-alert-danger.important .admonition-title, .rst-content .wy-alert-danger.important .wy-alert-title, .rst-content .wy-alert-danger.note .admonition-title, .rst-content .wy-alert-danger.note .wy-alert-title, .rst-content .wy-alert-danger.seealso .admonition-title, .rst-content .wy-alert-danger.seealso .wy-alert-title, .rst-content .wy-alert-danger.tip .admonition-title, .rst-content .wy-alert-danger.tip .wy-alert-title, .rst-content .wy-alert-danger.warning .admonition-title, .rst-content .wy-alert-danger.warning .wy-alert-title, .rst-content .wy-alert.wy-alert-danger .admonition-title, .wy-alert.wy-alert-danger .rst-content .admonition-title, .wy-alert.wy-alert-danger .wy-alert-title { + background: #e31704; +} + +/* Generic admonition titles */ +.wy-alert-title, .rst-content .admonition-title { + background: #277CB4; } diff --git a/branch/community-teaching/singlehtml/_static/tabs.css b/branch/community-teaching/singlehtml/_static/tabs.css new file mode 100644 index 0000000..957ba60 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/tabs.css @@ -0,0 +1,89 @@ +.sphinx-tabs { + margin-bottom: 1rem; +} + +[role="tablist"] { + border-bottom: 1px solid #a0b3bf; +} + +.sphinx-tabs-tab { + position: relative; + font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; + color: #1D5C87; + line-height: 24px; + margin: 0; + font-size: 16px; + font-weight: 400; + background-color: rgba(255, 255, 255, 0); + border-radius: 5px 5px 0 0; + border: 0; + padding: 1rem 1.5rem; + margin-bottom: 0; +} + +.sphinx-tabs-tab[aria-selected="true"] { + font-weight: 700; + border: 1px solid #a0b3bf; + border-bottom: 1px solid white; + margin: -1px; + background-color: white; +} + +.sphinx-tabs-tab:focus { + z-index: 1; + outline-offset: 1px; +} + +.sphinx-tabs-panel { + position: relative; + padding: 1rem; + border: 1px solid #a0b3bf; + margin: 0px -1px -1px -1px; + border-radius: 0 0 5px 5px; + border-top: 0; + background: white; +} + +.sphinx-tabs-panel.code-tab { + padding: 0.4rem; +} + +.sphinx-tab img { + margin-bottom: 24 px; +} + +/* Dark theme preference styling */ + +@media (prefers-color-scheme: dark) { + body[data-theme="auto"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); + } + + body[data-theme="auto"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); + } + + body[data-theme="auto"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 1px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); + } +} + +/* Explicit dark theme styling */ + +body[data-theme="dark"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); +} + +body[data-theme="dark"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); +} + +body[data-theme="dark"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 2px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); +} diff --git a/branch/community-teaching/singlehtml/_static/tabs.js b/branch/community-teaching/singlehtml/_static/tabs.js new file mode 100644 index 0000000..48dc303 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/tabs.js @@ -0,0 +1,145 @@ +try { + var session = window.sessionStorage || {}; +} catch (e) { + var session = {}; +} + +window.addEventListener("DOMContentLoaded", () => { + const allTabs = document.querySelectorAll('.sphinx-tabs-tab'); + const tabLists = document.querySelectorAll('[role="tablist"]'); + + allTabs.forEach(tab => { + tab.addEventListener("click", changeTabs); + }); + + tabLists.forEach(tabList => { + tabList.addEventListener("keydown", keyTabs); + }); + + // Restore group tab selection from session + const lastSelected = session.getItem('sphinx-tabs-last-selected'); + if (lastSelected != null) selectNamedTabs(lastSelected); +}); + +/** + * Key focus left and right between sibling elements using arrows + * @param {Node} e the element in focus when key was pressed + */ +function keyTabs(e) { + const tab = e.target; + let nextTab = null; + if (e.keyCode === 39 || e.keyCode === 37) { + tab.setAttribute("tabindex", -1); + // Move right + if (e.keyCode === 39) { + nextTab = tab.nextElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.firstElementChild; + } + // Move left + } else if (e.keyCode === 37) { + nextTab = tab.previousElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.lastElementChild; + } + } + } + + if (nextTab !== null) { + nextTab.setAttribute("tabindex", 0); + nextTab.focus(); + } +} + +/** + * Select or deselect clicked tab. If a group tab + * is selected, also select tab in other tabLists. + * @param {Node} e the element that was clicked + */ +function changeTabs(e) { + // Use this instead of the element that was clicked, in case it's a child + const notSelected = this.getAttribute("aria-selected") === "false"; + const positionBefore = this.parentNode.getBoundingClientRect().top; + const notClosable = !this.parentNode.classList.contains("closeable"); + + deselectTabList(this); + + if (notSelected || notClosable) { + selectTab(this); + const name = this.getAttribute("name"); + selectNamedTabs(name, this.id); + + if (this.classList.contains("group-tab")) { + // Persist during session + session.setItem('sphinx-tabs-last-selected', name); + } + } + + const positionAfter = this.parentNode.getBoundingClientRect().top; + const positionDelta = positionAfter - positionBefore; + // Scroll to offset content resizing + window.scrollTo(0, window.scrollY + positionDelta); +} + +/** + * Select tab and show associated panel. + * @param {Node} tab tab to select + */ +function selectTab(tab) { + tab.setAttribute("aria-selected", true); + + // Show the associated panel + document + .getElementById(tab.getAttribute("aria-controls")) + .removeAttribute("hidden"); +} + +/** + * Hide the panels associated with all tabs within the + * tablist containing this tab. + * @param {Node} tab a tab within the tablist to deselect + */ +function deselectTabList(tab) { + const parent = tab.parentNode; + const grandparent = parent.parentNode; + + Array.from(parent.children) + .forEach(t => t.setAttribute("aria-selected", false)); + + Array.from(grandparent.children) + .slice(1) // Skip tablist + .forEach(panel => panel.setAttribute("hidden", true)); +} + +/** + * Select grouped tabs with the same name, but no the tab + * with the given id. + * @param {Node} name name of grouped tab to be selected + * @param {Node} clickedId id of clicked tab + */ +function selectNamedTabs(name, clickedId=null) { + const groupedTabs = document.querySelectorAll(`.sphinx-tabs-tab[name="${name}"]`); + const tabLists = Array.from(groupedTabs).map(tab => tab.parentNode); + + tabLists + .forEach(tabList => { + // Don't want to change the tabList containing the clicked tab + const clickedTab = tabList.querySelector(`[id="${clickedId}"]`); + if (clickedTab === null ) { + // Select first tab with matching name + const tab = tabList.querySelector(`.sphinx-tabs-tab[name="${name}"]`); + deselectTabList(tab); + selectTab(tab); + } + }) +} + +if (typeof exports === 'undefined') { + exports = {}; +} + +exports.keyTabs = keyTabs; +exports.changeTabs = changeTabs; +exports.selectTab = selectTab; +exports.deselectTabList = deselectTabList; +exports.selectNamedTabs = selectNamedTabs; diff --git a/branch/community-teaching/singlehtml/_static/term_role_formatting.css b/branch/community-teaching/singlehtml/_static/term_role_formatting.css new file mode 100644 index 0000000..0b66095 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/term_role_formatting.css @@ -0,0 +1,4 @@ +/* Make terms bold */ +a.reference span.std-term { + font-weight: bold; +} diff --git a/branch/community-teaching/singlehtml/_static/togglebutton.css b/branch/community-teaching/singlehtml/_static/togglebutton.css new file mode 100644 index 0000000..54a6787 --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/togglebutton.css @@ -0,0 +1,160 @@ +/** + * Admonition-based toggles + */ + +/* Visibility of the target */ +.admonition.toggle .admonition-title ~ * { + transition: opacity .3s, height .3s; +} + +/* Toggle buttons inside admonitions so we see the title */ +.admonition.toggle { + position: relative; +} + +/* Titles should cut off earlier to avoid overlapping w/ button */ +.admonition.toggle .admonition-title { + padding-right: 25%; + cursor: pointer; +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:hover { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 1%); +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:active { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 3%); +} + +/* Remove extra whitespace below the admonition title when hidden */ +.admonition.toggle-hidden { + padding-bottom: 0; +} + +.admonition.toggle-hidden .admonition-title { + margin-bottom: 0; +} + +/* hides all the content of a page until de-toggled */ +.admonition.toggle-hidden .admonition-title ~ * { + height: 0; + margin: 0; + opacity: 0; + visibility: hidden; +} + +/* General button style and position*/ +button.toggle-button { + /** + * Background and shape. By default there's no background + * but users can style as they wish + */ + background: none; + border: none; + outline: none; + + /* Positioning just inside the admonition title */ + position: absolute; + right: 0.5em; + padding: 0px; + border: none; + outline: none; +} + +/* Display the toggle hint on wide screens */ +@media (min-width: 768px) { + button.toggle-button.toggle-button-hidden:before { + content: attr(data-toggle-hint); /* This will be filled in by JS */ + font-size: .8em; + align-self: center; + } +} + +/* Icon behavior */ +.tb-icon { + transition: transform .2s ease-out; + height: 1.5em; + width: 1.5em; + stroke: currentColor; /* So that we inherit the color of other text */ +} + +/* The icon should point right when closed, down when open. */ +/* Open */ +.admonition.toggle button .tb-icon { + transform: rotate(90deg); +} + +/* Closed */ +.admonition.toggle button.toggle-button-hidden .tb-icon { + transform: rotate(0deg); +} + +/* With details toggles, we don't rotate the icon so it points right */ +details.toggle-details .tb-icon { + height: 1.4em; + width: 1.4em; + margin-top: 0.1em; /* To center the button vertically */ +} + + +/** + * Details-based toggles. + * In this case, we wrap elements with `.toggle` in a details block. + */ + +/* Details blocks */ +details.toggle-details { + margin: 1em 0; +} + + +details.toggle-details summary { + display: flex; + align-items: center; + cursor: pointer; + list-style: none; + border-radius: .2em; + border-left: 3px solid #1976d2; + background-color: rgb(204 204 204 / 10%); + padding: 0.2em 0.7em 0.3em 0.5em; /* Less padding on left because the SVG has left margin */ + font-size: 0.9em; +} + +details.toggle-details summary:hover { + background-color: rgb(204 204 204 / 20%); +} + +details.toggle-details summary:active { + background: rgb(204 204 204 / 28%); +} + +.toggle-details__summary-text { + margin-left: 0.2em; +} + +details.toggle-details[open] summary { + margin-bottom: .5em; +} + +details.toggle-details[open] summary .tb-icon { + transform: rotate(90deg); +} + +details.toggle-details[open] summary ~ * { + animation: toggle-fade-in .3s ease-out; +} + +@keyframes toggle-fade-in { + from {opacity: 0%;} + to {opacity: 100%;} +} + +/* Print rules - we hide all toggle button elements at print */ +@media print { + /* Always hide the summary so the button doesn't show up */ + details.toggle-details summary { + display: none; + } +} \ No newline at end of file diff --git a/branch/community-teaching/singlehtml/_static/togglebutton.js b/branch/community-teaching/singlehtml/_static/togglebutton.js new file mode 100644 index 0000000..215a7ee --- /dev/null +++ b/branch/community-teaching/singlehtml/_static/togglebutton.js @@ -0,0 +1,187 @@ +/** + * Add Toggle Buttons to elements + */ + +let toggleChevron = ` + + + +`; + +var initToggleItems = () => { + var itemsToToggle = document.querySelectorAll(togglebuttonSelector); + console.log(`[togglebutton]: Adding toggle buttons to ${itemsToToggle.length} items`) + // Add the button to each admonition and hook up a callback to toggle visibility + itemsToToggle.forEach((item, index) => { + if (item.classList.contains("admonition")) { + // If it's an admonition block, then we'll add a button inside + // Generate unique IDs for this item + var toggleID = `toggle-${index}`; + var buttonID = `button-${toggleID}`; + + item.setAttribute('id', toggleID); + if (!item.classList.contains("toggle")){ + item.classList.add("toggle"); + } + // This is the button that will be added to each item to trigger the toggle + var collapseButton = ` + `; + + title = item.querySelector(".admonition-title") + title.insertAdjacentHTML("beforeend", collapseButton); + thisButton = document.getElementById(buttonID); + + // Add click handlers for the button + admonition title (if admonition) + admonitionTitle = document.querySelector(`#${toggleID} > .admonition-title`) + if (admonitionTitle) { + // If an admonition, then make the whole title block clickable + admonitionTitle.addEventListener('click', toggleClickHandler); + admonitionTitle.dataset.target = toggleID + admonitionTitle.dataset.button = buttonID + } else { + // If not an admonition then we'll listen for the button click + thisButton.addEventListener('click', toggleClickHandler); + } + + // Now hide the item for this toggle button unless explicitly noted to show + if (!item.classList.contains("toggle-shown")) { + toggleHidden(thisButton); + } + } else { + // If not an admonition, wrap the block in a
block + // Define the structure of the details block and insert it as a sibling + var detailsBlock = ` +
+ + ${toggleChevron} + ${toggleHintShow} + +
`; + item.insertAdjacentHTML("beforebegin", detailsBlock); + + // Now move the toggle-able content inside of the details block + details = item.previousElementSibling + details.appendChild(item) + item.classList.add("toggle-details__container") + + // Set up a click trigger to change the text as needed + details.addEventListener('click', (click) => { + let parent = click.target.parentElement; + if (parent.tagName.toLowerCase() == "details") { + summary = parent.querySelector("summary"); + details = parent; + } else { + summary = parent; + details = parent.parentElement; + } + // Update the inner text for the proper hint + if (details.open) { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintShow; + } else { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintHide; + } + + }); + + // If we have a toggle-shown class, open details block should be open + if (item.classList.contains("toggle-shown")) { + details.click(); + } + } + }) +}; + +// This should simply add / remove the collapsed class and change the button text +var toggleHidden = (button) => { + target = button.dataset['target'] + var itemToToggle = document.getElementById(target); + if (itemToToggle.classList.contains("toggle-hidden")) { + itemToToggle.classList.remove("toggle-hidden"); + button.classList.remove("toggle-button-hidden"); + } else { + itemToToggle.classList.add("toggle-hidden"); + button.classList.add("toggle-button-hidden"); + } +} + +var toggleClickHandler = (click) => { + // Be cause the admonition title is clickable and extends to the whole admonition + // We only look for a click event on this title to trigger the toggle. + + if (click.target.classList.contains("admonition-title")) { + button = click.target.querySelector(".toggle-button"); + } else if (click.target.classList.contains("tb-icon")) { + // We've clicked the icon and need to search up one parent for the button + button = click.target.parentElement; + } else if (click.target.tagName == "polyline") { + // We've clicked the SVG elements inside the button, need to up 2 layers + button = click.target.parentElement.parentElement; + } else if (click.target.classList.contains("toggle-button")) { + // We've clicked the button itself and so don't need to do anything + button = click.target; + } else { + console.log(`[togglebutton]: Couldn't find button for ${click.target}`) + } + target = document.getElementById(button.dataset['button']); + toggleHidden(target); +} + +// If we want to blanket-add toggle classes to certain cells +var addToggleToSelector = () => { + const selector = ""; + if (selector.length > 0) { + document.querySelectorAll(selector).forEach((item) => { + item.classList.add("toggle"); + }) + } +} + +// Helper function to run when the DOM is finished +const sphinxToggleRunWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} +sphinxToggleRunWhenDOMLoaded(addToggleToSelector) +sphinxToggleRunWhenDOMLoaded(initToggleItems) + +/** Toggle details blocks to be open when printing */ +if (toggleOpenOnPrint == "true") { + window.addEventListener("beforeprint", () => { + // Open the details + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.dataset["togglestatus"] = el.open; + el.open = true; + }); + + // Open the admonitions + document.querySelectorAll(".admonition.toggle.toggle-hidden").forEach((el) => { + console.log(el); + el.querySelector("button.toggle-button").click(); + el.dataset["toggle_after_print"] = "true"; + }); + }); + window.addEventListener("afterprint", () => { + // Re-close the details that were closed + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.open = el.dataset["togglestatus"] == "true"; + delete el.dataset["togglestatus"]; + }); + + // Re-close the admonition toggle buttons + document.querySelectorAll(".admonition.toggle").forEach((el) => { + if (el.dataset["toggle_after_print"] == "true") { + el.querySelector("button.toggle-button").click(); + delete el.dataset["toggle_after_print"]; + } + }); + }); +} diff --git a/branch/community-teaching/singlehtml/index.html b/branch/community-teaching/singlehtml/index.html new file mode 100644 index 0000000..a0b9a69 --- /dev/null +++ b/branch/community-teaching/singlehtml/index.html @@ -0,0 +1,3179 @@ + + + + + + + Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Community teaching training

+
+

Under development (mid 2022)

+

As of mid-2022, this material has been reworked for our summer workshop and +for the CarpentryCon 2022 workshop. The material will continue to be +improved before a longer training session in the autumn.

+

This material is the new version of our previous Instructor +training.

+
+
+

What this course covers

+

In 2020, we got farther from our offices but closer to each other. If +you could adapt to the circumstances, a huge number of possibilities +were opened - in particular with collaborative teaching. In this +training, you will learn how we use them. Teaching from 2019 is +almost obsolete - join us to learn more.

+
    +
  • Tools of teaching: how to make the most out of online (and +other) teaching.

  • +
  • Workshop organization, collaboratively: our vision of teaching +together outside of our silos.

  • +
  • Socio-technical factors: social and technical barriers to +learning, why you need to care, and what you can do about them.

  • +
  • Lesson development, collaboratively: how to design lessons and +teaching materials so that they can be open and shared.

  • +
+
+
+

Who is the course for?

+

Teaching is a profession, but also something that everyone needs to be +able to do to some degree, since everyone has their own personal +specialties they will either teach or mentor.

+

This course can be relevant for different learner personas:

+
    +
  • You run a practical teaching program at your institution (for example +as part of a research computing group) and would like to learn best +practices for collaborative teaching, so that you aren’t re-inventing +the same thing over and over again.

  • +
  • You are a technical specialist who is frustrated with the way you +currently try to teach others who need to use your software or +infrastructure. You can’t spend too much time to become a +professional, but you know you need something more than what you’ve +been doing. Thus, you would like to adopt some of the best practices of +designing and teaching interactive, hands-on workshops.

  • +
  • You’ve been teaching alone, but would like to join a collaboration +network for more co-teaching and to reduce the amount of duplication +of effort.

  • +
  • You are interested in teaching CodeRefinery lessons, and would like a +comprehensive kick-start to how CodeRefinery works, either to join us, +or teach its lessons with us or independently.

  • +
+
+
+

Pre-workshop preparation

+

These things will help you get the most out of this workshop, by +giving you a broad overview at the beginning that you might only get +later on in the lesson.

+

Don’t worry if you don’t have time to do everything here. The most +important ones are listed first.

+
+

Read “How to help someone use a computer” (5 min)

+

How to help someone use a computer, by Phil +Agre. +Summary: Most of our teaching challenge is helping people to overcome bad user +interface design.

+
+
+

Browse a CodeRefinery lesson (5 min)

+

Please take 5 minutes and go through a CodeRefinery +lesson and understand the general +layout. Don’t go in-depth to any of the material (unless you want, +obviously). We would recommend +git-intro if you don’t +have a preference.

+
+
+

(optional) Watch “The future of teaching” (35 min content only, 45 min with Q&A, or 15 min reading)

+

The “The Future of Teaching” talk is a summary of many things in this +course. You could watch it as a preparation (or if you are reading on +your own, as a summary). This is low priority, since we will cover +most of these things in the course itself. +Watch it on YouTube +or read it if you prefer.

+
+
+

(optional) Read “The science of learning” (20 min)

+

Read this short paper The Science of +Learning +which provides a brief overview of some key evidence-based results in +teaching. This paper is also used by The +Carpentries for their Instructor Training +workshops.

+
+
+
+
+
+

Welcome and introduction

+
+

What do we want to get out of this workshop

+
    +
  • Introduction of instructors and helpers

  • +
  • Each instructor can say what we want to get out of the instructor training

  • +
  • But we want to know from everybody and collect these in the live notes

  • +
+
+
+
+

Goals for this workshop

+
+

Goals for this instructor training

+
    +
  • Inspire teachers and staff who have to teach indirectly as part of +their job: use best practices for the modern world, especially +for online teaching.

  • +
  • Promote collaboration in teaching: less going alone.

  • +
  • Promote CodeRefinery sustainability: form a network that can +work together to share the work and benefits.

  • +
+
+
+
Giving confidence
+
+

Goal number one should be that we give participants the confidence to +independently apply the tools or knowledge learnt. This is more important +that giving a “complete” overview. [Lucy Whalley gave this great comment at one of our workshops]

+
+
    +
  • You don’t have to know everything to use (or teach) something.

  • +
  • For the large majority of topics we teach, there are many resources online +which provide how-to guides or tutorials. And the Stack Overflow answer bank +isn’t getting any smaller. So we need to ask why do people attend in-person +sessions if there is information freely available? Our impression is that +it is for confidence building, identity formation, perhaps signposting to +resources.

  • +
  • This also links with building a welcoming/inclusive environment: for example, +imposter syndrome, which disproportionately affects under-represented groups +(link), +can manifest as low self-confidence –> building the confidence of +students in the classroom may lead to a more diverse community.

  • +
+
+
+
+
+

Tools for this workshop

+

We often start workshops with these:

+ +
+
+
+

Code of Conduct

+
    +
  • We follow The CodeRefinery Code of +Conduct.

  • +
  • This is a hands-on, interactive workshop.

    +
      +
    • Be kind to each other and help each other as best you can.

    • +
    • If you can’t help someone or there is some problem, let someone know.

    • +
    • If you notice something that prevents you from learning as well as you can, let us know and don’t suffer silently.

    • +
    +
  • +
  • It’s also about the little things:

    +
      +
    • volume

    • +
    • font size

    • +
    • generally confusing instructor

    • +
    • not enough breaks

    • +
    +
  • +
+
+
+
+

About the CodeRefinery project and CodeRefinery workshops

+
+

Keypoints

+
    +
  • Teaches intermediate-level software development tool lessons

  • +
  • Training network for other lessons, too

  • +
  • Publicly-funded discrete projects (3 projects actually) transitioning towards an open community project

  • +
  • We have online material, teaching, and exercise sessions

  • +
  • We want more people to work with us, and to work with more people

  • +
+
+

CodeRefinery is a +Nordic e-Infrastructure Collaboration (NeIC) +project that has started in October 2016 and is +funded until February 2025.

+

The funding from 2022-2025 is designed to keep this project active +beyond 2025 by forming a support network and building a community of +instructors and contributors.

+
+

History

+

The CodeRefinery project idea grew out of two SeSE courses given at KTH Stockholm in 2014 and 2016:

+ +

The project proposal was submitted to NeIC in 2015, accepted in 2015, and started in 2016.

+

We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form.

+
+
+

Main goals

+
    +
  • Develop and maintain training material on software best practices for researchers that already write code. Our material addresses all academic disciplines and tries to be as programming language-independent as possible.

  • +
  • Provide a code repository hosting service that is open and free for all researchers based in universities and research institutes from Nordic countries.

  • +
  • Provide training opportunities in the Nordics using Carpentries and CodeRefinery training materials.

  • +
  • Articulate and implement the CodeRefinery sustainability plan.

  • +
+
+
+

Impact

+

We collect feedback and survey results to measure our impact.

+

3-6 months after attending a workshop, past participants are asked to complete a short post-workshop survey. +The survey questions aim to establish what impact CodeRefinery workshops have on how past participants develop +research software.

+

Pre- and post-workshop survey results

+
    +
  • Overall quality of research software has improved: more reusable, modular, reproducible and documented.

  • +
  • Collaboration on research software development has become easier

  • +
  • Past participants share their new knowledge with colleagues

  • +
  • Usage of several tools is improved, and new tools are adopted

  • +
+

Free-form answers +also suggest that workshops are having the intended effects on how people develop code. A common theme is:

+
+

I wish I had known this stuff already as a grad student 10+ years ago…

+
+

We would love to get suggestions on how we can better quantify our impact. This +would make it easier for us to convince institutions to partner with us and +also open up funding opportunities.

+
+
+

Target audience

+
+
Carpentries audience
+

The Carpentries aims to teach computational competence to learners through an applied approach, avoiding the theoretical and general in favor of the practical and specific.

+

Learners do not need to have any prior experience in programming. One major goal of a Carpentry workshop is to raise awareness on the tools researchers can learn/use to speed up their research.

+

By showing learners how to solve specific problems with specific tools and providing hands-on practice, learners develops confidence for future learning.

+
+

Novices

+

We often qualify Carpentry learners as novices: they do not know what they need to learn yet. A typical example is the usage of version control: the Carpentry git lesson aims to give a very high level conceptual overview of Git but it does not explain how it can be used in research projects.

+
+
+
+
CodeRefinery audience
+

In that sense, CodeRefinery workshops differ from Carpentry workshops as we assume our audience already writes code and scripts and we aim at teaching them best software practices.

+

Our learners usually do not have a good overview of best software practices but are aware of the need to learn them. Very often, they know the tools (Git, Jupyter, etc.) we are teaching but have difficulties to make the best use of them in their software development workflow.

+

Whenever we can, we should direct learners that do not have sufficient coding experience to Carpentries workshops.

+
+

Competent practitioners

+

We often qualify CodeRefinery learners as competent practitioners because they already have an understanding of their needs. +Novices and competent practitioners will be more clearly defined in the next section.

+
+
+

Best software practices for whom?

+

It can be useful to ask the question: best software practices for whom? +CodeRefinery teaches best software practices derived from producing and +shipping software. These practices are also very good for sharing software, +though our audience will probably not need to embrace all aspects of +software engineering.

+
+
+
+
+
+
+
+

Teaching online

+

Is online teaching better or worse? As usual for that question, “it’s +all a trade-off”. We believe that many people tried to directly +translate in-person strategies to online, and teaching suffered. In +some ways, this even revealed the flaws of in-person pedagogy (remove +some interaction and not much is left other than an info-dump).

+
+

Exercise

+

Using HackMD, brainstorm advantages and disadvantages of online and +in-person teaching. For each disadvantage of each, think of ways to compensate.

+
+
    +
  • We won’t elaborate more here right now - most of the rest of the +course somehow relates to online teaching!

  • +
  • We will see many techniques which compensate for some of the +disadvantages in the section tools of teaching.

  • +
  • Workshop organization will discuss new collaborative +opportunities with online teaching.

  • +
+
+

See also

+
    +
  • The rest of this course

  • +
  • CodeRefinery manuals: https://coderefinery.github.io/manuals/

  • +
+
+
+
+

Team teaching

+

One of the most significant improvemest of our teaching has been the +concept of co-teaching.

+
+

Co-teaching

+

Wikipedia: Co-teaching or team teaching is the division of labor +between educators to plan, organize, instruct and make assessments +on the same group of students, generally in the a common +classroom,[1] and often with a strong focus on those teaching as a +team complementing one another’s particular skills or other +strengths.

+
+

This is not strictly an effect of moving online. However, the +larger number of instructors and larger audiences make this practical +on a wide scale.

+
+

Primary article

+

https://coderefinery.github.io/manuals/team-teaching/

+
+
+

Benefits

+
    +
  • The course seems very interactive, much more so than expecting +students to speak up. The co-teacher can take on the “voice of the +audience”.

  • +
  • Quicker preparation time since co-teachers can rely on each other in +unexpected situations.

  • +
  • One co-teacher can be effectively learning at the same time and thus +acting as the “voice of the audience” in another way.

  • +
  • Great way to onboard new instructors - extensive training and +preparation no longer needed.

  • +
  • More active minds means better able to watch and react to other +feedback, such as HackMD or chat.

  • +
  • Less workload - one person does not have to prepare perfectly, any +uncertainty can usually be quickly answered by the other.

  • +
+
+
+

Strategies

+

In reality, these strategies are mixed and matched even within a +lesson, and there are many things between these:

+
    +
  • One person gives lectures, one does the typing during demos.

  • +
  • “Interview”: One primarily doing the “teaching”, one guiding by +asking questions - either as an interviewer or as a virtual learner.

  • +
+

Things that don’t work (are not team teaching):

+
    +
  • Dividing up a lesson into parts, each person gives different parts +independently.

  • +
+
+
+

Exercises

+
+

Exercise

+

Divide into groups of two or three. Choose one of the two models +in the team-teaching page, and quickly (5 min) prepare a short +topic (3-5 min) to team teach. You can quickly scan the +“preparation” section at the bottom.

+

The challenge is not just to give the lesson, but to prepare the +lesson quickly and rely on each other to give a good lesson anyway.

+
+
+
+

See also

+

(none yet)

+
+
+
+

HackMD

+

The name “HackMD” doesn’t do this concept justice, nor do the more +common descriptions of “shared notes” or “collaborative document”. It +is a full replacement for chat: perhaps it could be called random +access chat or parallel 2D chat ?

+

HackMD itself is a web service for collaborative documents in +Markdown. This isn’t special to HackMD, but we have used it for its +scalability, markdown support, and privacy in the “view” mode.

+
+

Primary articles

+ +
+
+

Advantages

+
    +
  • Synchronous questions, no disadvantage for quiet people.

  • +
  • Anonymous questions.

  • +
  • Parallel answers by a large number of helpers.

  • +
  • Easier to go back and review past questions during Q&A sessions +(compared to scrolling through chat), for example finding important +or unanswered questions.

  • +
  • The above can make a course feel much more interactive than it would +otherwise.

  • +
+
+
+

Disadvantages

+
    +
  • Overwhelming flood of information

    +
      +
    • But you wanted more interaction, right?

    • +
    • Co-teaching helps here, one person can focus on watching.

    • +
    • Students must be warned to be deliberate about where they focus +their attention (different learners have different interests).

    • +
    +
  • +
  • It is another tool to use

    +
      +
    • Not required for basic learners, learners can begin using when +they are comfortable.

    • +
    +
  • +
+
+
+

Exercise

+
+

Exercise

+
    +
  • Actively use HackMD during this course.

  • +
  • Observe how the instructors integrate it during the course +itself, and can immediately respond to the questions.

  • +
  • Observe how instructors occasionally mention and screenshare +HackMD to validate to the audience that it is being watched.

  • +
  • Keep HackMD open. Can you balance it and watching. Does it +increase or decrease engagement?

  • +
+
+
+
+
+

Teams

+

Everyone wants interaction in courses, yet when a group size gets too +large, it doesn’t have much interaction. A event in a physical space +naturally makes teams based on who is nearby. When done online, this +needs to be more explicit.

+
+

Primary articles

+ +
+
+

Basic concepts

+
    +
  • Teams are pre-assigned

  • +
  • Exercise leaders (aka helpers) assigned per team

  • +
  • Teams stay together during the whole workshop.

  • +
  • Learners can sign up either alone…

  • +
  • … or they can sign up with a pre-made team: people who know +each. “bring your own breakout room”:

    +
      +
    • When two people in a work group learn a skill, uptake within the +group is often much higher. Thus, we strongly encourage pre-made +teams that know each other.

    • +
    • Teams that all come from the same group or field, with a helper +from that field, can transition to help

    • +
    +
  • +
+
+
+

Online

+

In the best online implementations, our teams have these properties:

+
    +
  • Coordination of breakout rooms is a lot of work.

  • +
  • In zoom, we could request learners to rename to (N) Learner +Name, and then quickly assign people. Now, you can have learners +self-select their rooms. But will they actually do this, or stay in +main room?

  • +
  • One helper is assigned per team.

    +
      +
    • In fact, we would limit the number of registrations to 5× the +number of helpers so that all teams have a helper

    • +
    +
  • +
  • Our registration system (indico) is capable of mailing personalized +messages per person with their team information. This is quite a +bit of work to manage.

  • +
+

But they have these disadvantages:

+
    +
  • Much, much harder registration coordination, almost to the point of +being impossible.

  • +
  • Number of attendees.

  • +
  • Difficulties when attendees drop out partway through a course.

  • +
+
+
+

In-person

+

Teams may natuarally form based on setting location, but

+
    +
  • Teams may happen naturally by sitting at the same table

  • +
  • Do teams stay the same day after day?

  • +
  • Do teams get arranged in a manner useful for learning?

  • +
  • Do you have one helper per team?

  • +
  • Do you encourage people to interact explicitly enough?

  • +
  • Do you ensure that no one gets left out in the crowd? Are the teams +explicit enough?

  • +
+
+
+

Discussion: what we actually do

+
    +
  • For large enough CodeRefinery workshops, assign teams with one +helper each. Deal with re-adjustment

  • +
  • The livestream option allows everyone else to follow along.

  • +
  • In other workshops, create breakout rooms but somehow try let people +self-assign. Most don’t.

  • +
  • For large workshops without enough staff help, livestream and +encourage people to form their own teams and watch themselves - we +don’t actually need to be involved.

  • +
  • Teams can be delegated to a local organizer.

  • +
+
+
+

Exercises

+
+

Teams

+

Consider these questions:

+
    +
  • Should teams have similar or different people in them?

  • +
+
+
+
+
+

Livestreaming

+

In a large lecture, in effect, you don’t interact with most people - +not even close. Yet, trying to force this limited interaction greatly +limits our possible reach, and keeps us in an awkward state of +expecting live interaction yet usually receiving minimal. When we try +this online, it forces a closed

+

Teaching via livestreaming allows us to:

+
    +
  • Reach a near-unlimited number of people

  • +
  • Fully embrace online tools for interaction, instead of asking people +to speak up. This equalizes the participation for shy or passive +participants.

  • +
  • By being large, be more efficient and use the extra resources for +meaningful interactions in small groups.

  • +
+
+

Primary articles

+ +
+
+

Summary

+
    +
  • There are actually three levels here.

    +
      +
    • In-person

    • +
    • Online meeting

    • +
    • Online livestream

    • +
    +
  • +
+
+https://coderefinery.github.io/manuals/_images/mooc-diagram.png +
+

The general presence and information flow within the MOOC strategy.

+
+
+
    +
  • CodeRefinery livestreams via Twitch, but Twitch is not an essential +aspect.

  • +
  • We can invite anyone in the world, no risk of disruptions from +trolls.

  • +
  • This has enabled us to fully embrace strategies such as HackMD and +co-teaching.

    +
      +
    • While we tried these in-person, they didn’t work well since the +loud, extroverted people would dominate.

    • +
    +
  • +
+
+
Tech details
+
    +
  • We stream by using OBS to capture a Zoom meeting. We can switch +between a gallery view, screenshare, and mixed.

  • +
  • Dedicated instructor Zoom meeting - no learners. Thus, no chance of +privacy violations.

    +
      +
    • Learners can attend different ways: a) independently online b) +in-person breakout room c) Zoom breakout rooms.

    • +
    +
  • +
  • We don’t have time to get into details here… see the linked +documents and also join us for in-person experience while we improve +our materials more.

  • +
+
+
+
+

Exercises

+
+

(advanced) Set up and install OBS as a livestreaming tool.

+

This exercise is open-ended.

+
+
+
+
+

Instructor tech setup

+
+

Keypoints

+
    +
  • Screenshare: portrait layout instead of sharing entire screen

  • +
  • Prompt: adjust your prompt to make commands easy to read

  • +
  • Readability and beauty is important: adjust your setup for your audience

  • +
  • Share the history of your commands

  • +
  • Get set up a few days in advance and get an outside reviewer

  • +
+
+
+

Screenshare

+

Compare the following two screen-shares (you can find many more in +the coderefinery manuals:

+
+https://coderefinery.github.io/manuals/_images/screenshare-fullhd.png +
+

FullHD.

+
+
+
+https://coderefinery.github.io/manuals/_images/s10-kickstart-prompt-log.png +
+

Portrait, latest proposed best practices.

+
+
+

Share a portrait layout (left or right half of your screen) +instead of sharing entire screen.

+

Motivation:

+
    +
  • This makes it easier for you to look at some other notes or to coordinate +with other instructors at the same time +without distracting with too much information.

  • +
  • This makes it possible for participants to have something else open in the +other screen half: terminal or browser or notebook.

  • +
+
+
+

Adjust your prompt/configuration/colors

+

Adjust your prompt to make commands easy to read. What looks good for your own +work (many terminals, small font, extensions, shortcuts, color scheme) is +usually not the best for other people watching you. Adjust your setup for your +audience. Remove distractions.

+

You need to spend some time getting set up before you teach. 10 minutes +before the session starts is typically too late. Get set up a few days in +advance and get an outside reviewer.

+
+

Should instructors be forced to have a consistent screenshare?

+

There are pros and cons to all instructors using the same screenshare and prompt.

+
    +
  • What are the advantages?

  • +
  • What are the opportunities of instructors showing different setups?

  • +
  • How does it depend on the lesson and the experience of learners?

  • +
+
+
+
+

Share the history of your commands

+

Even if you type slowly it is almost impossible to follow every command. We +all get distracted or want to read up on something or while following a command +fails on the learner laptop while instructor gets no error.

+

Add pauses and share the commands that you have typed so that one can catch up.

+
+
+

More examples and how to set it up

+ +
+
+

Exercises

+
+

Evaluate screen captures

+

Evaluate screenshots within the instructor tech +setup lesson. +Use the collaborative document to make a list of the trade-offs of each one. +Which one do you prefer? Which are useful in each situation?

+
+
+

Set up your own environment

+

Set up your screen to teach something. Get some feedback from +another learner. We will discuss among the class.

+
+
+
+
+

Video recording

+
+

Keypoints

+
    +
  • We don’t expect many people to watch the recording from scratch later (but +some do) (some might look afterwards a few pieces, cmp. reading a book vs +look ing sth up from a book)

  • +
  • Learners getting an “instant replay” to review, or to make up for a lost day, is great.

  • +
  • Privacy is more important than any other factor

  • +
  • Recording only works if privacy is guaranteed and effort is low. +This is only possible with the instructor-audience split setup of livestreaming.

  • +
+
+
+

We try to release videos on the same day

+

Video recordings could be useful for people attending a course later, but also +are (perhaps more) useful for immediate review and catching up after missing +a day in a workshop.

+

For this, they need to be released immediately, within a few hours of the +workshop (see Video editing). CodeRefinery can do this.

+

For the videos to be released soon we need to make sure we guarantee privacy of +learners (see below). Our livestream setup makes the privacy guarantee easy at +the cost of separating instructors and learners into different video rooms.

+

Good preparation and documentation helps to make video recording and video +editing easier.

+
+
+

Privacy is more important than any other factor

+

If we can’t guarantee privacy, we can’t release videos at all.

+

Some events add a disclaimers such as “if you don’t want to appear +in a recording, leave your video off and don’t say anything”. We +would prefer not to do this, since:

+
    +
  • we know accidents happen (especially when coming back from breakout rooms)

  • +
  • it creates an incentive to not interact by voice/video

  • +
  • it could pressure participants to not object in order “to not be difficult”

  • +
+

Livestreaming solves this for us:

+
    +
  • By separating the instruction from +the audience audio/video, there is no privacy risk in the raw +recording. They could be released or shared unprocessed.

  • +
  • Recording with Zoom in a large meeting with all the instructors and +learners is simple, but not good for privacy: there are always +mistakes, reviewing takes too long.

  • +
  • Livestream platforms also provide instant recordings of the whole +stream, and some make instant replays possible. This could remove +the need for making our own videos, since one of the most important +cases is this instant replay idea.

  • +
+
+
+

Broadcasting role and setup

+

In the live-streaming setup, the Broadcasting role is central to video +recording.

+

Broadcaster description (most is not directly about recording): +https://coderefinery.github.io/manuals/broadcaster/

+
+
+
+

Video editing

+

Video recordings could be useful for people attending a course later, +but also are (perhaps more) useful for immediate review and catching +up after missing a day in a workshop. For this, they need to be +released immediately, within a few hours of the workshop. +CodeRefinery can do this.

+

Hypothesis: videos must be processed the same evening as they were +recorded, otherwise (it may never happen) or (it’s too late to be +useful). To do that, we have to make processing good enough (not +perfect) and fast and distributeable

+
+

Primary articles

+ +
+
+

Summary

+
    +
  • Basic principle: privacy is more important than any other factor. +If we can’t guarantee privacy, we can’t release videos at all.

    +
      +
    • Disclaimers such as “if you don’t want to appear in a recording, +leave your video off and don’t say anything”, since a) accidents +happen especially when coming back from breakout rooms. b) it +creates an incentive to not interact or participate in the course.

    • +
    +
  • +
  • Livestreaming is important here: by separating the instruction from +the audience audio/video, there is no privacy risk in the raw +recording. They could be released or shared unprocessed.

  • +
  • Our overall priorities

    +
      +
    1. No learner (or anyone not staff) video, audio, names, etc. are +present in the recordings.

    2. +
    3. Good descriptions.

    4. +
    5. Removing breaks and other dead time.

    6. +
    7. Splitting videos into useful chunks (e.g. per-episode), perhaps +equal with the next one:

    8. +
    9. Good Table of Contents information so learners can jump to the +right spots (this also helps with “good description”.)

    10. +
    +
  • +
  • ffmpeg-editlist allows us to +define an edit in a text file (crowdsourceable on Github), and then +generate videos very quickly.

  • +
+
+
+

Exercises

+
+
Exercise A
+

These exercises will take you through the whole sequence.

+
+

Editing-1: Get your sample video

+

Download a sample video:

+
+
+
+
+

Editing-2: Run Whisper to generate raw subtitles and test video.

+

First off, install Whisper and generate the base subtitles, based +on the. Since this is probably too much to expect for a short +lesson, they are provided for you (above), but if you want you can +try using Whisper, or generating the subtitles some other way.

+

You can start generating subtitles now, while you do the next +steps, so that they are ready by the time you are ready to apply +the editlist. ffmpeg-editlist can also slice up the subtitles from +the main video to make subtitles for each segment you cut out.

+

Whisper is left as an exercise to the reader.

+ +
+
+

Editing-3: Create the basic editlist.yaml file

+

Install ffmpeg-editlist and try to +follow its instructions, to create an edit with these features:

+
    +
  • The input definition.

  • +
  • Two output sections: the “Intro to the course”, and “From data +storage to your science” talks (Remember it said the recording +started at 11:35… look at the schedule for hints on when it +might start!). This should have a start/end timestamp from the +original video.

  • +
+

A basic example:

+
- input: day1-raw.mkv
+
+# This is the output from one section.  Your result should have two of these sections.
+- output: part1.mkv
+  title: something
+  description: >-
+    some long
+    description of the
+    segment
+  editlist:
+    - start: 10:00    # start timestamp of the section, in *original* video
+    - end: 20:00      # end timestamp of the section, in the *original* video
+
+
+ +
+
+

Discussion: what makes a video easy to edit?

+
    +
  • Clear speaking and have high audio quality.

  • +
  • For subtitle generation: Separate sentences cleanly, otherwise it +gets in a “stream of words” instead of “punctuated sentences” +mode.

  • +
  • Clearly screen-sharing the place you are at, including section +name.

  • +
  • Clear transitions, “OK, now let’s move on to the next lesson, +LESSON-NAME. Going back to the main page, we see it here.”

  • +
  • Clearly indicate where the transitions are

  • +
  • Hover mouse cursor over the area you are currently talking about.

  • +
  • Scroll screen when you move on to a new topic.

  • +
  • Accurate course webpage and sticking to the schedule

  • +
+

All of these are also good for learners. By editing videos, you +become an advocate for good teaching overall.

+
+
+

Editing-4: Run ffmpeg-editlist

+

Install ffmpeg-editlist: pip install ffmpeg-editlist[srt] (you +may want to use a virtual environment, but these are very minimal +dependencies).

+

The ffmpeg command line tool must be available in your +PATH.

+ +
+
+

Editing-5: Add more features

+
    +
  • Several chapter definitions.(re-run and you should see a +.info.txt file also generated). Video chapter definitions +are timestamps of the original video, that get translated to +timestamps of the output video.

    +
    - output: part1.mkv
    +  editlist:
    +  - start: 10:00
    +  - -: Introduction    #  <-- New, `-` means "at start time"
    +  - 10:45: Part 1      #  <-- New
    +  - 15:00: Part 2      #  <-- New
    +  - end: 20:00
    +
    +
    +

    Look at the .info.txt files that come out now. What is new in it?

    +
  • +
  • Add in “workshop title”, “workshop description”, and see the +.info.txt files that come out now. This is ready for +copy-pasting into a YouTube description (first line is the title, +rest is the description).

    +

    Look at the new .info.txt files. What is new?

    +
  • +
+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+
+
+

Editing-7: Generate the final output file.

+
    +
  • Run ffmpeg-editlist with the --reencode option: this +re-encodes the video and makes sure that there is no black point +at the start.

  • +
  • If you re-run with --check, it won’t output a new video file, +but it will re-output the .info.txt and .srt files. +This is useful when you adjust descriptions or chapters.

  • +
+
+
+

Discussion: how to distribute this?

+

Create a flowchat of all the parts that need to be done, and which +parts can be done in parallel. Don’t forget things that you might +need to do before the workshop starts.

+

How hard was this editing? Was it worth it?

+
+
+
+
Exercise B
+

This is similar to the above but more brief and not on a real example +video.

+
+

Use ffmpeg-editlist to edit this sample video

+

Prerequisites: ffmpeg must be installed on your computer +outside of Python. Be able to install ffmpeg-editlist. This is +simple in a Python virtual environment, but if not the only +dependency is PyYAML.

+ +
+ +
+
+
+

See also

+ +
+
+
+

Distributed workshop organization

+
+

Keypoints

+
    +
  • If another university/organization wants to run the course, they can easily join our existing course at little cost/risk to them and to us.

  • +
  • Each organization that joins provides a great benefit to us (helpers, instructors).

  • +
  • They can reserve an in-person breakout room and provide mentors while watching the livestream: A great experience for their audience.

  • +
+
+
+

It is easier to join and follow than to start or lead

+

Organizing a course is time intensive and so is developing a course. Many +courses given in country A are also relevant in other countries and instead of +developing and possibly re-inventing courses independently in different places, +it is so much more rewarding to collaborate and share.

+

In our courses we wish and try to make it easier for teams and organizations +and universities to join, at little risk and cost to them, possibly for a short +period of time, possibly only as observer. Later observers can progress to +exercise leads, expert helpers, instructors, and co-organizers.

+

One model that we have successfully tried is that the course is delivered via +live-stream to all partners and all the partner needs to do is to reserve a +room and motivate few people to help local learners as exercise leads during +exercise sessions which can happen in-person.

+
+

Lessons learned from organizing larger workshops

+
    +
  • One person is needed to coordinate the registration process and this person should +not have teaching duties in addition to this role.

  • +
  • Generally it helps to have well-defined roles (see Workshop roles).

  • +
+
+
+
+
+
+
+

Why teach together?

+

We usually say so much about the value of collaboration. Despite us +saying this, our teaching is still far too alone. Covid-19 gave us a +kick that reduced our barriers and led to lasting changes in how we +taught (eventually leading to this very course).

+

Open Science / FAIR data is heavily emphazised these days. But let’s +add a “C” to FAIR: “collaborative”. Instead of people doing their own +thing and releasing, develop, iterate, and maintain collaboratively.

+
+

Ways to teach together

+
    +
  • Develop materials together - avoid duplication.

  • +
  • Team teaching

  • +
  • Extensive use of helpers and team leaders.

  • +
  • HackMD for parallel and mass answers.

  • +
+
+
+

Advantages

+
    +
  • You need to teach anyway, less effort if you combine.

  • +
  • If done right, minimal extra effort for others to receive benefit (+ +you get publicity).

  • +
  • Many of the previously presented teaching strategies work best in +large courses - this makes the course more engaging than a small +event with minimal interaction.

  • +
  • More engaging for the audience.

  • +
  • Easier on-boarding of new instructors (less “scary” to teach a new course +with other instructors).

  • +
+
+
+

Challenges and disadvantages

+
    +
  • Coordination

    +
      +
    • Finding suitable partners with the same vision

    • +
    • Coordination efforts (if others don’t understand the vision).

    • +
    +
  • +
  • Materials

    +
      +
    • May not be perfectly tuned to your own audience

    • +
    • May not iterate as fast as you need

    • +
    +
  • +
  • Co-teaching

    +
      +
    • Difficulty in finding co-teachers

    • +
    • Required effort of syncing among staff

    • +
    • It might revert to independent teaching if you aren’t careful.

    • +
    +
  • +
  • HackMD

    +
      +
    • Can possibly overload both student and teacher.

    • +
    +
  • +
+
+
+

Exercises

+
+

What similarities do we have?

+

Using HackMD, make two lists:

+
    +
  • What courses do you think your local community would benefit +from, which you don’t currently have? +1 other people’s items +which are also relevant to you.

  • +
  • Which courses are you thinking of preparing for your local +community? +1 other people’s items which you would be +interested in helping out with.

  • +
+
+
+
+

See also

+ +
+
+
+

Collaboration models

+
+

Model: CodeRefinery

+
    +
  • Before Covid-19, workshops were physically around the Nordics, +instructors would travel (or already be there).

    +
      +
    • Maximum size: ~40 people

    • +
    • High workload per person

    • +
    +
  • +
  • After several small scaling attempts, now we have:

    +
      +
    • Two large workshops per year - livestream format

    • +
    • Combined organization efforts

    • +
    • Instructors from each location - on average two lessons taught.

    • +
    • Locations with staff can have local breakout rooms: physical +place to help during exercises.

    • +
    +
  • +
  • Others in the world can register and interact using HackMD, but no +promises of help.

  • +
  • Content still available to anyone in the world: live + instant +replay.

  • +
  • Course page and material: +https://coderefinery.github.io/2022-03-22-workshop/

  • +
+
+
+

Model: Python for Scientific Computing

+
    +
  • Aalto Scientific Computing wanted to host a course, Python for +Scientific Computing

  • +
  • ASC came up with initial vision and announced it

  • +
  • ASC hosted an open initial meeting, inviting any interested +organizers or instructors

  • +
  • We went over the plan and refined the topics and schedule. We also +decided things such as the date, organizers, and instructors for +each lesson.

  • +
  • Registration was open to everyone in the world, non-Nordic +participants could watch via livestream.

  • +
  • People prepared their parts and came together and presented. +Organizers kept everything on track.

  • +
  • Compared to the amount of effort each person put in, the results +were great.

  • +
  • A 2021 version also happened and was even larger.

  • +
  • Course page: https://scicomp.aalto.fi/training/scip/python-for-scicomp/

  • +
  • Material: https://aaltoscicomp.github.io/python-for-scicomp/

  • +
+
+
+

Exercises

+
+

List successes and failures in collaborative teaching

+

Using HackMD, list some successes and failures in collaborative +teaching that you have experienced.

+
+
+

Recommendations for co-teaching

+

If you have experience with co-teaching, what approach/technique/trick +can you recommend a colleague who would like to try co-teaching for the +first time?

+
+
+
+
+

Workshop roles

+

Running massive workshops requires a lot of people. We have a variety +of roles with different levels of support.

+

As usual, roles are a plan, and a plans are made to be updated.

+
+

Primary articles

+ +
+
+

Summary

+

Lower levels mean “top level sometimes split into some of these +sub-roles”.

+
    +
  • Instructor coordinator: coordinates schedule and instructors

    +
      +
    • Instructor: Teaches along with a co-teacher.

    • +
    • Expert helper: Spare person, usually watching HackMD but also +rotates among breakout rooms. Often instructs some lessons.

    • +
    • Director: Manages the flow of the schedule during the +workshop, introduces each lesson, etc. (often the instructor +coordinator)

      +
        +
      • Broadcaster: Manages the livestreaming

        +
          +
        • Video editor: Edits and publishes videos the day of the +workshop.

        • +
        +
      • +
      +
    • +
    +
  • +
  • Registration coordinator: coordinates registration, helpers, and +breakout rooms.

    +
      +
    • Exercise leader coordinator: Onboards exercise leaders

    • +
    • Host: Manages the learner breakout rooms, learner questions, +etc. (often the registration coordinator)

    • +
    • Advertisement coordinator: Advertises and outreaches

    • +
    +
  • +
  • Under both registration coordinator and instructor coordinator

    +
      +
    • HackMD manager: always watches and formats HackMD and +publishes it same-day. “Eyes on the ground” via HackMD and chat +and quickly communicates important information to instructor and +registration coordinators.

    • +
    +
  • +
  • Learner: attends and learns

  • +
  • Exercise leader: serves as a guide to the team, receives small +amount of training before the workshop.

  • +
+
+
+

Exercises

+
+

How many people teach in your workshops?

+
    +
  • Using HackMD, make a histogram of how many (instructors + +organizers) you typically have in your workshops.

  • +
  • List some of the common roles you have used.

  • +
+
+
+
+

See also

+

(none yet)

+
+
+
+
+
+

Why are computers hard?

+

Most of the time, when teaching, our difficulty is not what you expect.

+
+

Initial reading

+

Read the following:

+ +

Of each of the points made, how many are related to:

+
    +
  • The computing itself

  • +
  • The user interface

  • +
  • The ability of the user to work in the computing environment

  • +
  • Something else

  • +
+
+
+

Usability

+

As said in the text above:

+
+

Most user interfaces are terrible. When people make mistakes it’s +usually the fault of the interface. You’ve forgotten how many ways +you’ve learned to adapt to bad interfaces. You’ve forgotten how +many things you once assumed that the interface would be able to +do for you.

+
+
+
+

Deep abstraction layers

+

Most technology is built on abstraction layers, for good reason. They +help simplify implementation and understanding.

+
+

Exercise

+

Think of a tool or technology that is easy to understand and use if +you understand the underlying abstraction layers, but is almost +impossible otherwise.

+
+
+
+

Conclusion: what are we teaching, then?

+

As teachers of computing, we fill a critical role that is more +determined by our audience, than the technology we are teaching.

+
+
+

See also

+

(none yet)

+
+
+
+

Diversity and inclusion

+

When we are teaching, we fill a critical role in between people and +technology. We are not un-involved technical staff teaching asocial +topics, but we are very connected to the social context of the tools. +Unfortunately, there are major demographic imbalances in most +computing.

+
+

Primary articles

+ +
+
+

Support services vs diversity

+

Study this presentation by Richard Darst:

+ +

Summary:

+
    +
  • Computing is hard and quite often our ability to learn quickly is +connected to our social group.

  • +
  • Good technical services serve the role of mentors

  • +
  • This mentorship helps to equalize

  • +
  • Our entire system of research should be configured for more +equality. Modernization usually takes it the other way.

  • +
+
+
+

Exercises

+
+

Reflect on how your job can be defined to promote diversity.

+

What are some (possibly surprising) ways that your job promote +diversity and equality among people of different backgrounds?

+
+
+
+

See also

+

(none yet)

+
+
+
+

Placeholder

+
+
+
+
+

Lesson development with version control

+

So, we want to practically share. We have these minimum requirements:

+
    +
  • Someone can get the preferred form of modification, to improve +without limitation.

  • +
  • It is trivial to track differences and send the changes back to the +source, with little cost to the original maintainer.

  • +
+

Especially with the second of these, version control in an online +platform seems to be the only reasonable option.

+
+

Version control and static site generators

+

CodeRefinery and the Carpentries use git and Github to develop +lessons. The general procedure is this:

+
    +
  • Version control to store the raw files in text format

  • +
  • A static website compiler to convert them to HTML files

  • +
  • Serving to the public via Github Pages (but this could be replaced +with other systems)

  • +
+

This allows for true collaborative development and community +contributions.

+

Carpentries uses a custom website complierer based on R, CodeRefinery +uses the Sphinx documentation engine which is used in many different +projects for documentation. CodeRefinery’s use of a standard tool +allows us to build on a huge and growing ecosystem of extensions and +themes, and promotes local reuse.

+

The exact static website generator used isn’t so important, as long as +some form of version control is used.

+

A open-source license is the last bit to consider: without a license, +it can’t be reused and passed on, and there is little incentive for +someone to contribute.

+
+
+

CodeRefinery lesson tools

+

CodeRefinery uses the following tools to actually make its lessons +right now:

+
    +
  • Sphinx (a common documentation +generator, widely used in open source projects in general)

  • +
  • The sphinx-lesson, which is more of +a small collection of other extensions than new development itself.

  • +
  • Github for hosting lessons: https://github.com/coderefinery/

  • +
  • Github Actions and Github Pages for building and web serving our +lessons.

  • +
+
+
+

Exercises

+
+

Contribute to a sample lesson

+
    +
  • Open this very lesson in GitHub (it uses the same format as +typical CodeRefinery lessons): +https://github.com/coderefinery/community-teaching/

  • +
  • Browse the files and understand the general idea. Check out at +least these and use HackMD to record their functions:

    +
      +
    • .github/workflows/sphinx.yml

    • +
    • content/conf.py

    • +
    • content/index.rst

    • +
    • content/lessons-with-version-control.rst

    • +
    +
  • +
  • If you want, try to make a pull request to this lesson. It +doesn’t have to have any significant content, it can be a pure +test pull request.

  • +
+
+
+

(advanced) Create your own lesson

+

Use the +sphinx-lesson-template +to create a new lesson of your choice. Alternatively, use the current +Carpentries system, or some other system of your choice.

+
+
+
+

Recommendations and lessons learned

+
    +
  • Convert feedback about lessons and suggestions for improvements into issues +so that these don’t get lost.

  • +
  • Make your lesson citable: get a DOI.

  • +
  • Credit contributors (not only Git commits).

  • +
  • Instructor guide is essential for new instructors.

  • +
  • Lesson changes should be accompanied with instructor guide changes (it’s like +a documentation for the lesson material).

  • +
  • Apply and validate Backwards lesson design again and again.

  • +
  • Make it possible to try out new ideas (by making the lesson branch-able).

  • +
  • Before making larger changes, talk with somebody and discuss these changes.

  • +
  • For substantial changes we recommend to first open an issue and describe your +idea and collect feedback before you start with an extensive rewrite.

  • +
  • For things still under construction, open a draft pull request to collect +feedback and to signal to others what you are working on.

  • +
+
+
+

See also

+ +
+
+
+

Backwards lesson design

+

It happens far too often: someone creates a lesson, but they think +about what is interesting to them, not what is important for the +learners. In fact, an earlier version of this instructor training had +this very issue.

+

It is critical to backwards design almost any piece of communication, +especially something as widespread as teaching.

+
+

The approach

+
    +
  • You don’t think about how to do something and try to explain it.

  • +
  • Avoid the typical approach “I want to show a number of things which I think are cool about +tool X - how do I press these into 90 minutes?”

  • +
  • Instead, you start defining your target audience by answering to questions +such What is the expected educational level of my audience?, Have they +been already exposed to the technologies I am planning to teach?, What +tools do they already use?, What are the main issues they are currently +experiencing?. It is important to discuss these points with a group of +colleagues, preferably from diverse backgrounds and institutions to reduce +biases. Once you clarified your target audience, it is useful to create +learner personas; that will help you during the development process by +providing concrete examples of potential learners showing up at your +workshops. For each learner personas, try to think of what is useful to +them: “What do they need to +remember/understand/apply/analyze/evaluate/create?”. +Asking and answering to these questions will allow you to define the +background knowledge (starting points) and goals (end points) of your +learners. Then, you create a sequence of exercises which test incrementally +progressing tasks and acquisition of the new skills (from starting to end +points).

  • +
  • Then, you write the minimum amount +of material to teach the gap between exercises.

  • +
+
+
+

The process

+

As described in “A lesson design process” in the book Teaching Tech +Together:

+
    +
  1. Understand your learners

  2. +
  3. Brainstorm rough ideas

  4. +
  5. Create an summative assessment to know your overall goal

    +
      +
    • CodeRefinery translation: think of the things your learners will +be able to do at the end of the lesson. Think simple! The +simpler the better. Think of three main points they will +remember, of which maybe one or two are a concrete skill.

    • +
    +
  6. +
  7. Create formative assessments to go from the starting point to this.

    +
      +
    • CodeRefinery translation: think of some engaging and active +exercises.

    • +
    +
  8. +
  9. Order the formative assessments (exercises) into a reasonable order.

  10. +
  11. Write just enough material to get from one assessment (exercise) to +another.

  12. +
  13. Describe the course so the learners know if it is relevant to them.

  14. +
+

We can’t emphasize enough how important it is to know your end +state and keep it simple.

+
+

Example: designing an HPC Carpentry lesson

+

Let’s take as an example the HPC Carpentry lesson

+

Target audience

+
    +
  • What is the expected educational level of my audience?

    +
      +
    • A PhD student, postdoc or young researcher.

    • +
    +
  • +
  • Have they been already exposed to the technologies I am planning to teach?

    +
      +
    • The word HPC is not new to them and they may have already used an HPC but are still not capable of giving a proper definition of HPC. In addition, we do not expect them to know much about parallelism and they cannot make any distinction between various available parallelism paradigms.

    • +
    +
  • +
  • What tools do they already use?

    +
      +
    • serial codes, multi-threaded codes, data parallelism; usually out-of-the-box tools.

    • +
    • they may have tried to “scale” their code (multiprocessing, threading, GPUs) with more or less success.

    • +
    +
  • +
  • What are the main issues they are currently experiencing?

    +
      +
    • they cannot solve their problems either because they would like to run the same code but with many different datasets or because their problem is larger (more computations/memory).

    • +
    • most of the time they know their codes can run on HPC (from the documentation) but never really had the opportunity to try it out.

    • +
    • Very few will have their own codes where they may have tried different things to speed it up (threading, task parallelism) but have no clear strategy.

    • +
    +
  • +
+

Learner persona

+
    +
  • Sonya is a 1st year PhD student: she recently moved to Oslo and joined the +Computational and Systems Neuroscience group. She will be using the +NEST, a simulator for spiking +neural network model. She used NEST during her master thesis but on her +small cluster: she never used an HPC resource and is really excited about it.

  • +
  • Robert is a field ecologist who obtained his PhD 6 months ago. He is now +working on a new project with Climate scientists and as a consequence will +need to run global climate models. He is not very familiar with command +line even though he attended a Software Carpentry workshop and the idea to +use HPC is a bit terrifying. He knows that he will get support from his +team who has extensive experience with HPC but would like to become more +independent and be able to run his own simulations (rather than copying +existing cases).

  • +
  • Jessica is a postdoc working on a project that investigates numerically the +complex dynamics arising at the tip of a fluid-driven rupture. Fluid +dynamics will be computed by a finite element method solving the +compressible Navier-Stokes equations on a moving mesh. She uses a code she +has developed during her PhD and that is based on existing libraries. She +has mostly ran it on a local desktop; her work during her PhD was very +limited due to the lack of computing resources and she is now very keen is +moving to HPC; she knows that it will requires some work, in particular to +parallelize her code. This HPC training will be her first experience with +HPC.

  • +
+

Learning outcomes

+
    +
  • Understand the difference between HPCs and other local/remote machines

  • +
  • Understand the notion of core, nodes, cluster, shared/distributed memory, etc.

  • +
  • Understand the notion of login nodes.

  • +
  • Understand the need for a scheduler and how to use it appropriately

  • +
  • Understand why optimising I/O is important on HPC and how to best use HPC filesystems

  • +
  • Understand the need to parallelize (or use existing parallel) codes and in which cases HPCs is a must (when communications is required)

  • +
  • Understand how to get your code ready to use on HPC (access to libraries, installation of your own libraries/software, etc.)

  • +
  • Understand that an HPC is an operational machine and is not meant for developing codes.

  • +
+

Exercises

+
    +
  • Get basic information such the number of CPUs, memory from your laptop and try to do the same on a HPC. Discuss outcomes.

  • +
  • Try to create files on the different filesystems on your HPC resource and access them.

  • +
  • Create different types of job scripts, submit and check outputs.

  • +
  • Make a concrete example to run a specific software on your HPC (something like GROMACS).

  • +
+
+
+
+

Exercises

+
+

Backwards-design a lesson/topic

+

Choose a simple lesson topic and apply backwards lesson design. You +won’t get all the way through, but come up with a logical +progression of exercises.

+

The section you pick should require screen sharing and be of some follow-along +task (preferably using a shell).

+

Some suggestions:

+
    +
  • Regular expressions

  • +
  • Making papers in LaTeX

  • +
  • Making figures in your favorite programming language

  • +
  • Linux shell basics

  • +
  • Something non-technical, such as painting a room

  • +
  • An instructor training for CodeRefinery

  • +
  • Some aspect from an already existing lesson

  • +
  • Introduction to high-performance computing (or an episode therein)

  • +
  • Unix shell in a HPC context (or an episode therein)

  • +
  • A lesson you always wanted to teach

  • +
+
+
+
+
+
+
+

Possibilities for Carpentries

+
+

Keypoints

+
    +
  • Carpentries is currently designed around small workshops, so many of these ideas can’t directly apply

  • +
  • Yet many of these tools and also team teaching can still be used

  • +
  • You can run your own breakout room for any of our workshops

  • +
  • Join as observer if you want to see our workshop organization and tools in action

  • +
+
+

CodeRefinery workshops can be a good progression step after taking a +Carpentries workshop.

+

Helping out at a CodeRefinery workshop as exercise lead can be a good +progression step for those who have helped out at a Carpentries workshop or who +have taken the Carpentries instructor training.

+
+
+

CodeRefinery’s plans

+
+

Keypoints

+
    +
  • We are continuing to focus on online-first with local breakout rooms

  • +
  • We welcome people joining us, either individually or as an organization

  • +
  • Still interested in collaboration with Carpentries

  • +
  • We need to become better at marketing and outreach

  • +
+
+
+

Biggest open problems

+
    +
  • How to give helpers and contributors more credit and visibility

  • +
  • How to promote/engage new members

  • +
  • What are we? Non-profit? Institution collaboration network? Selling services?

  • +
  • Funding and sustainability (but we have ideas: collaboration network)

  • +
+
+
+

How you can join

+

Individual level:

+
    +
  • Join CodeRefinery +chat

  • +
  • Lead a team, co-teach, or help organize a workshop

  • +
  • Generally provide marketing and outreach

  • +
+

Organization level:

+
    +
  • Have your organization join CodeRefinery

  • +
  • Officially co-advertise and co-teach workshops

  • +
  • Run local breakout rooms and join a workshop as a team

  • +
  • Send an observer to a workshop

  • +
+
+
+

Aside: Nordic-RSE (research software engineers)

+ +
+
+
+
+
+

Other resources

+ +
+
+

Instructor’s guide

+

In a lesson that was further developed, this would include an +instructor’s guide that mentioned:

+
    +
  • Background of why the course is how it is

  • +
  • Recommendations of teaching it

  • +
  • Known pitfalls of teaching it, so that other instructors can avoid +them

  • +
  • Possibly how to contribute, long-term plans, etc.

  • +
+

For example, see git-intro’s instructor guide.

+
+
+

Exercise list

+

This is a list of all exercises and solutions in this lesson, mainly +as a reference for helpers and instructors. This list is +automatically generated from all of the other pages in the lesson. +Any single teaching event will probably cover only a subset of these, +depending on their interests.

+
+
+
+
+

CodeRefinery teaching philosophies

+
+

Ice-breaker in groups (20 minutes)

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also +Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+

Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops.

+

It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us.

+
+

Video recordings

+

Recently we have recorded some of the below as videos: +https://www.youtube.com/playlist?list=PLpLblYHCzJAAHF89P-GCjEXWC8CF-7nhX

+
+
+

Anne Fouilloux

+

I regularly teach Carpentries workshops so I try to apply what I have learnt to CodeRefinery workshops. However, I know our target audience is very much different and that I need to adapt my teaching style. I am still trying to find what works best in which situations and this is why I like so much CodeRefinery workshops. We usually have a wider range of skills and very mixed backgrounds so we usually have to be more careful with the pace and time given for exercises.

+

Some considerations:

+
    +
  • I spend quite a lot of time reading the CodeRefinery material and practising myself exercises. I particularly like to read the instructor notes just before teaching: they usually highlight important aspects both for preparing and teaching.

  • +
  • I usually do not show too much in advance the material as I think it prevents asking questions. If you have less competent practitioners in the classroom, they can easily copy-paste to avoid slowing down the entire classroom.

  • +
  • Ideally, I’d like to give several exercises so anyone can work at its own pace. I find it is important that everybody gets something different from the workshop.

  • +
  • I love breaks as it gives us an opportunity to discuss with attendees on their research topics. I am especially interested to understand what software they write and how they plan to use what they learn during our workshops.

  • +
+
+
+

Bjørn Lindi

+

My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this “BLOB” (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the “BLOB”, to be able to share it with others.

+

In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic.

+

When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson.

+

Tools that I find useful in preparing a lesson is concept maps and Learner Personas, though I have develop to few them.

+ +
+
+

Thor Wikfeldt

+

I never want to leave any learner behind and I really don’t like seeing confused, blank faces in the classroom. +At the same time I sometimes worry about some participants getting bored if a lesson is progressing slowly. +This is always a difficult compromise and something I struggle with!

+

I try to focus on making concepts intuitive, to “make sense” to the learners. Of course this is usually +based on how I learned the topic myself and how it makes sense to me.

+

I try to establish connections between topics: “this thing here is similar to what we saw in the previous +lesson where we learned about X…”.

+

Before mastering a lesson by teaching in many times I try to “follow the script”. After becoming very +familiar with a lesson I start to improvise more and react more dynamically to questions, e.g. by taking a +detour to explain a confusing topic more clearly.

+

What I think I do too often: copy-paste code/text from lesson material. This can leave learners behind - +typing out the code and describing it is slower, but more learning takes place. More advanced learners +will hopefully “be compensated” by interesting advanced exercises which follow.

+
+
+

Stefan Negru

+

A lesson is a conversation, it is useful if both the trainer and the trainee are engaged. +For that reason I try to have, most of the time, a conversation with the classroom and +after we finish parts of a lesson, step back and see how we might use what we learned.

+

That brings me to another point I follow throughout the lessons, answering questions like:

+
    +
  • How can we apply in practice what we just learned?

  • +
  • Do you see yourself (the trainee) using that in practice, why or why not?

  • +
+

Most of the times those seem like open-ended questions to the trainees that just learned +something new, so I try to find examples, most of the times from personal experience.

+

Last thing is that analogies are important when I teach, I try to find analogies in order +to simplify a convoluted part of a lesson.

+
+
+

Radovan Bast

+

My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos.

+

My goal for a lesson is to spark curiosity to try things after the lesson, +both for the novices (“This looks like a useful tool, I want to try using it +after the workshop.”) and the more experienced participants (“Aha - I did not +know you could do this. I wonder whether I can make it work with X.”). I like +to start lessons with a question because this makes participants look up from +their browsers.

+

Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise.

+

For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate +the answer.

+

I try to avoid jargon and “war stories” from the professional developers’ +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid “customer”, +“production”, also a lot of Agile jargon is hard to relate to.

+

Less and clear is better than more and unclear. Simple examples are better +than complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +“simply”, “just”, “easy”. If participants take home one or two points from +a lesson, that’s for me success.

+

I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don’t want to +be surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or +slide. This allows me to skip and distill the essence and not read bullet +point by bullet point.

+

I try to never deviate from the script and if I do, be very explicit about +it.

+

A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel.

+

I find it very helpful if there is somebody else in the room who helps me +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson but when doing that to +others, I am often worried of interrupting their flow and timing too much.

+

A mistake I often do is to type too fast and in my mind I force myself +to slow down.

+
+
+

Sabry Razick

+

My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case.

+
+
+

Juho Lehtonen

+

I’m gradually realising the different ways to get a hint whether the workshop +participants are still following or perhaps bored. I assume it’s communicating +with the class, with exercises and simply by asking now and then. I also try +to remember to observe how people look like (puzzled, bored) while I teach, not +so obvious for me.

+

I believe that learners communicating with each other, in addition to with +instructors and helpers, really helps them to understand things faster. (At least +it helps me). So I try to make sure that no one sits or works alone at the workshops.

+
+
+

Richard Darst

+

Like many people, I’ve often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I’ve realized long ago that my most important lessons weren’t +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I’ve realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds.

+

My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I’m often start at the +very basics, because this is what I see missing most often.

+

When teaching, I like lots of audience questions and don’t mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don’t have to know everything perfectly, just show how +you’d approach a problem.

+
+
+

João M. da Silva

+

I started giving technical trainings twenty years ago, and hence my perspective +is perhaps more inclined towards the development of hands-on abilities and +capability to solve problems, independently or in a team.

+

But the development of hands-on practical skills, requires some essential +knowledge about the domain and some willingness to try different approaches +in case one gets stuck. Some call this the “KSA approach” +(“Knowledge-Skills-Attitude). Hence, I +try to impart the essential knowledge (and where to find out more) at my +trainings. And to encourage and challenge students in order to make them +overcome their self-perceived limits (e.g. “I’m a Humanist, I can’t use +Python virtualenv”).

+

I’ve been trying to study more about the Cognitive aspects of learning over the years, +and I should find out the time to return to that. There’s very interesting +research in Problem Solving, with Learning being a important component in that domain.

+

Storytelling: humans are neurologically made for paying attention to good +stories, and that’s something that I try to put into account: to give +a lesson like it would be a relevant narrative for the students, one that they +could relate to and help them in their work

+

I like to draw and be creative with that, but have to pay attention to +my handwriting during my trainings. I reckon that Architectural diagrams +help students to understand the big picture, so I should invest more on +those when development training material. I would also like to start looking into +Concept Maps and Semantic Trees in training.

+
+
+
+

Interactive teaching style

+
+

What are the top issues new instructors face?

+ +
+
+
+

The Carpentries and CodeRefinery approaches to teaching

+

Here we will give you a very short overview of the Carpentries approach to teaching and highlight +parts that are most important for teaching CodeRefinery style lessons.

+

Most CodeRefinery instructors have completed the +Carpentry instructor training workshop, which +anyone can apply for

+
+

This material

+

This section is derived from the +Carpentries instructor training material. +We encourage you to further study this material later, and to sign up for a 2-day Carpentry +intructor training workshop.

+
+
+
+

Key principles

+

The “Carpentries” approach to teaching is based on:

+
    +
  • Applying research-based teaching principles, especially as they apply to the +Carpentries audience.

  • +
  • Understanding the importance of a respectful and inclusive classroom environment.

  • +
+
+
Carpentries teaching principles
+
    +
  • Learners need to practice what they are learning in real time and get feedback on what they +are doing. That is why the teaching approach relies on live coding.

  • +
  • Learners best learn in a respectful classroom environment, so the Carpentries use a +Code of Conduct.

  • +
  • Learners are encouraged to help each other during workshops as this improves their confidence +and reinforces concepts taught.

  • +
  • Carpentry instructors try to have learners do something that they think is useful in their +daily work within 15 minutes of starting each lesson.

  • +
+

What to Teach

+

In CodeRefinery, we follow The Carpentries teaching principles but in addition to live coding +we often use group discussions to put in context the concepts we are teaching.

+

Applying these teaching principles are not sufficient and in addition we need to be able to check +the effectiveness of our methods.

+
+
+
+
+

On the importance of feedback

+

Feedback is an essential part of effective learning. Feedback is bi-directional:

+
    +
  • To be effective, instructors need feedback on their learners’ progress. Learners can also check their progress and ask relevant questions to get clarification.

  • +
  • Instructors also need feedback on their teaching. For instance, this can help them to adapt the pace, add/skip optional exercises and improve their teaching.

  • +
+
+
Getting/giving feedback on learners’ progress
+

This feedback comes through what is called formative assessments (in contrast +to summative assessment).

+
+

Summative Assessment

+

Summative assessment is used +to judge whether a learner has reached an acceptable level of competence. +Usually at the end of a course +Learners either “pass” or “fail” a summative assessment. +One example is a driving exam, +which tells the rest of society whether someone can safely be allowed on the road. Most assessment done in university +courses is summative, and is used to assign course grades.

+
+
+

Formative assessment

+

Formative assessment takes place during teaching and learning. It sounds like +a fancy term, but it can be used to describe any interaction or activity +that provides feedback to both instructors and learners about learners’ level of understanding of the +material. For learners, this feedback can help focus their study efforts. For instructors, it allows them to refocus +their instruction to respond to challenges that learners are facing. +Used continuously

+
+

Learners don’t “pass” or “fail” formative assessments; they are simply a feedback mechanism. +For example, a music teacher might ask a learner to play a scale very slowly +in order to see whether they are breathing correctly, +and if not, what they should change.

+

Formative assessment is most useful when it happens frequently (we’ll talk about how frequently later) +and when the results are easily interpretable by the learner and instructor.

+

CodeRefinery uses different instruments to get feedback from learners:

+
    +
  • Surveys: we will discuss about CodeRefinery pre/post-surveys in the episode +Running a workshop: online.

  • +
  • Exercises: we have many exercises during CodeRefinery workshops and use polls too but not necessarily many multiple-choice questions. +This is something that we may change in the future but the initial reason was that we build on existing knowledge +(see below section on our target audience) and give recommendations for best software practices: +there is no unique solution and you would like our learners to choose the approach that is most suitable for them. +For the same reasons, we have many optional exercises to accommodate the different levels. +We would like everyone to get something useful out of the CodeRefinery workshops.

  • +
+
+
+
Getting/giving feedback on teaching
+

Teaching is a skill. One of the objective of the CodeRefinery Instructor training is to give you +the confidence in teaching CodeRefinery lessons. Later we will have group work where we will +practice teaching some lessons.

+

Before doing so, we will learn here to give feedback on teaching using the same +positive-vs-negative and content-vs-presentation rubric.

+
+

Give feedback on teaching (optional, 10 mn)

+

This exercise aims at learning to give feedback. It is optional as we have +similar exercises when practising teaching). +As a group, we will watch this video of teaching and +give feedback on two axes: positive vs. negative and content vs. presentation. Have each person in +the class add one point to a 2x2 grid on a whiteboard or in the shared notes (hackMD, etherpad, google doc) without duplicating any points. +For online instructor training event, use breakout room (4-5 persons per group) to facilitate discussion. Then each group reports to the shared notes. +You can use a rubric (used during The Carpentries teaching demos) to help you take notes. +What did other people see that you missed? What did they think that you strongly agree or disagree with?

+
+
+
+
+
+

Who are the learners

+

The first task in teaching is to figure out who your learners are. The Carpentries approach is +based on the work of researchers like Patricia Benner, +who applied the +Dreyfus model of skill acquisition +in her studies of +how nurses progress from novice to expert +(see also books by Benner). +This work indicates that through practice and formal instruction, learners acquire skills and advance +through distinct stages. In simplified form, the three stages of this model are:

+
+
Novices, competent practitioners and experts
+

Novice, Competent Practitioner, Expert

+
    +
  • Novice: someone who doesn’t know what they don’t know, i.e., +they don’t yet know what the key ideas in the domain are or how they relate. +One sign that someone is a novice is that their questions “aren’t even wrong”.

    +
      +
    • Example: A novice learner in a Carpentries workshop might never have heard of the bash +shell, and therefore may have no understanding of how it relates to their file system or +other programs on their computer.

    • +
    • Example HPC: A learner who has never executed a program on remote computer in headless mode

    • +
    • Example HPC: A learner who has no understanding about using a queue system and having a +hard time why a program can not be run directly after login in.

    • +
    +
  • +
  • Competent practitioner: someone who has enough understanding for everyday purposes. +They won’t know all the details of how something works and their understanding may not +be entirely accurate, but it is sufficient for completing normal tasks with normal +effort under normal circumstances.

    +
      +
    • Example: A competent practitioner in a Carpentries workshop might have used the shell +before and understand how to move around directories and use individual programs, but +they might not understand how they can fit these programs together to build scripts +and automate large tasks.

    • +
    • Example: A competent practitioner in a CodeRefinery workshop is someone that understands +the concepts of best software practices and its importance. He/she clearly sees the +benefits of applying best software practices but he/she does not fully know yet how and +what to use for their own projects.

    • +
    • Example HPC: Knows how to establish a connection to a cluster and have submitted jobs. +But may not know how to request optimal amount of resources in a job and how to setup +parallel jobs

    • +
    +
  • +
  • Expert: someone who can easily handle situations that are out of the ordinary.

    +
      +
    • Example: An expert in a Carpentries workshop may have experience writing and running shell +scripts and, when presented with a problem, immediately sees how these skills can be used +to solve the problem.

    • +
    • Example HPC: A learner who has a good understanding of the queue system, parallel processing +and understand how to interpret error reports when something goes wrong and knows how to +get help.

    • +
    +
  • +
+
+
+
Cognitive Development and Mental Models
+

Effective learning is facilitated by the creation of a well-founded mental model. A mental model +is a collection of concepts and facts, along with the relationships between those concepts, which +a person has about a topic. For example, a long-time resident of the United States may have an +advanced understanding of the location of US states, major cities and landmarks, weather patterns, +regional economies and demographic patterns, as well as the relationships among these, compared +with their understanding of these relationships for other countries. In other words, their mental +model of the United States is more complex compared with their mental model of other countries.

+

We can distinguish between a novice and a competent practitioner for a given domain based +on the complexity of their mental models.

+
    +
  • A novice is someone who has not yet built a mental model of the domain. +They therefore reason by analogy and guesswork, borrowing bits and pieces +of their mental models of other domains which seem superficially similar.

  • +
  • A competent practitioner is someone who has a mental model that’s good enough +for everyday purposes. This model does not have to be completely accurate in order +to be useful: for example, the average driver’s mental model of how a car works +probably doesn’t include most of the complexities that a mechanical engineer +would be concerned with.

  • +
+

We could expect a mixture of learners from novice and competent practitioner groups +in HPC training events.

+

Mental Models

+
+
+
+
How “knowledge” gets in the way
+

Mental models are hardly ever built from scratch. Every learner comes to a topic with +some amount of information, ideas and opinions about the topic. This is true even in +the case where a learner can’t articulate their prior knowledge and beliefs.

+

In many cases, this prior knowledge is incomplete or inaccurate. Inaccurate beliefs +can be termed “misconceptions” and can impede learning by making it more difficult for +learners to incorporate new, correct information into their mental models. +Correcting learners’ misconceptions is at least as important as presenting them with +correct information. Broadly speaking, misconceptions fall into three categories:

+
    +
  • Simple factual errors, such as believing that Vancouver is the capital of +British Columbia. These are the easiest to correct.

  • +
  • Broken models, such as believing that motion and acceleration must be in the +same direction. We can address these by having learners reason through examples to +see contradictions.

  • +
  • Fundamental beliefs, such as “the world is only a few thousand years old” or +“human beings cannot affect the planet’s climate”. These beliefs are deeply connected +to the learner’s social identity and are the hardest to change.

  • +
+

The current HPC carpentry workshop material are aimed at Novice of HPC

+

Among Novice learners there might be learners who are experts in their domain and very +competent in the program they are executing, but may not have used a HPC system before. +Then among the competent practitioners There might be learners who repeat some procedures +they have inherited but lack a in-depth understanding of what’s going on. That is why it is +important to get accurate feedback, before and during the workshops to understand the learner profiles.

+
+

Exercise: How to identify learner profiles?

+
    +
  1. How to identify leaner profiles from surveys and during the class

  2. +
  3. Which types of learners should the leassons focus on

  4. +
+
+
+
+
+
+

CodeRefinery Curriculum and Reverse Instructional Design (with recommendations for HPC carpentries)

+

When writing a CodeRefinery lesson, we take a “reverse” approach to instruction, +as described in Wiggins and McTighe’s +Understanding by Design, +that keeps the focus firmly on learning outcomes. The order of preparation in this case becomes

+
    +
  • Determine your learning objectives

  • +
  • Decide what constitutes evidence that objectives have been met, and design assessments +to target that evidence

  • +
  • Design instruction: Sort assessments in order of increasing complexity, +and write content that connects everything together

  • +
+
+
Working with learning objectives
+

Each CodeRefinery lesson (also the HPC capentries lessons) usually has a learning objectives section. +Good learning objectives are quite specific about the intended effect of a lesson on its learners. +We aim to create learning objectives that are specific, accurate, and informative for +both learners and instructors.

+
+
+
Using Bloom’s Taxonomy to write effective learning objectives
+

Bloom’s Taxonomy is a framework for thinking about learning that breaks progress down into discrete, hierarchical steps. +While many ideas have come and gone in education, Bloom’s has remained a useful tool for educators, in particular because the +hierarchy seems to be reasonably valid: outcomes at the top of the hierarchy cannot be achieved without mastery of outcomes at +the bottom. In the long term, everybody wants to be at the top. However, in aiming to meet learners where they are, we also +need to be mindful about helping them to “grow a level,” helping them to recognize when they have achieved that growth, and +guiding them to look ahead to where we might not be able to take them.

+

Bloom's Taxonomy

+

Image credit: Vanderbilt University Center for Teaching

+
+
+
Revisiting Learning objectives
+

When using existing teaching material, reverse instructional design principles might be applied as +follows:

+
    +
  1. Review the lesson’s learning objectives carefully, thinking about how they will work for your audience

  2. +
  3. Scan the lesson to identify promising points to check in with your learners, using formative assessment to verify that objectives have been met

  4. +
  5. Review the connecting content in detail to be sure everything works and you have anticipated likely problems and questions.

  6. +
+

We strongly encourage you to read them before teaching a lesson and to review whether they still match the content of the lesson:

+
+
+
+
+

Workshop manuals

+

CodeRefinery maintains a number of workshop manuals +with most of the “primary” information. This episode condenses this +into a quick overview.

+
+
+

Running a workshop: online

+
+

Online teaching discussion

+
+

Discussion: Online vs in-person

+

In notes:

+
    +
  • Compare and contrast the benefits of online teaching with +in-person: {advantage, disadvantage} × {content, presentation}

  • +
  • How do you have to prepare differently?

  • +
  • What are your own experiences?

  • +
+
+
+
+

Case study: Mega-CodeRefinery and Finland HPC Kickstart

+
    +
  • Mega-CodeRefinery

    +
      +
    • Audience of around 90-100

    • +
    • “bring your own breakout room” (see below)

    • +
    • 3 days/week, 6 days total

    • +
    • Lessons as normal in CodeRefinery

    • +
    +
  • +
  • HPC Kickstart

    +
      +
    • 250 registered, ~180 max participants

    • +
    • Multi-university: local differences made this much harder to manage.

    • +
    • Breakout rooms not pre-planned.

    • +
    +
  • +
+

Mega-CodeRefinery worked very well, HPC kickstart didn’t - but not +because of the size.

+
+
+

General workshop arrangements

+ +
    +
  • Select a coordinator, recruit instructors (at least 3 is important), +find helpers

  • +
  • Find a good lecture room: +requirements

  • +
  • Set up workshop webpage using the [Github, template +repository](https://github.com/coderefinery/template-workshop-webpage]: +see +manuals

  • +
  • Advertising the workshop

  • +
  • Communication with registered participants

  • +
+
+
+

CodeRefinery online scaling strategy

+
    +
  • We started online workshops in 2020 March, for the obvious reasons.

  • +
  • First, we started with two “normal size” (20 people) practice +workshops

  • +
  • Then we did a 100 person workshop. It went well, but there is less +tolerance for problems.

  • +
+
+
Basic preparation
+
    +
  • You need more breaks are needed

  • +
  • People have a way of doing too many things and not focusing.

  • +
  • How to attend an online +workshop” +guide to prepare learners

  • +
+
+
+
Basic platform: Zoom
+
    +
  • Zoom (not the most ethical, but worked well and was available)

  • +
  • Zoom mechanics: instructions for +students.

    +
      +
    • Mostly things that are known

    • +
    • We don’t use Zoom interaction features much anymore +(faster/slower/etc), but breakout rooms and HackMD instead

    • +
    +
  • +
  • See also: Online training +manual +(which is getting a bit old compared to what is below).

  • +
+
+
+
Breakout rooms, bring your own team
+
    +
  • Breakout rooms are

    +
      +
    • Static: same people across whole workshop

    • +
    • Contain one helper per room (see below)

    • +
    +
  • +
  • Team registration: accept a “team” field when registering, people on the +same team are put together.

    +
      +
    • Gives motivations for learners to bring their colleagues and +learn together.

    • +
    • More than one person learning together greatly increases update

    • +
    +
  • +
  • You need a powerful enough registration system to assign rooms and +email them to people!

  • +
  • We ask people to name themselves “(N) Firstname Lastname” or “(N,H) +Firstname Lastname” for helpers. Then it is fast to assign them to +their designated breakout rooms.

  • +
  • See also: Breakout room +mechanics

  • +
+
+
+
Helper training
+
    +
  • Each breakout room has a helper

  • +
  • Helper should be a little bit familiar, but not expected to be able +to answer all questions.

  • +
  • Special, custom helper +training +since helpers make or break the workshop

  • +
  • Helper recruitment:

    +
      +
    • Our networks

    • +
    • Team registration: if a team registers with their own helper, then +they are guaranteed to get in together. “bring your own breakout +room”

    • +
    • Former learners, ask them to come back.

    • +
    +
  • +
  • Two helper trainings the week before the workshop.

  • +
+
+
+
Staff roles
+

To reduce stress on any one person, we clearly define the different +roles and try to avoid overlap. We actually have enough people for +all of these, so it works well.

+
    +
  • Workshop coordinator

    +
      +
    • Registration, etc.

    • +
    +
  • +
  • Zoom host

    +
      +
    • Handles registration, breakout rooms, recording, Zoom chat.

    • +
    +
  • +
  • HackMD helper

    +
      +
    • Dedicated to watching HackMD and answering questions quickly.

    • +
    • Host on manuals

    • +
    +
  • +
  • Expert helpers

    +
      +
    • “Spare hands” who rotate between breakout rooms and make sure +helpers are doing well.

    • +
    • Give feedback to instructor about how breakout rooms are going.

    • +
    • Take the place of missing helpers.

    • +
    • Easy way for any people with a bit of spare time to help out.

    • +
    • Expert helpers in workshop

    • +
    +
  • +
  • Instructors

    +
      +
    • Teach, they shouldn’t overlap with the above roles (but serve as +expert helpers other times).

    • +
    • Usually also improve the lesson a bit before teaching

    • +
    • General staff intro in manuals

    • +
    +
  • +
  • Workshop preparation meeting

    + +
  • +
+
+
+
HackMD
+
    +
  • We’ve been using it here

  • +
  • Chat doesn’t work wen large, written +document does.

  • +
  • HackMD can just about scale to ~100 person workshop. Recommend +learners keep it in view mode while not editing.

  • +
  • Voice questions are still allowed, but will be recorded. Staff +raise important questions from HackMD to the instructor immediately.

  • +
  • HackMD also allows communication when in breakout rooms.

  • +
  • You can get multiple answers, and answers can be improved over +time.

  • +
  • HackMD +mechanics +and HackMD +helpers.

  • +
+
+
+
Recording and streaming
+
    +
  • When you have 100 people, main room is quiet anyway: you don’t lose +much by recording.

    +
      +
    • Questions anonymously in HackMD, privacy loss is not so bad

    • +
    +
  • +
  • Breakout rooms are never recorded

  • +
  • Streaming

    +
      +
    • We streamed via Twitch: https://twitch.tv/coderefinery

    • +
    • We typically get 5-40 viewers.

    • +
    • Zoom can directly send the stream to Twitch: no extra software +needed.

    • +
    • Twitch archives videos for 14 days, which allows learners to get +an instant reply (we get hundreds of views in the next days).

    • +
    • So while possibly not useful for new people to learn, the instant +reply is very useful. Instructor can also work on problems in +main stream during breakout rooms, which learners can watch +later.

    • +
    • Streamers also have access to HackMD to ask questions.

    • +
    +
  • +
  • Certain tricks needed to keep learners from appearing in recording +or stream

    +
      +
    • “Spotlight video”, host does not go to gallery view, uses dual +monitor mode. We are still figuring this out.

    • +
    +
  • +
+
+
+
Installation time
+
    +
  • People have to be ready once we start, or else everything fails.

  • +
  • Two installation help times the week before.

  • +
  • Every email emphasizes that you have to be prepared, and “requires” +you to attend workshops (but really it’s only)

  • +
  • Installation instructions include steps to verify

  • +
  • Installation instructions also include video demonstrations of +installation and verification.

  • +
  • We haven’t had that many installation problems, but also we keep the +requirements simple.

  • +
  • Helper introduction is right before software install time, so +helpers can stay and help with install if they want.

  • +
  • Design to be easy to install and get set up.

  • +
+
+
+
Other notes
+
    +
  • Make breakout sessions as long as possible: 10 minutes is really too +short. 20 minutes is a good minimum time.

  • +
  • Be very clear about exercise expectations

  • +
  • Keep HackMD updated as a log.

  • +
  • Don’t combine breaks and breakout times.

  • +
  • The more people you have, the more diverse audience you have and the +more people overwhelmed and under whelmed.

  • +
+
+
+
+

Workshop collaborations

+

Why limit ourselves to CodeRefinery workshop? Why not use our network +and techniquess for more

+
    +
  • Case study: Python for Scientific +Computing

    +
      +
    • Started by Aalto

    • +
    • Announced to CodeRefinery, five more instructors from three +countries joined.

    • +
    • Rapid collaboration, taught course shortly later.

    • +
    • Announced to all institutions. Some places had physical rooms, +some were pure online

    • +
    • Also streamed

    • +
    • It was much more fun and less stressful to work together

    • +
    +
  • +
  • We want to continue this kind of collaboration in other workshops.

  • +
+
+
+
+

How to teach online

+
+

Objectives

+
    +
  • Understand the benefits and disadvantage of online teaching, +compared to in-person

  • +
  • Set up a good screen share

  • +
  • Understand the benefits and disadvantages of team teaching

  • +
  • Prepare for the teaching practice

  • +
+
+
+

Why teaching mechanics matter

+
    +
  • When you teach, you are mainly showing a basic example for the +learner to follow along

  • +
  • The learner has a lot more to think about than you do, so you need +to minimize the possible distractions and unnecessary weirdness.

  • +
  • A learner will often only one small screen, limiting the number of +things that they can think about.

  • +
  • You are must faster than learners (5 times possibly?) You have to +do things to slow yourself down.

  • +
  • It’s easy to save these mechanics until the end, and then you run +out of time.

  • +
+
+
+

Shell sharing

+ +

When doing any demonstration, there are difficulties:

+
    +
  • If one misses something, you can’t rewind to see it - is there any +way to catch up?

  • +
  • The learner must get oriented with the whole picture, while +instructor knows precisely where to focus.

  • +
+

A good shell share has some of the following properties:

+
    +
  • Large font

  • +
  • Shell history, available separately from the main shell window

  • +
  • Closely matches the type-along instructions

  • +
+

We have a collection of shell sharing systems:

+ +
+

Discussion

+

The instructor will demonstrate several shell-sharing systems. You +will use this in the teaching practice.

+
+
+
+

Screen sharing

+
+

Discussion

+

Look at the various screen layouts in the CodeRefinery +manuals. +Use the HackMD to comment about what which are better or worse.

+ +
+
    +
  • Many learners will have a smaller screen than you.

  • +
  • You should plan for learners with only one small screen.

  • +
  • A learner will need to focus on both your screen share and their +work.

  • +
  • Sharing your a whole screen is almost always a bad idea, if you want +the learners to do anything at the same time.

  • +
  • If you constrict yourself, then your experience is more similar to +that of a learner.

  • +
+

Vertical sharing:

+
    +
  • CodeRefinery has recently started trialing a vertical share +system, where you share a vertical half of your screen.

  • +
  • This allows learners with one screen to display your screen +side-by-side with their learn

  • +
  • Zoom provides a “Share a part of screen” that is good for this.

  • +
+
+
+

Meta-talk

+

Don’t just teach, also make sure you guide the learners through the +course.

+
    +
  • You know what you just discussed, and what is coming next, but +learners are often stuck thinking about now.

  • +
  • Give a lot of “meta-talk” that is not just about the topic you are +teaching, but how you are teaching it.

  • +
  • Examples

    +
      +
    • Why you are doing each episode

    • +
    • What is the purpose of each exercise

    • +
    • Clearly state what someone should accomplish in each exercise and +how long it will take - don’t assume this is obvious.

    • +
    • What is the point of each lesson. How much should people expect +to get from it? Should you follow everything, or are some things +advanced and optional? Make that clear.

    • +
    +
  • +
+
+
+

Teach teaching

+
    +
  • Demonstration-based teaching require two different types of focus:

    +
      +
    • Doing the mechanical steps as a demonstration

    • +
    • Explaining why you are doing it

    • +
    +
  • +
  • This is a lot for one person to keep in mind, so can multiple people +work together for this?

  • +
  • Team teaching idea:

    +
      +
    • One person is doing the demonstrations

    • +
    • One person is giving the commentary about what they are doing

    • +
    • The lecture becomes a discussion between two people instead.

    • +
    +
  • +
+

Advantages:

+
    +
  • This reduces the pressure on each person (reduces demo effect)

  • +
  • You are less likely to forget things

  • +
  • It slows you down in teaching

  • +
  • It makes the lesson more interesting to listen to

  • +
  • One person can follow questions

  • +
  • Great for introducing new instructors (which half is easier to start +with?)

  • +
+

Disadvantage:

+
    +
  • Requires two people’s time

  • +
  • Requires coordination when preparing (slows you down in preparation)

  • +
  • Unfamiliar concept to most people

  • +
+
+
+

Questions

+
    +
  • Questions are great, and important for any practical and interactive +class

  • +
  • But questions in main room doesn’t scale to very large rooms.

  • +
  • CodeRefinery strategy: HackMD for questions

    +
      +
    • Chat is not good enough, you can’t reply to old things

    • +
    • HackMD allows threaded replies and follow up later

    • +
    • You need some other helpers to watch HackMD and answer, and bring +things up to you. And let you know how things are going.

    • +
    • Learners can ask anonymously

    • +
    • Learners don’t have to worry about interrupting the flow.

    • +
    • Disadvantage: can produce information overload, warn people to not +follow too closely

    • +
    • With too few people, it can turn out to be very quiet.

    • +
    +
  • +
  • We will learn more about HackMD questions tomorrow in +Running a workshop: online.

  • +
+
+

See also

+ +
+
+
+

Teaching practice

+

In Teaching practice and feedback, you will break into groups and try to +apply these strategies to a five-minute example session.

+
+
+

See also

+

In this lesson:

+ +

CodeRefinery manuals:

+ +
+
+
+

Teaching practice and feedback

+

Goals of the teaching practice:

+
    +
  • In groups of 4-5 persons we will practice teaching a 5-minute segment +of a lesson of your choice.

  • +
  • The section you pick should require screen sharing and be of some +demonstration or follow-along task (preferably using a shell) to also +practice having a good screen-sharing setup.

  • +
  • We will practice giving constructive feedback.

  • +
  • We will practice improving our 5-minute segment by taking the feedback into account.

  • +
  • In both session you can teach the same topic/segment but if you prefer you can also +change the topic/aspect for the second session.

  • +
+
+
+

Instructor demo

+
    +
  • In order to demonstrate the goals of this section, the instructor +will make a 5-minute demo for your evaluation.

  • +
  • It is designed to include some good and bad practices for you to +notice.

  • +
+
+
+
+

Teaching demos part 1

+

In group rooms, 50 minutes.

+
+

Exercise

+
    +
  • We organize the breakout rooms to not only discuss one lesson/topic so that it is more interesting +to listen and also probably we will all get more useful feedback.

  • +
  • Give each other constructive verbal feedback on the teaching demos, for example +using this demo rubric.

  • +
  • Write down questions (in the collaborative document) that you would like to +discuss in the main room or interesting conclusions which you would like to +share with others.

  • +
+
+
+
+

Teaching demos, part 2

+

In group rooms, 50 minutes.

+
+

Exercise

+
    +
  • In the second round we distribute the rooms differently so that you can +present it to a new group of workshop participants and can receive new +feedback.

  • +
  • Ask for feedback and one/few point(s) you want to improve.

  • +
  • In your second trial check whether you feel the demonstration improved.

  • +
  • Share your lessons learned in the collaborative document.

  • +
  • Give us also feedback on this exercise format. Was it useful? What can we improve?

  • +
+
+
+
+
+

Discussion

+
+

Main room discussion

+
    +
  • We discuss questions and conclusions which came up during the group work session.

  • +
+
+
+
+
+

Optional: feedback for two live-coding examples

+
+

Exercise

+

Teaching by live coding is a +performance art which requires practice. +This exercise highlights some typical pitfalls that most instructors +fall into sooner or later, and also shows how to avoid them. +Watch closely since we will be giving feedback!

+
    +
  • Watch these two videos: video 1 and +video 2

  • +
  • What was better in video 1 and what was better in video 2?

  • +
  • Please give feedback in the shared workshop document.

  • +
+
+
+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020-, The contributors.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/singlehtml/objects.inv b/branch/community-teaching/singlehtml/objects.inv new file mode 100644 index 0000000..2802baa Binary files /dev/null and b/branch/community-teaching/singlehtml/objects.inv differ diff --git a/branch/community-teaching/teaching-online/index.html b/branch/community-teaching/teaching-online/index.html new file mode 100644 index 0000000..580be5a --- /dev/null +++ b/branch/community-teaching/teaching-online/index.html @@ -0,0 +1,212 @@ + + + + + + + Teaching online — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Teaching online

+

Is online teaching better or worse? As usual for that question, “it’s +all a trade-off”. We believe that many people tried to directly +translate in-person strategies to online, and teaching suffered. In +some ways, this even revealed the flaws of in-person pedagogy (remove +some interaction and not much is left other than an info-dump).

+
+

Exercise

+

Using HackMD, brainstorm advantages and disadvantages of online and +in-person teaching. For each disadvantage of each, think of ways to compensate.

+
+
    +
  • We won’t elaborate more here right now - most of the rest of the +course somehow relates to online teaching!

  • +
  • We will see many techniques which compensate for some of the +disadvantages in the section tools of teaching.

  • +
  • Workshop organization will discuss new collaborative +opportunities with online teaching.

  • +
+
+

See also

+
    +
  • The rest of this course

  • +
  • CodeRefinery manuals: https://coderefinery.github.io/manuals/

  • +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/teaching-practice/index.html b/branch/community-teaching/teaching-practice/index.html new file mode 100644 index 0000000..97ba1b1 --- /dev/null +++ b/branch/community-teaching/teaching-practice/index.html @@ -0,0 +1,272 @@ + + + + + + + Teaching practice and feedback — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Teaching practice and feedback

+

Goals of the teaching practice:

+
    +
  • In groups of 4-5 persons we will practice teaching a 5-minute segment +of a lesson of your choice.

  • +
  • The section you pick should require screen sharing and be of some +demonstration or follow-along task (preferably using a shell) to also +practice having a good screen-sharing setup.

  • +
  • We will practice giving constructive feedback.

  • +
  • We will practice improving our 5-minute segment by taking the feedback into account.

  • +
  • In both session you can teach the same topic/segment but if you prefer you can also +change the topic/aspect for the second session.

  • +
+
+
+

Instructor demo

+
    +
  • In order to demonstrate the goals of this section, the instructor +will make a 5-minute demo for your evaluation.

  • +
  • It is designed to include some good and bad practices for you to +notice.

  • +
+
+
+
+

Teaching demos part 1

+

In group rooms, 50 minutes.

+
+

Exercise

+
    +
  • We organize the breakout rooms to not only discuss one lesson/topic so that it is more interesting +to listen and also probably we will all get more useful feedback.

  • +
  • Give each other constructive verbal feedback on the teaching demos, for example +using this demo rubric.

  • +
  • Write down questions (in the collaborative document) that you would like to +discuss in the main room or interesting conclusions which you would like to +share with others.

  • +
+
+
+
+

Teaching demos, part 2

+

In group rooms, 50 minutes.

+
+

Exercise

+
    +
  • In the second round we distribute the rooms differently so that you can +present it to a new group of workshop participants and can receive new +feedback.

  • +
  • Ask for feedback and one/few point(s) you want to improve.

  • +
  • In your second trial check whether you feel the demonstration improved.

  • +
  • Share your lessons learned in the collaborative document.

  • +
  • Give us also feedback on this exercise format. Was it useful? What can we improve?

  • +
+
+
+
+
+

Discussion

+
+

Main room discussion

+
    +
  • We discuss questions and conclusions which came up during the group work session.

  • +
+
+
+
+
+

Optional: feedback for two live-coding examples

+
+

Exercise

+

Teaching by live coding is a +performance art which requires practice. +This exercise highlights some typical pitfalls that most instructors +fall into sooner or later, and also shows how to avoid them. +Watch closely since we will be giving feedback!

+
    +
  • Watch these two videos: video 1 and +video 2

  • +
  • What was better in video 1 and what was better in video 2?

  • +
  • Please give feedback in the shared workshop document.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/teaching-strategies/index.html b/branch/community-teaching/teaching-strategies/index.html new file mode 100644 index 0000000..7a81f06 --- /dev/null +++ b/branch/community-teaching/teaching-strategies/index.html @@ -0,0 +1,422 @@ + + + + + + + How to teach online — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

How to teach online

+
+

Objectives

+
    +
  • Understand the benefits and disadvantage of online teaching, +compared to in-person

  • +
  • Set up a good screen share

  • +
  • Understand the benefits and disadvantages of team teaching

  • +
  • Prepare for the teaching practice

  • +
+
+
+

Why teaching mechanics matter

+
    +
  • When you teach, you are mainly showing a basic example for the +learner to follow along

  • +
  • The learner has a lot more to think about than you do, so you need +to minimize the possible distractions and unnecessary weirdness.

  • +
  • A learner will often only one small screen, limiting the number of +things that they can think about.

  • +
  • You are must faster than learners (5 times possibly?) You have to +do things to slow yourself down.

  • +
  • It’s easy to save these mechanics until the end, and then you run +out of time.

  • +
+
+
+

Shell sharing

+ +

When doing any demonstration, there are difficulties:

+
    +
  • If one misses something, you can’t rewind to see it - is there any +way to catch up?

  • +
  • The learner must get oriented with the whole picture, while +instructor knows precisely where to focus.

  • +
+

A good shell share has some of the following properties:

+
    +
  • Large font

  • +
  • Shell history, available separately from the main shell window

  • +
  • Closely matches the type-along instructions

  • +
+

We have a collection of shell sharing systems:

+ +
+

Discussion

+

The instructor will demonstrate several shell-sharing systems. You +will use this in the teaching practice.

+
+
+
+

Screen sharing

+
+

Discussion

+

Look at the various screen layouts in the CodeRefinery +manuals. +Use the HackMD to comment about what which are better or worse.

+ +
+
    +
  • Many learners will have a smaller screen than you.

  • +
  • You should plan for learners with only one small screen.

  • +
  • A learner will need to focus on both your screen share and their +work.

  • +
  • Sharing your a whole screen is almost always a bad idea, if you want +the learners to do anything at the same time.

  • +
  • If you constrict yourself, then your experience is more similar to +that of a learner.

  • +
+

Vertical sharing:

+
    +
  • CodeRefinery has recently started trialing a vertical share +system, where you share a vertical half of your screen.

  • +
  • This allows learners with one screen to display your screen +side-by-side with their learn

  • +
  • Zoom provides a “Share a part of screen” that is good for this.

  • +
+
+
+

Meta-talk

+

Don’t just teach, also make sure you guide the learners through the +course.

+
    +
  • You know what you just discussed, and what is coming next, but +learners are often stuck thinking about now.

  • +
  • Give a lot of “meta-talk” that is not just about the topic you are +teaching, but how you are teaching it.

  • +
  • Examples

    +
      +
    • Why you are doing each episode

    • +
    • What is the purpose of each exercise

    • +
    • Clearly state what someone should accomplish in each exercise and +how long it will take - don’t assume this is obvious.

    • +
    • What is the point of each lesson. How much should people expect +to get from it? Should you follow everything, or are some things +advanced and optional? Make that clear.

    • +
    +
  • +
+
+
+

Teach teaching

+
    +
  • Demonstration-based teaching require two different types of focus:

    +
      +
    • Doing the mechanical steps as a demonstration

    • +
    • Explaining why you are doing it

    • +
    +
  • +
  • This is a lot for one person to keep in mind, so can multiple people +work together for this?

  • +
  • Team teaching idea:

    +
      +
    • One person is doing the demonstrations

    • +
    • One person is giving the commentary about what they are doing

    • +
    • The lecture becomes a discussion between two people instead.

    • +
    +
  • +
+

Advantages:

+
    +
  • This reduces the pressure on each person (reduces demo effect)

  • +
  • You are less likely to forget things

  • +
  • It slows you down in teaching

  • +
  • It makes the lesson more interesting to listen to

  • +
  • One person can follow questions

  • +
  • Great for introducing new instructors (which half is easier to start +with?)

  • +
+

Disadvantage:

+
    +
  • Requires two people’s time

  • +
  • Requires coordination when preparing (slows you down in preparation)

  • +
  • Unfamiliar concept to most people

  • +
+
+
+

Questions

+
    +
  • Questions are great, and important for any practical and interactive +class

  • +
  • But questions in main room doesn’t scale to very large rooms.

  • +
  • CodeRefinery strategy: HackMD for questions

    +
      +
    • Chat is not good enough, you can’t reply to old things

    • +
    • HackMD allows threaded replies and follow up later

    • +
    • You need some other helpers to watch HackMD and answer, and bring +things up to you. And let you know how things are going.

    • +
    • Learners can ask anonymously

    • +
    • Learners don’t have to worry about interrupting the flow.

    • +
    • Disadvantage: can produce information overload, warn people to not +follow too closely

    • +
    • With too few people, it can turn out to be very quiet.

    • +
    +
  • +
  • We will learn more about HackMD questions tomorrow in +Running a workshop: online.

  • +
+
+

See also

+ +
+
+
+

Teaching practice

+

In Teaching practice and feedback, you will break into groups and try to +apply these strategies to a five-minute example session.

+
+
+

See also

+

In this lesson:

+ +

CodeRefinery manuals:

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/team-teaching/index.html b/branch/community-teaching/team-teaching/index.html new file mode 100644 index 0000000..a844827 --- /dev/null +++ b/branch/community-teaching/team-teaching/index.html @@ -0,0 +1,258 @@ + + + + + + + Team teaching — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Team teaching

+

One of the most significant improvemest of our teaching has been the +concept of co-teaching.

+
+

Co-teaching

+

Wikipedia: Co-teaching or team teaching is the division of labor +between educators to plan, organize, instruct and make assessments +on the same group of students, generally in the a common +classroom,[1] and often with a strong focus on those teaching as a +team complementing one another’s particular skills or other +strengths.

+
+

This is not strictly an effect of moving online. However, the +larger number of instructors and larger audiences make this practical +on a wide scale.

+
+

Primary article

+

https://coderefinery.github.io/manuals/team-teaching/

+
+
+

Benefits

+
    +
  • The course seems very interactive, much more so than expecting +students to speak up. The co-teacher can take on the “voice of the +audience”.

  • +
  • Quicker preparation time since co-teachers can rely on each other in +unexpected situations.

  • +
  • One co-teacher can be effectively learning at the same time and thus +acting as the “voice of the audience” in another way.

  • +
  • Great way to onboard new instructors - extensive training and +preparation no longer needed.

  • +
  • More active minds means better able to watch and react to other +feedback, such as HackMD or chat.

  • +
  • Less workload - one person does not have to prepare perfectly, any +uncertainty can usually be quickly answered by the other.

  • +
+
+
+

Strategies

+

In reality, these strategies are mixed and matched even within a +lesson, and there are many things between these:

+
    +
  • One person gives lectures, one does the typing during demos.

  • +
  • “Interview”: One primarily doing the “teaching”, one guiding by +asking questions - either as an interviewer or as a virtual learner.

  • +
+

Things that don’t work (are not team teaching):

+
    +
  • Dividing up a lesson into parts, each person gives different parts +independently.

  • +
+
+
+

Exercises

+
+

Exercise

+

Divide into groups of two or three. Choose one of the two models +in the team-teaching page, and quickly (5 min) prepare a short +topic (3-5 min) to team teach. You can quickly scan the +“preparation” section at the bottom.

+

The challenge is not just to give the lesson, but to prepare the +lesson quickly and rely on each other to give a good lesson anyway.

+
+
+
+

See also

+

(none yet)

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/teams/index.html b/branch/community-teaching/teams/index.html new file mode 100644 index 0000000..0b8a7d6 --- /dev/null +++ b/branch/community-teaching/teams/index.html @@ -0,0 +1,288 @@ + + + + + + + Teams — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Teams

+

Everyone wants interaction in courses, yet when a group size gets too +large, it doesn’t have much interaction. A event in a physical space +naturally makes teams based on who is nearby. When done online, this +needs to be more explicit.

+
+

Primary articles

+ +
+
+

Basic concepts

+
    +
  • Teams are pre-assigned

  • +
  • Exercise leaders (aka helpers) assigned per team

  • +
  • Teams stay together during the whole workshop.

  • +
  • Learners can sign up either alone…

  • +
  • … or they can sign up with a pre-made team: people who know +each. “bring your own breakout room”:

    +
      +
    • When two people in a work group learn a skill, uptake within the +group is often much higher. Thus, we strongly encourage pre-made +teams that know each other.

    • +
    • Teams that all come from the same group or field, with a helper +from that field, can transition to help

    • +
    +
  • +
+
+
+

Online

+

In the best online implementations, our teams have these properties:

+
    +
  • Coordination of breakout rooms is a lot of work.

  • +
  • In zoom, we could request learners to rename to (N) Learner +Name, and then quickly assign people. Now, you can have learners +self-select their rooms. But will they actually do this, or stay in +main room?

  • +
  • One helper is assigned per team.

    +
      +
    • In fact, we would limit the number of registrations to 5× the +number of helpers so that all teams have a helper

    • +
    +
  • +
  • Our registration system (indico) is capable of mailing personalized +messages per person with their team information. This is quite a +bit of work to manage.

  • +
+

But they have these disadvantages:

+
    +
  • Much, much harder registration coordination, almost to the point of +being impossible.

  • +
  • Number of attendees.

  • +
  • Difficulties when attendees drop out partway through a course.

  • +
+
+
+

In-person

+

Teams may natuarally form based on setting location, but

+
    +
  • Teams may happen naturally by sitting at the same table

  • +
  • Do teams stay the same day after day?

  • +
  • Do teams get arranged in a manner useful for learning?

  • +
  • Do you have one helper per team?

  • +
  • Do you encourage people to interact explicitly enough?

  • +
  • Do you ensure that no one gets left out in the crowd? Are the teams +explicit enough?

  • +
+
+
+

Discussion: what we actually do

+
    +
  • For large enough CodeRefinery workshops, assign teams with one +helper each. Deal with re-adjustment

  • +
  • The livestream option allows everyone else to follow along.

  • +
  • In other workshops, create breakout rooms but somehow try let people +self-assign. Most don’t.

  • +
  • For large workshops without enough staff help, livestream and +encourage people to form their own teams and watch themselves - we +don’t actually need to be involved.

  • +
  • Teams can be delegated to a local organizer.

  • +
+
+
+

Exercises

+
+

Teams

+

Consider these questions:

+
    +
  • Should teams have similar or different people in them?

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/video-editing/index.html b/branch/community-teaching/video-editing/index.html new file mode 100644 index 0000000..f51db75 --- /dev/null +++ b/branch/community-teaching/video-editing/index.html @@ -0,0 +1,565 @@ + + + + + + + Video editing — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Video editing

+

Video recordings could be useful for people attending a course later, +but also are (perhaps more) useful for immediate review and catching +up after missing a day in a workshop. For this, they need to be +released immediately, within a few hours of the workshop. +CodeRefinery can do this.

+

Hypothesis: videos must be processed the same evening as they were +recorded, otherwise (it may never happen) or (it’s too late to be +useful). To do that, we have to make processing good enough (not +perfect) and fast and distributeable

+
+

Primary articles

+ +
+
+

Summary

+
    +
  • Basic principle: privacy is more important than any other factor. +If we can’t guarantee privacy, we can’t release videos at all.

    +
      +
    • Disclaimers such as “if you don’t want to appear in a recording, +leave your video off and don’t say anything”, since a) accidents +happen especially when coming back from breakout rooms. b) it +creates an incentive to not interact or participate in the course.

    • +
    +
  • +
  • Livestreaming is important here: by separating the instruction from +the audience audio/video, there is no privacy risk in the raw +recording. They could be released or shared unprocessed.

  • +
  • Our overall priorities

    +
      +
    1. No learner (or anyone not staff) video, audio, names, etc. are +present in the recordings.

    2. +
    3. Good descriptions.

    4. +
    5. Removing breaks and other dead time.

    6. +
    7. Splitting videos into useful chunks (e.g. per-episode), perhaps +equal with the next one:

    8. +
    9. Good Table of Contents information so learners can jump to the +right spots (this also helps with “good description”.)

    10. +
    +
  • +
  • ffmpeg-editlist allows us to +define an edit in a text file (crowdsourceable on Github), and then +generate videos very quickly.

  • +
+
+
+

Exercises

+
+

Exercise A

+

These exercises will take you through the whole sequence.

+
+

Editing-1: Get your sample video

+

Download a sample video:

+
+
+
+
+

Editing-2: Run Whisper to generate raw subtitles and test video.

+

First off, install Whisper and generate the base subtitles, based +on the. Since this is probably too much to expect for a short +lesson, they are provided for you (above), but if you want you can +try using Whisper, or generating the subtitles some other way.

+

You can start generating subtitles now, while you do the next +steps, so that they are ready by the time you are ready to apply +the editlist. ffmpeg-editlist can also slice up the subtitles from +the main video to make subtitles for each segment you cut out.

+

Whisper is left as an exercise to the reader.

+ +
+
+

Editing-3: Create the basic editlist.yaml file

+

Install ffmpeg-editlist and try to +follow its instructions, to create an edit with these features:

+
    +
  • The input definition.

  • +
  • Two output sections: the “Intro to the course”, and “From data +storage to your science” talks (Remember it said the recording +started at 11:35… look at the schedule for hints on when it +might start!). This should have a start/end timestamp from the +original video.

  • +
+

A basic example:

+
- input: day1-raw.mkv
+
+# This is the output from one section.  Your result should have two of these sections.
+- output: part1.mkv
+  title: something
+  description: >-
+    some long
+    description of the
+    segment
+  editlist:
+    - start: 10:00    # start timestamp of the section, in *original* video
+    - end: 20:00      # end timestamp of the section, in the *original* video
+
+
+ +
+
+

Discussion: what makes a video easy to edit?

+
    +
  • Clear speaking and have high audio quality.

  • +
  • For subtitle generation: Separate sentences cleanly, otherwise it +gets in a “stream of words” instead of “punctuated sentences” +mode.

  • +
  • Clearly screen-sharing the place you are at, including section +name.

  • +
  • Clear transitions, “OK, now let’s move on to the next lesson, +LESSON-NAME. Going back to the main page, we see it here.”

  • +
  • Clearly indicate where the transitions are

  • +
  • Hover mouse cursor over the area you are currently talking about.

  • +
  • Scroll screen when you move on to a new topic.

  • +
  • Accurate course webpage and sticking to the schedule

  • +
+

All of these are also good for learners. By editing videos, you +become an advocate for good teaching overall.

+
+
+

Editing-4: Run ffmpeg-editlist

+

Install ffmpeg-editlist: pip install ffmpeg-editlist[srt] (you +may want to use a virtual environment, but these are very minimal +dependencies).

+

The ffmpeg command line tool must be available in your +PATH.

+ +
+
+

Editing-5: Add more features

+
    +
  • Several chapter definitions.(re-run and you should see a +.info.txt file also generated). Video chapter definitions +are timestamps of the original video, that get translated to +timestamps of the output video.

    +
    - output: part1.mkv
    +  editlist:
    +  - start: 10:00
    +  - -: Introduction    #  <-- New, `-` means "at start time"
    +  - 10:45: Part 1      #  <-- New
    +  - 15:00: Part 2      #  <-- New
    +  - end: 20:00
    +
    +
    +

    Look at the .info.txt files that come out now. What is new in it?

    +
  • +
  • Add in “workshop title”, “workshop description”, and see the +.info.txt files that come out now. This is ready for +copy-pasting into a YouTube description (first line is the title, +rest is the description).

    +

    Look at the new .info.txt files. What is new?

    +
  • +
+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+
+
+

Editing-7: Generate the final output file.

+
    +
  • Run ffmpeg-editlist with the --reencode option: this +re-encodes the video and makes sure that there is no black point +at the start.

  • +
  • If you re-run with --check, it won’t output a new video file, +but it will re-output the .info.txt and .srt files. +This is useful when you adjust descriptions or chapters.

  • +
+
+
+

Discussion: how to distribute this?

+

Create a flowchat of all the parts that need to be done, and which +parts can be done in parallel. Don’t forget things that you might +need to do before the workshop starts.

+

How hard was this editing? Was it worth it?

+
+
+
+

Exercise B

+

This is similar to the above but more brief and not on a real example +video.

+
+

Use ffmpeg-editlist to edit this sample video

+

Prerequisites: ffmpeg must be installed on your computer +outside of Python. Be able to install ffmpeg-editlist. This is +simple in a Python virtual environment, but if not the only +dependency is PyYAML.

+ +
+ +
+
+
+

See also

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/video-recording/index.html b/branch/community-teaching/video-recording/index.html new file mode 100644 index 0000000..f0cdae0 --- /dev/null +++ b/branch/community-teaching/video-recording/index.html @@ -0,0 +1,246 @@ + + + + + + + Video recording — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Video recording

+
+

Keypoints

+
    +
  • We don’t expect many people to watch the recording from scratch later (but +some do) (some might look afterwards a few pieces, cmp. reading a book vs +look ing sth up from a book)

  • +
  • Learners getting an “instant replay” to review, or to make up for a lost day, is great.

  • +
  • Privacy is more important than any other factor

  • +
  • Recording only works if privacy is guaranteed and effort is low. +This is only possible with the instructor-audience split setup of livestreaming.

  • +
+
+
+

We try to release videos on the same day

+

Video recordings could be useful for people attending a course later, but also +are (perhaps more) useful for immediate review and catching up after missing +a day in a workshop.

+

For this, they need to be released immediately, within a few hours of the +workshop (see Video editing). CodeRefinery can do this.

+

For the videos to be released soon we need to make sure we guarantee privacy of +learners (see below). Our livestream setup makes the privacy guarantee easy at +the cost of separating instructors and learners into different video rooms.

+

Good preparation and documentation helps to make video recording and video +editing easier.

+
+
+

Privacy is more important than any other factor

+

If we can’t guarantee privacy, we can’t release videos at all.

+

Some events add a disclaimers such as “if you don’t want to appear +in a recording, leave your video off and don’t say anything”. We +would prefer not to do this, since:

+
    +
  • we know accidents happen (especially when coming back from breakout rooms)

  • +
  • it creates an incentive to not interact by voice/video

  • +
  • it could pressure participants to not object in order “to not be difficult”

  • +
+

Livestreaming solves this for us:

+
    +
  • By separating the instruction from +the audience audio/video, there is no privacy risk in the raw +recording. They could be released or shared unprocessed.

  • +
  • Recording with Zoom in a large meeting with all the instructors and +learners is simple, but not good for privacy: there are always +mistakes, reviewing takes too long.

  • +
  • Livestream platforms also provide instant recordings of the whole +stream, and some make instant replays possible. This could remove +the need for making our own videos, since one of the most important +cases is this instant replay idea.

  • +
+
+
+

Broadcasting role and setup

+

In the live-streaming setup, the Broadcasting role is central to video +recording.

+

Broadcaster description (most is not directly about recording): +https://coderefinery.github.io/manuals/broadcaster/

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/welcome/index.html b/branch/community-teaching/welcome/index.html new file mode 100644 index 0000000..716502f --- /dev/null +++ b/branch/community-teaching/welcome/index.html @@ -0,0 +1,270 @@ + + + + + + + Welcome and introduction — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Welcome and introduction

+
+

What do we want to get out of this workshop

+
    +
  • Introduction of instructors and helpers

  • +
  • Each instructor can say what we want to get out of the instructor training

  • +
  • But we want to know from everybody and collect these in the live notes

  • +
+
+
+
+

Goals for this workshop

+
+

Goals for this instructor training

+
    +
  • Inspire teachers and staff who have to teach indirectly as part of +their job: use best practices for the modern world, especially +for online teaching.

  • +
  • Promote collaboration in teaching: less going alone.

  • +
  • Promote CodeRefinery sustainability: form a network that can +work together to share the work and benefits.

  • +
+
+
+

Giving confidence

+
+

Goal number one should be that we give participants the confidence to +independently apply the tools or knowledge learnt. This is more important +that giving a “complete” overview. [Lucy Whalley gave this great comment at one of our workshops]

+
+
    +
  • You don’t have to know everything to use (or teach) something.

  • +
  • For the large majority of topics we teach, there are many resources online +which provide how-to guides or tutorials. And the Stack Overflow answer bank +isn’t getting any smaller. So we need to ask why do people attend in-person +sessions if there is information freely available? Our impression is that +it is for confidence building, identity formation, perhaps signposting to +resources.

  • +
  • This also links with building a welcoming/inclusive environment: for example, +imposter syndrome, which disproportionately affects under-represented groups +(link), +can manifest as low self-confidence –> building the confidence of +students in the classroom may lead to a more diverse community.

  • +
+
+
+
+
+

Tools for this workshop

+

We often start workshops with these:

+ +
+
+
+

Code of Conduct

+
    +
  • We follow The CodeRefinery Code of +Conduct.

  • +
  • This is a hands-on, interactive workshop.

    +
      +
    • Be kind to each other and help each other as best you can.

    • +
    • If you can’t help someone or there is some problem, let someone know.

    • +
    • If you notice something that prevents you from learning as well as you can, let us know and don’t suffer silently.

    • +
    +
  • +
  • It’s also about the little things:

    +
      +
    • volume

    • +
    • font size

    • +
    • generally confusing instructor

    • +
    • not enough breaks

    • +
    +
  • +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/why-are-computers-hard/index.html b/branch/community-teaching/why-are-computers-hard/index.html new file mode 100644 index 0000000..d257bbb --- /dev/null +++ b/branch/community-teaching/why-are-computers-hard/index.html @@ -0,0 +1,238 @@ + + + + + + + Why are computers hard? — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Why are computers hard?

+

Most of the time, when teaching, our difficulty is not what you expect.

+
+

Initial reading

+

Read the following:

+ +

Of each of the points made, how many are related to:

+
    +
  • The computing itself

  • +
  • The user interface

  • +
  • The ability of the user to work in the computing environment

  • +
  • Something else

  • +
+
+
+

Usability

+

As said in the text above:

+
+

Most user interfaces are terrible. When people make mistakes it’s +usually the fault of the interface. You’ve forgotten how many ways +you’ve learned to adapt to bad interfaces. You’ve forgotten how +many things you once assumed that the interface would be able to +do for you.

+
+
+
+

Deep abstraction layers

+

Most technology is built on abstraction layers, for good reason. They +help simplify implementation and understanding.

+
+

Exercise

+

Think of a tool or technology that is easy to understand and use if +you understand the underlying abstraction layers, but is almost +impossible otherwise.

+
+
+
+

Conclusion: what are we teaching, then?

+

As teachers of computing, we fill a critical role that is more +determined by our audience, than the technology we are teaching.

+
+
+

See also

+

(none yet)

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/why-teach-together/index.html b/branch/community-teaching/why-teach-together/index.html new file mode 100644 index 0000000..d7b10e0 --- /dev/null +++ b/branch/community-teaching/why-teach-together/index.html @@ -0,0 +1,271 @@ + + + + + + + Why teach together? — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Why teach together?

+

We usually say so much about the value of collaboration. Despite us +saying this, our teaching is still far too alone. Covid-19 gave us a +kick that reduced our barriers and led to lasting changes in how we +taught (eventually leading to this very course).

+

Open Science / FAIR data is heavily emphazised these days. But let’s +add a “C” to FAIR: “collaborative”. Instead of people doing their own +thing and releasing, develop, iterate, and maintain collaboratively.

+
+

Ways to teach together

+
    +
  • Develop materials together - avoid duplication.

  • +
  • Team teaching

  • +
  • Extensive use of helpers and team leaders.

  • +
  • HackMD for parallel and mass answers.

  • +
+
+
+

Advantages

+
    +
  • You need to teach anyway, less effort if you combine.

  • +
  • If done right, minimal extra effort for others to receive benefit (+ +you get publicity).

  • +
  • Many of the previously presented teaching strategies work best in +large courses - this makes the course more engaging than a small +event with minimal interaction.

  • +
  • More engaging for the audience.

  • +
  • Easier on-boarding of new instructors (less “scary” to teach a new course +with other instructors).

  • +
+
+
+

Challenges and disadvantages

+
    +
  • Coordination

    +
      +
    • Finding suitable partners with the same vision

    • +
    • Coordination efforts (if others don’t understand the vision).

    • +
    +
  • +
  • Materials

    +
      +
    • May not be perfectly tuned to your own audience

    • +
    • May not iterate as fast as you need

    • +
    +
  • +
  • Co-teaching

    +
      +
    • Difficulty in finding co-teachers

    • +
    • Required effort of syncing among staff

    • +
    • It might revert to independent teaching if you aren’t careful.

    • +
    +
  • +
  • HackMD

    +
      +
    • Can possibly overload both student and teacher.

    • +
    +
  • +
+
+
+

Exercises

+
+

What similarities do we have?

+

Using HackMD, make two lists:

+
    +
  • What courses do you think your local community would benefit +from, which you don’t currently have? +1 other people’s items +which are also relevant to you.

  • +
  • Which courses are you thinking of preparing for your local +community? +1 other people’s items which you would be +interested in helping out with.

  • +
+
+
+
+

See also

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/workshop-roles/index.html b/branch/community-teaching/workshop-roles/index.html new file mode 100644 index 0000000..95b2f9d --- /dev/null +++ b/branch/community-teaching/workshop-roles/index.html @@ -0,0 +1,260 @@ + + + + + + + Workshop roles — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Workshop roles

+

Running massive workshops requires a lot of people. We have a variety +of roles with different levels of support.

+

As usual, roles are a plan, and a plans are made to be updated.

+
+

Primary articles

+ +
+
+

Summary

+

Lower levels mean “top level sometimes split into some of these +sub-roles”.

+
    +
  • Instructor coordinator: coordinates schedule and instructors

    +
      +
    • Instructor: Teaches along with a co-teacher.

    • +
    • Expert helper: Spare person, usually watching HackMD but also +rotates among breakout rooms. Often instructs some lessons.

    • +
    • Director: Manages the flow of the schedule during the +workshop, introduces each lesson, etc. (often the instructor +coordinator)

      +
        +
      • Broadcaster: Manages the livestreaming

        +
          +
        • Video editor: Edits and publishes videos the day of the +workshop.

        • +
        +
      • +
      +
    • +
    +
  • +
  • Registration coordinator: coordinates registration, helpers, and +breakout rooms.

    +
      +
    • Exercise leader coordinator: Onboards exercise leaders

    • +
    • Host: Manages the learner breakout rooms, learner questions, +etc. (often the registration coordinator)

    • +
    • Advertisement coordinator: Advertises and outreaches

    • +
    +
  • +
  • Under both registration coordinator and instructor coordinator

    +
      +
    • HackMD manager: always watches and formats HackMD and +publishes it same-day. “Eyes on the ground” via HackMD and chat +and quickly communicates important information to instructor and +registration coordinators.

    • +
    +
  • +
  • Learner: attends and learns

  • +
  • Exercise leader: serves as a guide to the team, receives small +amount of training before the workshop.

  • +
+
+
+

Exercises

+
+

How many people teach in your workshops?

+
    +
  • Using HackMD, make a histogram of how many (instructors + +organizers) you typically have in your workshops.

  • +
  • List some of the common roles you have used.

  • +
+
+
+
+

See also

+

(none yet)

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/community-teaching/workshops-online/index.html b/branch/community-teaching/workshops-online/index.html new file mode 100644 index 0000000..df34f02 --- /dev/null +++ b/branch/community-teaching/workshops-online/index.html @@ -0,0 +1,500 @@ + + + + + + + Running a workshop: online — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Workshop manuals

+

CodeRefinery maintains a number of workshop manuals +with most of the “primary” information. This episode condenses this +into a quick overview.

+
+
+

Running a workshop: online

+
+

Online teaching discussion

+
+

Discussion: Online vs in-person

+

In notes:

+
    +
  • Compare and contrast the benefits of online teaching with +in-person: {advantage, disadvantage} × {content, presentation}

  • +
  • How do you have to prepare differently?

  • +
  • What are your own experiences?

  • +
+
+
+
+

Case study: Mega-CodeRefinery and Finland HPC Kickstart

+
    +
  • Mega-CodeRefinery

    +
      +
    • Audience of around 90-100

    • +
    • “bring your own breakout room” (see below)

    • +
    • 3 days/week, 6 days total

    • +
    • Lessons as normal in CodeRefinery

    • +
    +
  • +
  • HPC Kickstart

    +
      +
    • 250 registered, ~180 max participants

    • +
    • Multi-university: local differences made this much harder to manage.

    • +
    • Breakout rooms not pre-planned.

    • +
    +
  • +
+

Mega-CodeRefinery worked very well, HPC kickstart didn’t - but not +because of the size.

+
+
+

General workshop arrangements

+ +
    +
  • Select a coordinator, recruit instructors (at least 3 is important), +find helpers

  • +
  • Find a good lecture room: +requirements

  • +
  • Set up workshop webpage using the [Github, template +repository](https://github.com/coderefinery/template-workshop-webpage]: +see +manuals

  • +
  • Advertising the workshop

  • +
  • Communication with registered participants

  • +
+
+
+

CodeRefinery online scaling strategy

+
    +
  • We started online workshops in 2020 March, for the obvious reasons.

  • +
  • First, we started with two “normal size” (20 people) practice +workshops

  • +
  • Then we did a 100 person workshop. It went well, but there is less +tolerance for problems.

  • +
+
+

Basic preparation

+
    +
  • You need more breaks are needed

  • +
  • People have a way of doing too many things and not focusing.

  • +
  • How to attend an online +workshop” +guide to prepare learners

  • +
+
+
+

Basic platform: Zoom

+
    +
  • Zoom (not the most ethical, but worked well and was available)

  • +
  • Zoom mechanics: instructions for +students.

    +
      +
    • Mostly things that are known

    • +
    • We don’t use Zoom interaction features much anymore +(faster/slower/etc), but breakout rooms and HackMD instead

    • +
    +
  • +
  • See also: Online training +manual +(which is getting a bit old compared to what is below).

  • +
+
+
+

Breakout rooms, bring your own team

+
    +
  • Breakout rooms are

    +
      +
    • Static: same people across whole workshop

    • +
    • Contain one helper per room (see below)

    • +
    +
  • +
  • Team registration: accept a “team” field when registering, people on the +same team are put together.

    +
      +
    • Gives motivations for learners to bring their colleagues and +learn together.

    • +
    • More than one person learning together greatly increases update

    • +
    +
  • +
  • You need a powerful enough registration system to assign rooms and +email them to people!

  • +
  • We ask people to name themselves “(N) Firstname Lastname” or “(N,H) +Firstname Lastname” for helpers. Then it is fast to assign them to +their designated breakout rooms.

  • +
  • See also: Breakout room +mechanics

  • +
+
+
+

Helper training

+
    +
  • Each breakout room has a helper

  • +
  • Helper should be a little bit familiar, but not expected to be able +to answer all questions.

  • +
  • Special, custom helper +training +since helpers make or break the workshop

  • +
  • Helper recruitment:

    +
      +
    • Our networks

    • +
    • Team registration: if a team registers with their own helper, then +they are guaranteed to get in together. “bring your own breakout +room”

    • +
    • Former learners, ask them to come back.

    • +
    +
  • +
  • Two helper trainings the week before the workshop.

  • +
+
+
+

Staff roles

+

To reduce stress on any one person, we clearly define the different +roles and try to avoid overlap. We actually have enough people for +all of these, so it works well.

+
    +
  • Workshop coordinator

    +
      +
    • Registration, etc.

    • +
    +
  • +
  • Zoom host

    +
      +
    • Handles registration, breakout rooms, recording, Zoom chat.

    • +
    +
  • +
  • HackMD helper

    +
      +
    • Dedicated to watching HackMD and answering questions quickly.

    • +
    • Host on manuals

    • +
    +
  • +
  • Expert helpers

    +
      +
    • “Spare hands” who rotate between breakout rooms and make sure +helpers are doing well.

    • +
    • Give feedback to instructor about how breakout rooms are going.

    • +
    • Take the place of missing helpers.

    • +
    • Easy way for any people with a bit of spare time to help out.

    • +
    • Expert helpers in workshop

    • +
    +
  • +
  • Instructors

    +
      +
    • Teach, they shouldn’t overlap with the above roles (but serve as +expert helpers other times).

    • +
    • Usually also improve the lesson a bit before teaching

    • +
    • General staff intro in manuals

    • +
    +
  • +
  • Workshop preparation meeting

    + +
  • +
+
+
+

HackMD

+
    +
  • We’ve been using it here

  • +
  • Chat doesn’t work wen large, written +document does.

  • +
  • HackMD can just about scale to ~100 person workshop. Recommend +learners keep it in view mode while not editing.

  • +
  • Voice questions are still allowed, but will be recorded. Staff +raise important questions from HackMD to the instructor immediately.

  • +
  • HackMD also allows communication when in breakout rooms.

  • +
  • You can get multiple answers, and answers can be improved over +time.

  • +
  • HackMD +mechanics +and HackMD +helpers.

  • +
+
+
+

Recording and streaming

+
    +
  • When you have 100 people, main room is quiet anyway: you don’t lose +much by recording.

    +
      +
    • Questions anonymously in HackMD, privacy loss is not so bad

    • +
    +
  • +
  • Breakout rooms are never recorded

  • +
  • Streaming

    +
      +
    • We streamed via Twitch: https://twitch.tv/coderefinery

    • +
    • We typically get 5-40 viewers.

    • +
    • Zoom can directly send the stream to Twitch: no extra software +needed.

    • +
    • Twitch archives videos for 14 days, which allows learners to get +an instant reply (we get hundreds of views in the next days).

    • +
    • So while possibly not useful for new people to learn, the instant +reply is very useful. Instructor can also work on problems in +main stream during breakout rooms, which learners can watch +later.

    • +
    • Streamers also have access to HackMD to ask questions.

    • +
    +
  • +
  • Certain tricks needed to keep learners from appearing in recording +or stream

    +
      +
    • “Spotlight video”, host does not go to gallery view, uses dual +monitor mode. We are still figuring this out.

    • +
    +
  • +
+
+
+

Installation time

+
    +
  • People have to be ready once we start, or else everything fails.

  • +
  • Two installation help times the week before.

  • +
  • Every email emphasizes that you have to be prepared, and “requires” +you to attend workshops (but really it’s only)

  • +
  • Installation instructions include steps to verify

  • +
  • Installation instructions also include video demonstrations of +installation and verification.

  • +
  • We haven’t had that many installation problems, but also we keep the +requirements simple.

  • +
  • Helper introduction is right before software install time, so +helpers can stay and help with install if they want.

  • +
  • Design to be easy to install and get set up.

  • +
+
+
+

Other notes

+
    +
  • Make breakout sessions as long as possible: 10 minutes is really too +short. 20 minutes is a good minimum time.

  • +
  • Be very clear about exercise expectations

  • +
  • Keep HackMD updated as a log.

  • +
  • Don’t combine breaks and breakout times.

  • +
  • The more people you have, the more diverse audience you have and the +more people overwhelmed and under whelmed.

  • +
+
+
+
+

Workshop collaborations

+

Why limit ourselves to CodeRefinery workshop? Why not use our network +and techniquess for more

+
    +
  • Case study: Python for Scientific +Computing

    +
      +
    • Started by Aalto

    • +
    • Announced to CodeRefinery, five more instructors from three +countries joined.

    • +
    • Rapid collaboration, taught course shortly later.

    • +
    • Announced to all institutions. Some places had physical rooms, +some were pure online

    • +
    • Also streamed

    • +
    • It was much more fun and less stressful to work together

    • +
    +
  • +
  • We want to continue this kind of collaboration in other workshops.

  • +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/02-teaching-philosophies/index.html b/branch/ignore/02-teaching-philosophies/index.html new file mode 100644 index 0000000..d177303 --- /dev/null +++ b/branch/ignore/02-teaching-philosophies/index.html @@ -0,0 +1,376 @@ + + + + + + + CodeRefinery teaching philosophies — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CodeRefinery teaching philosophies

+
+

Ice-breaker in groups (20 minutes)

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also +Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+

Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops.

+

It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us.

+
+

Video recordings

+

Recently we have recorded some of the below as videos: +https://www.youtube.com/playlist?list=PLpLblYHCzJAAHF89P-GCjEXWC8CF-7nhX

+
+
+

Anne Fouilloux

+

I regularly teach Carpentries workshops so I try to apply what I have learnt to CodeRefinery workshops. However, I know our target audience is very much different and that I need to adapt my teaching style. I am still trying to find what works best in which situations and this is why I like so much CodeRefinery workshops. We usually have a wider range of skills and very mixed backgrounds so we usually have to be more careful with the pace and time given for exercises.

+

Some considerations:

+
    +
  • I spend quite a lot of time reading the CodeRefinery material and practising myself exercises. I particularly like to read the instructor notes just before teaching: they usually highlight important aspects both for preparing and teaching.

  • +
  • I usually do not show too much in advance the material as I think it prevents asking questions. If you have less competent practitioners in the classroom, they can easily copy-paste to avoid slowing down the entire classroom.

  • +
  • Ideally, I’d like to give several exercises so anyone can work at its own pace. I find it is important that everybody gets something different from the workshop.

  • +
  • I love breaks as it gives us an opportunity to discuss with attendees on their research topics. I am especially interested to understand what software they write and how they plan to use what they learn during our workshops.

  • +
+
+
+

Bjørn Lindi

+

My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this “BLOB” (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the “BLOB”, to be able to share it with others.

+

In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic.

+

When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson.

+

Tools that I find useful in preparing a lesson is concept maps and Learner Personas, though I have develop to few them.

+ +
+
+

Thor Wikfeldt

+

I never want to leave any learner behind and I really don’t like seeing confused, blank faces in the classroom. +At the same time I sometimes worry about some participants getting bored if a lesson is progressing slowly. +This is always a difficult compromise and something I struggle with!

+

I try to focus on making concepts intuitive, to “make sense” to the learners. Of course this is usually +based on how I learned the topic myself and how it makes sense to me.

+

I try to establish connections between topics: “this thing here is similar to what we saw in the previous +lesson where we learned about X…”.

+

Before mastering a lesson by teaching in many times I try to “follow the script”. After becoming very +familiar with a lesson I start to improvise more and react more dynamically to questions, e.g. by taking a +detour to explain a confusing topic more clearly.

+

What I think I do too often: copy-paste code/text from lesson material. This can leave learners behind - +typing out the code and describing it is slower, but more learning takes place. More advanced learners +will hopefully “be compensated” by interesting advanced exercises which follow.

+
+
+

Stefan Negru

+

A lesson is a conversation, it is useful if both the trainer and the trainee are engaged. +For that reason I try to have, most of the time, a conversation with the classroom and +after we finish parts of a lesson, step back and see how we might use what we learned.

+

That brings me to another point I follow throughout the lessons, answering questions like:

+
    +
  • How can we apply in practice what we just learned?

  • +
  • Do you see yourself (the trainee) using that in practice, why or why not?

  • +
+

Most of the times those seem like open-ended questions to the trainees that just learned +something new, so I try to find examples, most of the times from personal experience.

+

Last thing is that analogies are important when I teach, I try to find analogies in order +to simplify a convoluted part of a lesson.

+
+
+

Radovan Bast

+

My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos.

+

My goal for a lesson is to spark curiosity to try things after the lesson, +both for the novices (“This looks like a useful tool, I want to try using it +after the workshop.”) and the more experienced participants (“Aha - I did not +know you could do this. I wonder whether I can make it work with X.”). I like +to start lessons with a question because this makes participants look up from +their browsers.

+

Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise.

+

For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate +the answer.

+

I try to avoid jargon and “war stories” from the professional developers’ +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid “customer”, +“production”, also a lot of Agile jargon is hard to relate to.

+

Less and clear is better than more and unclear. Simple examples are better +than complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +“simply”, “just”, “easy”. If participants take home one or two points from +a lesson, that’s for me success.

+

I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don’t want to +be surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or +slide. This allows me to skip and distill the essence and not read bullet +point by bullet point.

+

I try to never deviate from the script and if I do, be very explicit about +it.

+

A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel.

+

I find it very helpful if there is somebody else in the room who helps me +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson but when doing that to +others, I am often worried of interrupting their flow and timing too much.

+

A mistake I often do is to type too fast and in my mind I force myself +to slow down.

+
+
+

Sabry Razick

+

My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case.

+
+
+

Juho Lehtonen

+

I’m gradually realising the different ways to get a hint whether the workshop +participants are still following or perhaps bored. I assume it’s communicating +with the class, with exercises and simply by asking now and then. I also try +to remember to observe how people look like (puzzled, bored) while I teach, not +so obvious for me.

+

I believe that learners communicating with each other, in addition to with +instructors and helpers, really helps them to understand things faster. (At least +it helps me). So I try to make sure that no one sits or works alone at the workshops.

+
+
+

Richard Darst

+

Like many people, I’ve often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I’ve realized long ago that my most important lessons weren’t +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I’ve realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds.

+

My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I’m often start at the +very basics, because this is what I see missing most often.

+

When teaching, I like lots of audience questions and don’t mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don’t have to know everything perfectly, just show how +you’d approach a problem.

+
+
+

João M. da Silva

+

I started giving technical trainings twenty years ago, and hence my perspective +is perhaps more inclined towards the development of hands-on abilities and +capability to solve problems, independently or in a team.

+

But the development of hands-on practical skills, requires some essential +knowledge about the domain and some willingness to try different approaches +in case one gets stuck. Some call this the “KSA approach” +(“Knowledge-Skills-Attitude). Hence, I +try to impart the essential knowledge (and where to find out more) at my +trainings. And to encourage and challenge students in order to make them +overcome their self-perceived limits (e.g. “I’m a Humanist, I can’t use +Python virtualenv”).

+

I’ve been trying to study more about the Cognitive aspects of learning over the years, +and I should find out the time to return to that. There’s very interesting +research in Problem Solving, with Learning being a important component in that domain.

+

Storytelling: humans are neurologically made for paying attention to good +stories, and that’s something that I try to put into account: to give +a lesson like it would be a relevant narrative for the students, one that they +could relate to and help them in their work

+

I like to draw and be creative with that, but have to pay attention to +my handwriting during my trainings. I reckon that Architectural diagrams +help students to understand the big picture, so I should invest more on +those when development training material. I would also like to start looking into +Concept Maps and Semantic Trees in training.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/03-teaching-style/index.html b/branch/ignore/03-teaching-style/index.html new file mode 100644 index 0000000..34213fb --- /dev/null +++ b/branch/ignore/03-teaching-style/index.html @@ -0,0 +1,507 @@ + + + + + + + Interactive teaching style — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Interactive teaching style

+
+

What are the top issues new instructors face?

+ +
+
+
+

The Carpentries and CodeRefinery approaches to teaching

+

Here we will give you a very short overview of the Carpentries approach to teaching and highlight +parts that are most important for teaching CodeRefinery style lessons.

+

Most CodeRefinery instructors have completed the +Carpentry instructor training workshop, which +anyone can apply for

+
+

This material

+

This section is derived from the +Carpentries instructor training material. +We encourage you to further study this material later, and to sign up for a 2-day Carpentry +intructor training workshop.

+
+
+
+

Key principles

+

The “Carpentries” approach to teaching is based on:

+
    +
  • Applying research-based teaching principles, especially as they apply to the +Carpentries audience.

  • +
  • Understanding the importance of a respectful and inclusive classroom environment.

  • +
+
+

Carpentries teaching principles

+
    +
  • Learners need to practice what they are learning in real time and get feedback on what they +are doing. That is why the teaching approach relies on live coding.

  • +
  • Learners best learn in a respectful classroom environment, so the Carpentries use a +Code of Conduct.

  • +
  • Learners are encouraged to help each other during workshops as this improves their confidence +and reinforces concepts taught.

  • +
  • Carpentry instructors try to have learners do something that they think is useful in their +daily work within 15 minutes of starting each lesson.

  • +
+

What to Teach

+

In CodeRefinery, we follow The Carpentries teaching principles but in addition to live coding +we often use group discussions to put in context the concepts we are teaching.

+

Applying these teaching principles are not sufficient and in addition we need to be able to check +the effectiveness of our methods.

+
+
+
+
+

On the importance of feedback

+

Feedback is an essential part of effective learning. Feedback is bi-directional:

+
    +
  • To be effective, instructors need feedback on their learners’ progress. Learners can also check their progress and ask relevant questions to get clarification.

  • +
  • Instructors also need feedback on their teaching. For instance, this can help them to adapt the pace, add/skip optional exercises and improve their teaching.

  • +
+
+

Getting/giving feedback on learners’ progress

+

This feedback comes through what is called formative assessments (in contrast +to summative assessment).

+
+

Summative Assessment

+

Summative assessment is used +to judge whether a learner has reached an acceptable level of competence. +Usually at the end of a course +Learners either “pass” or “fail” a summative assessment. +One example is a driving exam, +which tells the rest of society whether someone can safely be allowed on the road. Most assessment done in university +courses is summative, and is used to assign course grades.

+
+
+

Formative assessment

+

Formative assessment takes place during teaching and learning. It sounds like +a fancy term, but it can be used to describe any interaction or activity +that provides feedback to both instructors and learners about learners’ level of understanding of the +material. For learners, this feedback can help focus their study efforts. For instructors, it allows them to refocus +their instruction to respond to challenges that learners are facing. +Used continuously

+
+

Learners don’t “pass” or “fail” formative assessments; they are simply a feedback mechanism. +For example, a music teacher might ask a learner to play a scale very slowly +in order to see whether they are breathing correctly, +and if not, what they should change.

+

Formative assessment is most useful when it happens frequently (we’ll talk about how frequently later) +and when the results are easily interpretable by the learner and instructor.

+

CodeRefinery uses different instruments to get feedback from learners:

+
    +
  • Surveys: we will discuss about CodeRefinery pre/post-surveys in the episode +Running a workshop: online.

  • +
  • Exercises: we have many exercises during CodeRefinery workshops and use polls too but not necessarily many multiple-choice questions. +This is something that we may change in the future but the initial reason was that we build on existing knowledge +(see below section on our target audience) and give recommendations for best software practices: +there is no unique solution and you would like our learners to choose the approach that is most suitable for them. +For the same reasons, we have many optional exercises to accommodate the different levels. +We would like everyone to get something useful out of the CodeRefinery workshops.

  • +
+
+
+

Getting/giving feedback on teaching

+

Teaching is a skill. One of the objective of the CodeRefinery Instructor training is to give you +the confidence in teaching CodeRefinery lessons. Later we will have group work where we will +practice teaching some lessons.

+

Before doing so, we will learn here to give feedback on teaching using the same +positive-vs-negative and content-vs-presentation rubric.

+
+

Give feedback on teaching (optional, 10 mn)

+

This exercise aims at learning to give feedback. It is optional as we have +similar exercises when practising teaching). +As a group, we will watch this video of teaching and +give feedback on two axes: positive vs. negative and content vs. presentation. Have each person in +the class add one point to a 2x2 grid on a whiteboard or in the shared notes (hackMD, etherpad, google doc) without duplicating any points. +For online instructor training event, use breakout room (4-5 persons per group) to facilitate discussion. Then each group reports to the shared notes. +You can use a rubric (used during The Carpentries teaching demos) to help you take notes. +What did other people see that you missed? What did they think that you strongly agree or disagree with?

+
+
+
+
+
+

Who are the learners

+

The first task in teaching is to figure out who your learners are. The Carpentries approach is +based on the work of researchers like Patricia Benner, +who applied the +Dreyfus model of skill acquisition +in her studies of +how nurses progress from novice to expert +(see also books by Benner). +This work indicates that through practice and formal instruction, learners acquire skills and advance +through distinct stages. In simplified form, the three stages of this model are:

+
+

Novices, competent practitioners and experts

+

Novice, Competent Practitioner, Expert

+
    +
  • Novice: someone who doesn’t know what they don’t know, i.e., +they don’t yet know what the key ideas in the domain are or how they relate. +One sign that someone is a novice is that their questions “aren’t even wrong”.

    +
      +
    • Example: A novice learner in a Carpentries workshop might never have heard of the bash +shell, and therefore may have no understanding of how it relates to their file system or +other programs on their computer.

    • +
    • Example HPC: A learner who has never executed a program on remote computer in headless mode

    • +
    • Example HPC: A learner who has no understanding about using a queue system and having a +hard time why a program can not be run directly after login in.

    • +
    +
  • +
  • Competent practitioner: someone who has enough understanding for everyday purposes. +They won’t know all the details of how something works and their understanding may not +be entirely accurate, but it is sufficient for completing normal tasks with normal +effort under normal circumstances.

    +
      +
    • Example: A competent practitioner in a Carpentries workshop might have used the shell +before and understand how to move around directories and use individual programs, but +they might not understand how they can fit these programs together to build scripts +and automate large tasks.

    • +
    • Example: A competent practitioner in a CodeRefinery workshop is someone that understands +the concepts of best software practices and its importance. He/she clearly sees the +benefits of applying best software practices but he/she does not fully know yet how and +what to use for their own projects.

    • +
    • Example HPC: Knows how to establish a connection to a cluster and have submitted jobs. +But may not know how to request optimal amount of resources in a job and how to setup +parallel jobs

    • +
    +
  • +
  • Expert: someone who can easily handle situations that are out of the ordinary.

    +
      +
    • Example: An expert in a Carpentries workshop may have experience writing and running shell +scripts and, when presented with a problem, immediately sees how these skills can be used +to solve the problem.

    • +
    • Example HPC: A learner who has a good understanding of the queue system, parallel processing +and understand how to interpret error reports when something goes wrong and knows how to +get help.

    • +
    +
  • +
+
+
+

Cognitive Development and Mental Models

+

Effective learning is facilitated by the creation of a well-founded mental model. A mental model +is a collection of concepts and facts, along with the relationships between those concepts, which +a person has about a topic. For example, a long-time resident of the United States may have an +advanced understanding of the location of US states, major cities and landmarks, weather patterns, +regional economies and demographic patterns, as well as the relationships among these, compared +with their understanding of these relationships for other countries. In other words, their mental +model of the United States is more complex compared with their mental model of other countries.

+

We can distinguish between a novice and a competent practitioner for a given domain based +on the complexity of their mental models.

+
    +
  • A novice is someone who has not yet built a mental model of the domain. +They therefore reason by analogy and guesswork, borrowing bits and pieces +of their mental models of other domains which seem superficially similar.

  • +
  • A competent practitioner is someone who has a mental model that’s good enough +for everyday purposes. This model does not have to be completely accurate in order +to be useful: for example, the average driver’s mental model of how a car works +probably doesn’t include most of the complexities that a mechanical engineer +would be concerned with.

  • +
+

We could expect a mixture of learners from novice and competent practitioner groups +in HPC training events.

+

Mental Models

+
+
+
+

How “knowledge” gets in the way

+

Mental models are hardly ever built from scratch. Every learner comes to a topic with +some amount of information, ideas and opinions about the topic. This is true even in +the case where a learner can’t articulate their prior knowledge and beliefs.

+

In many cases, this prior knowledge is incomplete or inaccurate. Inaccurate beliefs +can be termed “misconceptions” and can impede learning by making it more difficult for +learners to incorporate new, correct information into their mental models. +Correcting learners’ misconceptions is at least as important as presenting them with +correct information. Broadly speaking, misconceptions fall into three categories:

+
    +
  • Simple factual errors, such as believing that Vancouver is the capital of +British Columbia. These are the easiest to correct.

  • +
  • Broken models, such as believing that motion and acceleration must be in the +same direction. We can address these by having learners reason through examples to +see contradictions.

  • +
  • Fundamental beliefs, such as “the world is only a few thousand years old” or +“human beings cannot affect the planet’s climate”. These beliefs are deeply connected +to the learner’s social identity and are the hardest to change.

  • +
+

The current HPC carpentry workshop material are aimed at Novice of HPC

+

Among Novice learners there might be learners who are experts in their domain and very +competent in the program they are executing, but may not have used a HPC system before. +Then among the competent practitioners There might be learners who repeat some procedures +they have inherited but lack a in-depth understanding of what’s going on. That is why it is +important to get accurate feedback, before and during the workshops to understand the learner profiles.

+
+

Exercise: How to identify learner profiles?

+
    +
  1. How to identify leaner profiles from surveys and during the class

  2. +
  3. Which types of learners should the leassons focus on

  4. +
+
+
+
+
+
+

CodeRefinery Curriculum and Reverse Instructional Design (with recommendations for HPC carpentries)

+

When writing a CodeRefinery lesson, we take a “reverse” approach to instruction, +as described in Wiggins and McTighe’s +Understanding by Design, +that keeps the focus firmly on learning outcomes. The order of preparation in this case becomes

+
    +
  • Determine your learning objectives

  • +
  • Decide what constitutes evidence that objectives have been met, and design assessments +to target that evidence

  • +
  • Design instruction: Sort assessments in order of increasing complexity, +and write content that connects everything together

  • +
+
+

Working with learning objectives

+

Each CodeRefinery lesson (also the HPC capentries lessons) usually has a learning objectives section. +Good learning objectives are quite specific about the intended effect of a lesson on its learners. +We aim to create learning objectives that are specific, accurate, and informative for +both learners and instructors.

+
+
+

Using Bloom’s Taxonomy to write effective learning objectives

+

Bloom’s Taxonomy is a framework for thinking about learning that breaks progress down into discrete, hierarchical steps. +While many ideas have come and gone in education, Bloom’s has remained a useful tool for educators, in particular because the +hierarchy seems to be reasonably valid: outcomes at the top of the hierarchy cannot be achieved without mastery of outcomes at +the bottom. In the long term, everybody wants to be at the top. However, in aiming to meet learners where they are, we also +need to be mindful about helping them to “grow a level,” helping them to recognize when they have achieved that growth, and +guiding them to look ahead to where we might not be able to take them.

+

Bloom's Taxonomy

+

Image credit: Vanderbilt University Center for Teaching

+
+
+

Revisiting Learning objectives

+

When using existing teaching material, reverse instructional design principles might be applied as +follows:

+
    +
  1. Review the lesson’s learning objectives carefully, thinking about how they will work for your audience

  2. +
  3. Scan the lesson to identify promising points to check in with your learners, using formative assessment to verify that objectives have been met

  4. +
  5. Review the connecting content in detail to be sure everything works and you have anticipated likely problems and questions.

  6. +
+

We strongly encourage you to read them before teaching a lesson and to review whether they still match the content of the lesson:

+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/_sources/02-teaching-philosophies.md.txt b/branch/ignore/_sources/02-teaching-philosophies.md.txt new file mode 100644 index 0000000..66bae95 --- /dev/null +++ b/branch/ignore/_sources/02-teaching-philosophies.md.txt @@ -0,0 +1,237 @@ +--- +layout: episode +title: "Our teaching philosophies" +teaching: 0 +exercises: 30 +questions: + - "What are our teaching philosophies?" +--- + +# CodeRefinery teaching philosophies + +> ## Ice-breaker in groups (20 minutes) +> +> - Share your approach to teaching and your teaching philosophy with your group. +> - Please share your tricks and solutions in the live document for others. +> +> Additional ice-breaker questions: +> - What is your motivation for taking this training? +> - How structured or informal are your own teaching needs? +> - What difference do you notice between the teaching what we (also +> Carpentries) do and traditional academic teaching? +> - What other skills need to be taught, but academic teaching isn't the right setting? +{: .challenge} + +--- + +Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops. + +It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us. + +> ## Video recordings +> +> Recently we have recorded some of the below as videos: +> +{: .prereq} + +> ## Anne Fouilloux +> +> I regularly teach Carpentries workshops so I try to apply what I have learnt to CodeRefinery workshops. However, I know our target audience is very much different and that I need to adapt my teaching style. I am still trying to find what works best in which situations and this is why I like so much CodeRefinery workshops. We usually have a wider range of skills and very mixed backgrounds so we usually have to be more careful with the pace and time given for exercises. +> +> Some considerations: +> - I spend quite a lot of time reading the CodeRefinery material and practising myself exercises. I particularly like to read the instructor notes just before teaching: they usually highlight important aspects both for preparing and teaching. +> - I usually do not show too much in advance the material as I think it prevents asking questions. If you have less competent practitioners in the classroom, they can easily copy-paste to avoid slowing down the entire classroom. +> - Ideally, I'd like to give several exercises so anyone can work at its own pace. I find it is important that everybody gets something different from the workshop. +> - I love breaks as it gives us an opportunity to discuss with attendees on their research topics. I am especially interested to understand what software they write and how they plan to use what they learn during our workshops. +{: .challenge} + +> ## Bjørn Lindi +> +> My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this "BLOB" (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the "BLOB", to be able to share it with others. +> +>In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic. +> +>When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson. +> +>Tools that I find useful in preparing a lesson is concept maps and Learner Personas, though I have develop to few them. +>- [Concept Maps](https://teachtogether.tech/#s:memory-concept-maps) +>- [Learner Personas](https://teachtogether.tech/#s:process-personas) +{: .challenge} + +> ## Thor Wikfeldt +> +> I never want to leave any learner behind and I really don't like seeing confused, blank faces in the classroom. +> At the same time I sometimes worry about some participants getting bored if a lesson is progressing slowly. +> This is always a difficult compromise and something I struggle with! +> +> I try to focus on making concepts intuitive, to "make sense" to the learners. Of course this is usually +> based on how I learned the topic myself and how it makes sense to me. +> +> I try to establish connections between topics: "this thing here is similar to what we saw in the previous +> lesson where we learned about X...". +> +> Before mastering a lesson by teaching in many times I try to "follow the script". After becoming very +> familiar with a lesson I start to improvise more and react more dynamically to questions, e.g. by taking a +> detour to explain a confusing topic more clearly. +> +> What I think I do too often: copy-paste code/text from lesson material. This can leave learners behind - +> typing out the code and describing it is slower, but more learning takes place. More advanced learners +> will hopefully "be compensated" by interesting advanced exercises which follow. +{: .challenge} + +> ## Stefan Negru +> +> A lesson is a conversation, it is useful if both the trainer and the trainee are engaged. +> For that reason I try to have, most of the time, a conversation with the classroom and +> after we finish parts of a lesson, step back and see how we might use what we learned. +> +> That brings me to another point I follow throughout the lessons, answering questions like: +> * How can we apply in practice what we just learned? +> * Do you see yourself (the trainee) using that in practice, why or why not? +> +> Most of the times those seem like open-ended questions to the trainees that just learned +> something new, so I try to find examples, most of the times from personal experience. +> +> Last thing is that analogies are important when I teach, I try to find analogies in order +> to simplify a convoluted part of a lesson. +{: .challenge} + +> ## Radovan Bast +> +> My teaching changed by 180 degrees after taking the Carpentries instructor +> training. Before that I used slides, 45 minute lecture blocks, and separate +> exercise sessions. After the Carpentries instructor training I embraced the +> interaction, exercises, demos, and typos. +> +> My goal for a lesson is to spark curiosity to try things after the lesson, +> both for the novices ("This looks like a useful tool, I want to try using it +> after the workshop.") and the more experienced participants ("Aha - I did not +> know you could do this. I wonder whether I can make it work with X."). I like +> to start lessons with a question because this makes participants look up from +> their browsers. +> +> Keeping both the novices and the experts engaged during a lesson can be +> difficult and offering additional exercises seems to be a good compromise. +> +> For me it is a good sign if there are many questions. I like to encourage +> questions by asking questions to the participants. But I also try not to go +> into a rabbit hole when I get a question where only experts will appreciate +> the answer. +> +> I try to avoid jargon and "war stories" from the professional developers' +> perspective or the business world. Most researchers may not relate to them. +> For examples I always try to use the research context. Avoid "customer", +> "production", also a lot of Agile jargon is hard to relate to. +> +> Less and clear is better than more and unclear. Simple examples are better +> than complicated examples. Almost never I have felt or got the feedback that +> something was too simple. I am repeating in my head to not use the words +> "simply", "just", "easy". If participants take home one or two points from +> a lesson, that's for me success. +> +> I prepare for the lesson by reading the instructor guide and all issues and +> open pull requests. I might not be able to solve issues, but I don't want to +> be surprised by known issues. I learn the material to a point where I know +> precisely what comes next and am never surprised by the next episode or +> slide. This allows me to skip and distill the essence and not read bullet +> point by bullet point. +> +> I try to never deviate from the script and if I do, be very explicit about +> it. +> +> A great exercise I can recommend is to watch a tutorial on a new programming +> language/tool you have never used. It can feel very overwhelming and fast to +> get all these new concepts and tools thrown at self. This can prepare me for +> how a participant might feel. +> +> I find it very helpful if there is somebody else in the room who helps me +> detecting when I go too fast or become too confusing. I like when two +> instructors complement each other during a lesson but when doing that to +> others, I am often worried of interrupting their flow and timing too much. +> +> A mistake I often do is to type too fast and in my mind I force myself +> to slow down. +{: .challenge} + +> ## Sabry Razick +> My approach is to show it is fun to demystify concepts. Once a concept is +> not a mystery anymore, the learners will understand is what it means, where +> it is coming from, why it is in place and what it could it offer for their future. +> I try to relate concepts to real life with a twist of humour whenever possible if +> the outcome is certain not be offensive to any one. I use diagrams whenever possible, +> I have spent weeks creating diagrams that is sometime three or four sentences. That +> effort I consider worthwhile as my intention is not to teach, but to demystify. +> Once that is achieved, learners will learn the nitty gritty on their own easily +> and with confidence, when they have the use-case. +> +> +{: .challenge} + +> ## Juho Lehtonen +> I'm gradually realising the different ways to get a hint whether the workshop +> participants are still following or perhaps bored. I assume it's communicating +> with the class, with exercises and simply by asking now and then. I also try +> to remember to observe how people look like (puzzled, bored) while I teach, not +> so obvious for me. +> +> I believe that learners communicating with each other, in addition to with +> instructors and helpers, really helps them to understand things faster. (At least +> it helps me). So I try to make sure that no one sits or works alone at the workshops. +{: .challenge} + +> ## Richard Darst +> +> Like many people, I've often been teaching, but rarely a teacher. I +> tend to teach like I am doing an informal mentorship. +> I've realized long ago that my most important lessons weren't +> learned in classes, but by a combination of seeing things done by +> friends and independent study after that. I've realized that +> teaching (the things I teach) is trying to correct these differences +> in backgrounds. +> +> My main job is supporting computing infrastructure, so my teaching +> is very grounded in real-world problems. I'm often start at the +> very basics, because this is what I see missing most often. +> +> When teaching, I like lots of audience questions and don't mind +> going off-script a bit (even though I know it should be minimized). +> I find that sufficient audience interest allows any lesson to be a +> success - you don't have to know everything perfectly, just show how +> you'd approach a problem. +> +{: .challenge} + +> ## João M. da Silva +> +> I started giving technical trainings twenty years ago, and hence my perspective +> is perhaps more inclined towards the development of hands-on abilities and +> capability to solve problems, independently or in a team. +> +> But the development of hands-on practical skills, requires some essential +> knowledge about the domain and some willingness to try different approaches +> in case one gets stuck. Some call this the "KSA approach" +> ("Knowledge-Skills-Attitude). Hence, I +> try to impart the essential knowledge (and where to find out more) at my +> trainings. And to encourage and challenge students in order to make them +> overcome their self-perceived limits (e.g. "I'm a Humanist, I can't use +> Python virtualenv"). +> +> I've been trying to study more about the Cognitive aspects of learning over the years, +> and I should find out the time to return to that. There's very interesting +> research in Problem Solving, with Learning being a important component in that domain. +> +> Storytelling: humans are neurologically made for paying attention to good +> stories, and that's something that I try to put into account: to give +> a lesson like it would be a relevant narrative for the students, one that they +> could relate to and help them in their work +> +> I like to draw and be creative with that, but have to pay attention to +> my handwriting during my trainings. I reckon that Architectural diagrams +> help students to understand the big picture, so I should invest more on +> those when development training material. I would also like to start looking into +> Concept Maps and Semantic Trees in training. +{: .challenge} diff --git a/branch/ignore/_sources/03-teaching-style.md.txt b/branch/ignore/_sources/03-teaching-style.md.txt new file mode 100644 index 0000000..8164130 --- /dev/null +++ b/branch/ignore/_sources/03-teaching-style.md.txt @@ -0,0 +1,336 @@ +--- +layout: episode +title: "Carpentries and CodeRefinery approach to teaching" +teaching: 30 +exercises: 30 +questions: + - "What pedagogical concepts underpin CodeRefinery and Carpentry workshops?" + - "How to get and give feedback?" + - "Who are the CodeRefinery learners?" + - "Why is it important to define learning objectives?" +objectives: + - "Explain The Carpentries and CodeRefinery approaches to teaching" + - "Understand what is meant by feedback, cognitive development, mental models and reverse instructional design" + - "Explain and practice important pedagogical concepts" +keypoints: + - "CodeRefinery lessons and teaching build on these principles" +--- +# Interactive teaching style + + +## What are the top issues new instructors face? + +```{solution} + - Breaks are not negotiable, minimum 10 minutes. + - Breakout sessions too short. Make them as long as possible, don't expect to come back for + new intro, then go back. + - Get the speed correct. Not too fast and not too slow. + - People will accomplish less than you expect. Expect learners to be 5 times slower than you, at best! + - All the other tools and stuff will go wrong. Try to not bring in a dependency when you don't need it. + - Trying to accomplish too much: it's OK to cut out and adapt to the audience. + Have a reserve session at the end you prepare, but are ready to skip. + - Explaining how, but not why. + - Running out of time to making your environment match the learner's. + - Running out of time to set up good screen sharing practices + - (terminal history, portion of screen, remote history) in advance. + - Assuming learners remember what they have already learned, or know the prerequisites. Or have stuff installed and configured. + - Not managing expectations: learners think that you will accomplish everything, and feel sad when you don't. + - Special issues when lessons delivered online (discussed during Workshop preparation and organization) +``` + + +# The Carpentries and CodeRefinery approaches to teaching + +Here we will give you a very short overview of the Carpentries approach to teaching and highlight +parts that are most important for teaching CodeRefinery style lessons. + +Most CodeRefinery instructors have completed the +[Carpentry instructor training workshop](https://carpentries.github.io/instructor-training/), which +[anyone can apply for](https://carpentries.org/become-instructor/) + +> ## This material +> +> This section is derived from the +> [Carpentries instructor training material](https://carpentries.github.io/instructor-training/). +> We encourage you to further study this material later, and to sign up for a 2-day Carpentry +> intructor training workshop. +{: .callout} + +--- + +## Key principles + +The "Carpentries" approach to teaching is based on: + +- Applying research-based teaching principles, especially as they apply to the + Carpentries audience. +- Understanding the importance of a respectful and inclusive classroom environment. + + +### Carpentries teaching principles + +- Learners need to practice what they are learning in real time and get **feedback** on what they + are doing. That is why the teaching approach relies on **live coding**. +- Learners best learn in a respectful classroom environment, so the Carpentries use a + [Code of Conduct](https://docs.carpentries.org/topic_folders/policies/code-of-conduct.html). +- Learners are encouraged to help each other during workshops as this improves their confidence + and reinforces concepts taught. +- Carpentry instructors try to have learners do something that they think is useful in their + daily work within **15 minutes of starting each lesson**. + +![What to Teach](https://carpentries.github.io/instructor-training/fig/what-to-teach.png) + +In CodeRefinery, we follow The Carpentries teaching principles but in addition to **live coding** +we often use **group discussions** to put in context the concepts we are teaching. + +Applying these teaching principles are not sufficient and in addition we need to be able to check +the effectiveness of our methods. + +--- + +## On the importance of feedback + +Feedback is an essential part of effective learning. Feedback is bi-directional: +- To be effective, instructors need feedback on their learners' progress. Learners can also check their progress and ask relevant questions to get clarification. +- Instructors also need feedback on their teaching. For instance, this can help them to adapt the pace, add/skip optional exercises and improve their teaching. + +### Getting/giving feedback on learners' progress + +This feedback comes through what is called *formative assessments* (in contrast + to *summative assessment*). + +> ## Summative Assessment +> *Summative assessment* is used +> to judge whether a learner has reached an acceptable level of competence. +> Usually at the end of a course +> Learners either "pass" or "fail" a summative assessment. +> One example is a driving exam, +> which tells the rest of society whether someone can safely be allowed on the road. Most assessment done in university +> courses is summative, and is used to assign course grades. +{: .callout} + +> ## Formative assessment +> *Formative assessment* takes place during teaching and learning. It sounds like +> a fancy term, but it can be used to describe any interaction or activity +> that provides feedback to both instructors and learners about learners' level of understanding of the +> material. For learners, this feedback can help focus their study efforts. For instructors, it allows them to refocus +> their instruction to respond to challenges that learners are facing. +> Used continuously +{: .callout} + +Learners don't "pass" or "fail" formative assessments; they are simply a feedback mechanism. +For example, a music teacher might ask a learner to play a scale very slowly +in order to see whether they are breathing correctly, +and if not, what they should change. + +Formative assessment is most useful when it happens frequently (we'll talk about how frequently later) +and when the results are easily interpretable by the learner and instructor. + + +CodeRefinery uses different instruments to get feedback from learners: + +- Surveys: we will discuss about CodeRefinery pre/post-surveys in the episode + {doc}`workshops-online`. +- Exercises: we have many exercises during CodeRefinery workshops and use polls too but not necessarily many multiple-choice questions. + This is something that we may change in the future but the initial reason was that we build on existing knowledge + (see below section on our target audience) and give recommendations for best software practices: + there is no unique solution and you would like our learners to choose the approach that is most suitable for them. + For the same reasons, we have many optional exercises to accommodate the different levels. + We would like everyone to get something useful out of the CodeRefinery workshops. + +### Getting/giving feedback on teaching + +Teaching is a skill. One of the objective of the CodeRefinery Instructor training is to give you +the confidence in teaching CodeRefinery lessons. Later we will have group work where we will +practice teaching some lessons. + +Before doing so, we will learn here to give feedback on teaching using the same +positive-vs-negative and content-vs-presentation rubric. + +> ## Give feedback on teaching (optional, 10 mn) +> This exercise aims at learning to give feedback. It is optional as we have +> similar exercises when {doc}`practising teaching `). +> As a group, we will watch [this video of teaching](https://www.youtube.com/watch?v=-ApVt04rB4U) and +> give feedback on two axes: positive vs. negative and content vs. presentation. Have each person in +> the class add one point to a 2x2 grid on a whiteboard or in the shared notes (hackMD, etherpad, google doc) without duplicating any points. +> For online instructor training event, use breakout room (4-5 persons per group) to facilitate discussion. Then each group reports to the shared notes. +> You can use a [rubric](http://carpentries.github.io/instructor-training/demos_rubric/) (used during The Carpentries teaching demos) to help you take notes. +> What did other people see that you missed? What did they think that you strongly agree or disagree with? +> +{: .challenge} + +--- + +## Who are the learners + +The first task in teaching is to figure out who your learners are. The Carpentries approach is +based on the work of researchers like [Patricia Benner](https://en.wikipedia.org/wiki/Patricia_Benner), +who applied the +[Dreyfus model of skill acquisition](https://en.wikipedia.org/wiki/Dreyfus_model_of_skill_acquisition) +in her studies of +[how nurses progress from novice to expert](http://journals.sagepub.com/doi/10.1177/0270467604265061) +([see also books by Benner](https://www.worldcat.org/search?q=au%3ABenner%2C+Patricia+E.&qt=hot_author)). +This work indicates that through practice and formal instruction, learners acquire skills and advance +through distinct stages. In simplified form, the three stages of this model are: + +### Novices, competent practitioners and experts + +![Novice, Competent Practitioner, Expert](https://carpentries.github.io/instructor-training/fig/skill-level.svg) + +* *Novice*: someone who doesn't know what they don't know, i.e., + they don't yet know what the key ideas in the domain are or how they relate. + One sign that someone is a novice is that their questions "aren't even wrong". + + - Example: A *novice* learner in a Carpentries workshop might never have heard of the bash + shell, and therefore may have no understanding of how it relates to their file system or + other programs on their computer. + + - Example HPC: A learner who has never executed a program on remote computer in headless mode + + - Example HPC: A learner who has no understanding about using a queue system and having a + hard time why a program can not be run directly after login in. + +* *Competent practitioner*: someone who has enough understanding for everyday purposes. + They won't know all the details of how something works and their understanding may not + be entirely accurate, but it is sufficient for completing normal tasks with normal + effort under normal circumstances. + + - Example: A *competent practitioner* in a Carpentries workshop might have used the shell + before and understand how to move around directories and use individual programs, but + they might not understand how they can fit these programs together to build scripts + and automate large tasks. + + - Example: A *competent practitioner* in a CodeRefinery workshop is someone that understands + the concepts of best software practices and its importance. He/she clearly sees the + benefits of applying best software practices but he/she does not fully know yet how and + what to use for their own projects. + + - Example HPC: Knows how to establish a connection to a cluster and have submitted jobs. + But may not know how to request optimal amount of resources in a job and how to setup + parallel jobs + + +* *Expert*: someone who can easily handle situations that are out of the ordinary. + + - Example: An *expert* in a Carpentries workshop may have experience writing and running shell + scripts and, when presented with a problem, immediately sees how these skills can be used + to solve the problem. + + - Example HPC: A learner who has a good understanding of the queue system, parallel processing + and understand how to interpret error reports when something goes wrong and knows how to + get help. + + +### Cognitive Development and Mental Models + +Effective learning is facilitated by the creation of a well-founded mental model. A mental model +is a collection of concepts and facts, along with the relationships between those concepts, which +a person has about a topic. For example, a long-time resident of the United States may have an +advanced understanding of the location of US states, major cities and landmarks, weather patterns, +regional economies and demographic patterns, as well as the relationships among these, compared +with their understanding of these relationships for other countries. In other words, their mental +model of the United States is more complex compared with their mental model of other countries. + +We can distinguish between a *novice* and a *competent practitioner* for a given domain based +on the complexity of their mental models. + +* A *novice* is someone who has not yet built a mental model of the domain. + They therefore reason by analogy and guesswork, borrowing bits and pieces + of their mental models of other domains which seem superficially similar. +* A *competent practitioner* is someone who has a mental model that's good enough + for everyday purposes. This model does not have to be completely accurate in order + to be useful: for example, the average driver's mental model of how a car works + probably doesn't include most of the complexities that a mechanical engineer + would be concerned with. + +We could expect a mixture of learners from *novice* and *competent practitioner* groups +in HPC training events. + +![Mental Models](https://carpentries.github.io/instructor-training/fig/mental_models.svg) + +--- + +### How “knowledge” gets in the way + +Mental models are hardly ever built from scratch. Every learner comes to a topic with +some amount of information, ideas and opinions about the topic. This is true even in +the case where a learner can’t articulate their prior knowledge and beliefs. + +In many cases, this prior knowledge is incomplete or inaccurate. Inaccurate beliefs +can be termed “misconceptions” and can impede learning by making it more difficult for +learners to incorporate new, correct information into their mental models. +Correcting learners’ misconceptions is at least as important as presenting them with +correct information. Broadly speaking, misconceptions fall into three categories: + +- **Simple factual errors**, such as believing that Vancouver is the capital of + British Columbia. These are the easiest to correct. +- **Broken models**, such as believing that motion and acceleration must be in the + same direction. We can address these by having learners reason through examples to + see contradictions. +- **Fundamental beliefs**, such as “the world is only a few thousand years old” or + “human beings cannot affect the planet’s climate”. These beliefs are deeply connected + to the learner’s social identity and are the hardest to change. + + +The current HPC carpentry workshop material are aimed at **Novice** of HPC + +Among *Novice* learners there might be learners who are experts in their domain and very +competent in the program they are executing, but may not have used a HPC system before. +Then among the **competent practitioners** There might be learners who repeat some procedures +they have inherited but lack a in-depth understanding of what's going on. That is why it is +important to get accurate feedback, before and during the workshops to understand the learner profiles. + + +> ## Exercise: How to identify learner profiles? +> +> 1. How to identify leaner profiles from surveys and during the class +> 2. Which types of learners should the leassons focus on +{: .challenge} + +--- + +## CodeRefinery Curriculum and Reverse Instructional Design (with recommendations for HPC carpentries) + +When writing a CodeRefinery lesson, we take a “reverse” approach to instruction, +as described in Wiggins and McTighe’s +[Understanding by Design](http://www.worldcat.org/title/understanding-by-design/oclc/56491025), +that keeps the focus firmly on learning outcomes. The order of preparation in this case becomes + +- Determine your learning objectives +- Decide what constitutes evidence that objectives have been met, and design assessments + to target that evidence +- Design instruction: Sort assessments in order of increasing complexity, + and write content that connects everything together + +### Working with learning objectives + +Each CodeRefinery lesson (also the HPC capentries lessons) usually has a *learning objectives* section. +Good learning objectives are quite specific about the intended effect of a lesson on its learners. +We aim to create learning objectives that are specific, accurate, and informative for +both learners and instructors. + + +### Using Bloom's Taxonomy to write effective learning objectives + +[Bloom's Taxonomy](https://cft.vanderbilt.edu/guides-sub-pages/blooms-taxonomy/) is a framework for thinking about learning that breaks progress down into discrete, hierarchical steps. +While many ideas have come and gone in education, Bloom's has remained a useful tool for educators, in particular because the +hierarchy seems to be reasonably valid: outcomes at the top of the hierarchy cannot be achieved without mastery of outcomes at +the bottom. In the long term, everybody wants to be at the top. However, in aiming to meet learners where they are, we also +need to be mindful about helping them to ["grow a level,"](https://software-carpentry.org/blog/2018/03/tractenberg-summary.html) helping them to recognize when they have achieved that growth, and +guiding them to look ahead to where we might not be able to take them. + +![Bloom's Taxonomy](https://carpentries.github.io/instructor-training/fig/Blooms.png) + +Image credit: Vanderbilt University Center for Teaching + +### Revisiting Learning objectives + +When using existing teaching material, *reverse instructional design* principles might be applied as +follows: + +1. Review the lesson's learning objectives carefully, thinking about how they will work for your audience +2. Scan the lesson to identify promising points to check in with your learners, using formative assessment to verify that objectives have been met +3. Review the connecting content in detail to be sure everything works and you have anticipated likely problems and questions. + + +We strongly encourage you to read them before teaching a lesson and to review whether they still match the content of the lesson: diff --git a/branch/ignore/_sources/about-coderefinery.md.txt b/branch/ignore/_sources/about-coderefinery.md.txt new file mode 100644 index 0000000..fac5c92 --- /dev/null +++ b/branch/ignore/_sources/about-coderefinery.md.txt @@ -0,0 +1,100 @@ +# About the CodeRefinery project and CodeRefinery workshops + +```{keypoints} +- Teaches intermediate-level software development tool lessons +- Training network for other lessons, too +- Publicly-funded discrete projects (3 projects actually) transitioning towards an open community project +- We have online material, teaching, and exercise sessions +- We want more people to work with us, and to work with more people +``` + +CodeRefinery is a +[Nordic e-Infrastructure Collaboration (NeIC)](https://neic.no/) +project that has started in October 2016 and is +funded until February 2025. + +The funding from 2022-2025 is designed to keep this project active +beyond 2025 by forming a support network and building a community of +instructors and contributors. + +```{discussion} History + +The CodeRefinery project idea grew out of two [SeSE](http://sese.nu) courses given at KTH Stockholm in 2014 and 2016: +- [http://sese.nu/scientific-software-development-toolbox/](http://sese.nu/scientific-software-development-toolbox/) +- [http://sese.nu/scientific-software-development-toolbox-2016/](http://sese.nu/scientific-software-development-toolbox-2016/) + +The project proposal was submitted to NeIC in 2015, accepted in 2015, and started in 2016. + +We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form. +``` + + +## Main goals + +- Develop and maintain **training material on software best practices** for researchers that already write code. Our material addresses all academic disciplines and tries to be as programming language-independent as possible. +- Provide a [code repository hosting service](https://coderefinery.org/repository/) that is open and free for all researchers based in universities and research institutes from Nordic countries. +- Provide **training opportunities** in the Nordics using Carpentries and CodeRefinery training materials. +- Articulate and implement the CodeRefinery **sustainability plan**. + + +## Impact + +We collect feedback and survey results to measure our impact. + +3-6 months after attending a workshop, past participants are asked to complete a short post-workshop survey. +The survey questions aim to establish what impact CodeRefinery workshops have on how past participants develop +research software. + +[Pre- and post-workshop survey results](https://coderefinery.org/about/impact/) + +- Overall quality of research software has improved: more reusable, modular, reproducible and documented. +- Collaboration on research software development has become easier +- Past participants share their new knowledge with colleagues +- Usage of several tools is improved, and new tools are adopted + +[Free-form answers](https://coderefinery.org/#what-do-our-participants-say-after-attending-a-workshop) +also suggest that workshops are having the intended effects on how people develop code. A common theme is: +> *I wish I had known this stuff already as a grad student 10+ years ago...* + +We would love to get suggestions on how we can better quantify our impact. This +would make it easier for us to convince institutions to partner with us and +also open up funding opportunities. + + +## Target audience + +### Carpentries audience + +The Carpentries aims to teach computational **competence** to learners through an applied approach, avoiding the theoretical and general in favor of the practical and specific. + +**Learners do not need to have any prior experience in programming.** One major goal of a Carpentry workshop is to raise awareness on the tools researchers can learn/use to speed up their research. + +By showing learners how to solve specific problems with specific tools and providing hands-on practice, learners develops confidence for future learning. + +> ## Novices +> We often qualify Carpentry learners as **novices**: they do not know what they need to learn yet. A typical example is the usage of version control: the Carpentry `git` lesson aims to give a very high level conceptual overview of Git but it does not explain how it can be used in research projects. +{: .callout} + + +### CodeRefinery audience + +In that sense, CodeRefinery workshops differ from Carpentry workshops as we assume our audience already writes code and scripts and we aim at teaching them **best software practices**. + +Our learners usually do not have a good overview of **best software practices** but are aware of the need to learn them. Very often, they know the tools (Git, Jupyter, etc.) we are teaching but have difficulties to make the best use of them in their software development workflow. + +Whenever we can, we should direct learners that do not have sufficient coding experience to Carpentries workshops. + +> ## Competent practitioners +> We often qualify CodeRefinery learners as **competent practitioners** because they already have an understanding of their needs. +> *Novices* and *competent practitioners* will be more clearly defined in the {doc}`next section <03-teaching-style>`. +{: .callout} + +> ## Best software practices for whom? +> It can be useful to ask the question: *best software practices for whom*? +> CodeRefinery teaches *best software practices* derived from producing and +> shipping software. These practices are also very good for sharing software, +> though our audience will probably not need to embrace *all* aspects of +> software engineering. +{: .callout} diff --git a/branch/ignore/_sources/backward-lesson-design.md.txt b/branch/ignore/_sources/backward-lesson-design.md.txt new file mode 100644 index 0000000..7f141b0 --- /dev/null +++ b/branch/ignore/_sources/backward-lesson-design.md.txt @@ -0,0 +1,152 @@ +(backwards-lesson-design)= + +# Backwards lesson design + +It happens far too often: someone creates a lesson, but they think +about what is interesting to them, not what is important for the +learners. In fact, an earlier version of this instructor training had +this very issue. + +It is critical to backwards design almost any piece of communication, +especially something as widespread as teaching. + + +## The approach + +- You don't think about how to do something and try to explain it. +- Avoid the typical approach *"I want to show a number of things which I think are cool about + tool X - how do I press these into 90 minutes?"* +- Instead, you start defining your target audience by answering to questions + such **What is the expected educational level of my audience?**, **Have they + been already exposed to the technologies I am planning to teach?**, **What + tools do they already use?**, **What are the main issues they are currently + experiencing?**. It is important to discuss these points with a group of + colleagues, preferably from diverse backgrounds and institutions to reduce + biases. Once you clarified your target audience, it is useful to create + **learner personas**; that will help you during the development process by + providing concrete examples of potential learners showing up at your + workshops. For each **learner personas**, try to think of what is **useful to + them**: *"What do they **need** to + [remember/understand/apply/analyze/evaluate/create](https://coderefinery.github.io/instructor-training/03-teaching-style/#using-bloom-s-taxonomy-to-write-effective-learning-objectives)?"*. + Asking and answering to these questions will allow you to define the + background knowledge (starting points) and goals (end points) of your + learners. Then, you create a sequence of exercises which test incrementally + progressing tasks and acquisition of the new skills (from starting to end + points). +- Then, you write the minimum amount + of material to teach the gap between exercises. + + +## The process + +As described in ["A lesson design process" in the book Teaching Tech +Together](https://teachtogether.tech/en/index.html#s:process): + +1. Understand your learners + +2. Brainstorm rough ideas + +3. Create an summative assessment to know your overall goal + + * CodeRefinery translation: think of the things your learners will + be able to do at the end of the lesson. Think simple! The + simpler the better. Think of three main points they will + remember, of which maybe one or two are a concrete skill. + +4. Create formative assessments to go from the starting point to this. + + * CodeRefinery translation: think of some engaging and active + exercises. + +5. Order the formative assessments (exercises) into a reasonable order. + +6. Write just enough material to get from one assessment (exercise) to + another. + +7. Describe the course so the learners know if it is relevant to them. + +We can't emphasize enough how important it is to **know your end +state and keep it simple**. + +```{discussion} Example: designing an HPC Carpentry lesson + +Let's take as an example the *[HPC Carpentry lesson](https://hpc-carpentry.github.io/hpc-intro/)* + +**Target audience** + - What is the expected educational level of my audience? + - A PhD student, postdoc or young researcher. + - Have they been already exposed to the technologies I am planning to teach? + - The word **HPC** is not new to them and they may have already used an HPC but are still not capable of giving a proper definition of HPC. In addition, we do not expect them to know much about parallelism and they cannot make any distinction between various available parallelism paradigms. + - What tools do they already use? + - serial codes, multi-threaded codes, data parallelism; usually out-of-the-box tools. + - they may have tried to "scale" their code (multiprocessing, threading, GPUs) with more or less success. + - What are the main issues they are currently experiencing? + - they cannot solve their problems either because they would like to run the same code but with many different datasets or because their problem is larger (more computations/memory). + - most of the time they know their codes can run on HPC (from the documentation) but never really had the opportunity to try it out. + - Very few will have their own codes where they may have tried different things to speed it up (threading, task parallelism) but have no clear strategy. + +**Learner persona** + - Sonya is a 1st year PhD student: she recently moved to Oslo and joined the + Computational and Systems Neuroscience group. She will be using the + [NEST](https://nest-simulator.readthedocs.io/), a simulator for spiking + neural network model. She used NEST during her master thesis but on her + small cluster: **she never used an HPC resource** and is really excited about it. + - Robert is a field ecologist who obtained his PhD 6 months ago. He is now + working on a new project with Climate scientists and as a consequence will + need to run global climate models. He is **not very familiar with command + line** even though he attended a Software Carpentry workshop and the idea to + use HPC is a bit terrifying. He knows that he will get support from his + team who has extensive experience with HPC but would like to become more + independent and be able to **run his own simulations** (rather than copying + existing cases). + - Jessica is a postdoc working on a project that investigates numerically the + complex dynamics arising at the tip of a fluid-driven rupture. Fluid + dynamics will be computed by a finite element method solving the + compressible Navier-Stokes equations on a moving mesh. She **uses a code she + has developed** during her PhD and that is based on existing libraries. She + has mostly ran it on a local desktop; her work during her PhD was very + limited due to the lack of computing resources and she is now very keen is + **moving to HPC**; she knows that it will requires some work, in particular to + parallelize her code. This HPC training will be her first experience with + HPC. + +**Learning outcomes** + - Understand the difference between HPCs and other local/remote machines + - Understand the notion of core, nodes, cluster, shared/distributed memory, etc. + - Understand the notion of login nodes. + - Understand the need for a scheduler and how to use it appropriately + - Understand why optimising I/O is important on HPC and how to best use HPC filesystems + - Understand the need to parallelize (or use existing parallel) codes and in which cases HPCs is a must (when communications is required) + - Understand how to get your code ready to use on HPC (access to libraries, installation of your own libraries/software, etc.) + - Understand that an HPC is an operational machine and is not meant for developing codes. + +**Exercises** + - Get basic information such the number of CPUs, memory from your laptop and try to do the same on a HPC. Discuss outcomes. + - Try to create files on the different filesystems on your HPC resource and access them. + - Create different types of job scripts, submit and check outputs. + - Make a concrete example to run a specific software on your HPC (something like GROMACS). +``` + + +## Exercises + +```{exercise} Backwards-design a lesson/topic +Choose a simple lesson topic and apply backwards lesson design. You +won't get all the way through, but come up with a logical +progression of exercises. + +The section you pick should require **screen sharing** and be of some **follow-along +task** (preferably using a shell). + +Some suggestions: +- Regular expressions +- Making papers in LaTeX +- Making figures in your favorite programming language +- Linux shell basics +- Something non-technical, such as painting a room +- An instructor training for CodeRefinery +- Some aspect from an already existing lesson +- [Introduction to high-performance computing](https://hpc-carpentry.github.io/hpc-intro/) (or an episode therein) +- [Unix shell in a HPC context](https://hpc-carpentry.github.io/hpc-shell/) (or an episode therein) +- A lesson you always wanted to teach +``` diff --git a/branch/ignore/_sources/collaboration-models.rst.txt b/branch/ignore/_sources/collaboration-models.rst.txt new file mode 100644 index 0000000..11ea3e6 --- /dev/null +++ b/branch/ignore/_sources/collaboration-models.rst.txt @@ -0,0 +1,69 @@ +Collaboration models +==================== + + + +Model: CodeRefinery +------------------- + +* Before Covid-19, workshops were physically around the Nordics, + instructors would travel (or already be there). + + * Maximum size: ~40 people + * High workload per person + +* After several small scaling attempts, now we have: + + * Two large workshops per year - livestream format + * Combined organization efforts + * Instructors from each location - on average two lessons taught. + * Locations with staff can have **local breakout rooms**: physical + place to help during exercises. + +* Others in the world can register and interact using HackMD, but no + promises of help. + +* Content still available to anyone in the world: live + instant + replay. + +* Course page and material: + https://coderefinery.github.io/2022-03-22-workshop/ + + + +Model: Python for Scientific Computing +-------------------------------------- + +* Aalto Scientific Computing wanted to host a course, **Python for + Scientific Computing** +* ASC came up with initial vision and announced it +* ASC hosted an open initial meeting, inviting any interested + organizers or instructors +* We went over the plan and refined the topics and schedule. We also + decided things such as the date, organizers, and instructors for + each lesson. +* Registration was open to everyone in the world, non-Nordic + participants could watch via livestream. +* People prepared their parts and came together and presented. + Organizers kept everything on track. +* **Compared to the amount of effort each person put in, the results + were great.** +* A 2021 version also happened and was even larger. +* Course page: https://scicomp.aalto.fi/training/scip/python-for-scicomp/ +* Material: https://aaltoscicomp.github.io/python-for-scicomp/ + + + +Exercises +--------- + +.. exercise:: List successes and failures in collaborative teaching + + Using HackMD, list some successes and failures in collaborative + teaching that you have experienced. + +.. exercise:: Recommendations for co-teaching + + If you have experience with co-teaching, what approach/technique/trick + can you recommend a colleague who would like to try co-teaching for the + first time? diff --git a/branch/ignore/_sources/distributed.md.txt b/branch/ignore/_sources/distributed.md.txt new file mode 100644 index 0000000..477f0d2 --- /dev/null +++ b/branch/ignore/_sources/distributed.md.txt @@ -0,0 +1,32 @@ +# Distributed workshop organization + +```{keypoints} +- If another university/organization wants to run the course, they can easily join our existing course at little cost/risk to them and to us. +- Each organization that joins provides a great benefit to us (helpers, instructors). +- They can reserve an in-person breakout room and provide mentors while watching the livestream: A great experience for their audience. +``` + + +## It is easier to join and follow than to start or lead + +Organizing a course is time intensive and so is developing a course. Many +courses given in country A are also relevant in other countries and instead of +developing and possibly re-inventing courses independently in different places, +it is so much more rewarding to collaborate and share. + +In our courses we wish and try to make it easier for teams and organizations +and universities to join, at little risk and cost to them, possibly for a short +period of time, possibly only as observer. Later observers can progress to +exercise leads, expert helpers, instructors, and co-organizers. + +One model that we have successfully tried is that the course is delivered via +live-stream to all partners and all the partner needs to do is to reserve a +room and motivate few people to help local learners as exercise leads during +exercise sessions which can happen in-person. + +```{discussion} Lessons learned from organizing larger workshops + +- **One person is needed to coordinate the registration process** and this person should + not have teaching duties in addition to this role. +- Generally it helps to have **well-defined roles** (see {ref}`workshop-roles`). +``` diff --git a/branch/ignore/_sources/diversity-and-inclusion.rst.txt b/branch/ignore/_sources/diversity-and-inclusion.rst.txt new file mode 100644 index 0000000..5baf30d --- /dev/null +++ b/branch/ignore/_sources/diversity-and-inclusion.rst.txt @@ -0,0 +1,58 @@ +Diversity and inclusion +======================= + +When we are teaching, we fill a critical role in between people and +technology. We are not un-involved technical staff teaching asocial +topics, but we are very connected to the social context of the tools. +Unfortunately, there are major demographic imbalances in most +computing. + + + +Primary articles +---------------- + +* Several sections from the Carpentries Instructor Training: + `Motivation and demotivation + `__ + and `Equity, inclusion, accessibility + `__. +* Exercise leaders `During the workshop + `__ + + + +Support services vs diversity +----------------------------- + +Study this presentation by Richard Darst: + +* Watch: https://www.youtube.com/watch?v=z1VS1wleN-o +* Or read: https://docs.google.com/presentation/d/e/2PACX-1vQkzOMFI5SFnx69D4qRq_3N-mtcv7GUbPZd4A6UYpEKZUMGK0FL5W0RsSe6Alzxv1nE635Yl1GpyCKk/pub + +Summary: + +* Computing is hard and quite often our ability to learn quickly is + connected to our social group. +* Good technical services serve the role of mentors +* This mentorship helps to equalize +* Our entire system of research should be configured for more + equality. Modernization usually takes it the other way. + + + +Exercises +--------- + +.. exercise:: Reflect on how your job can be defined to promote diversity. + + What are some (possibly surprising) ways that your job promote + diversity and equality among people of different backgrounds? + + + +See also +-------- + +(none yet) + diff --git a/branch/ignore/_sources/exercises.rst.txt b/branch/ignore/_sources/exercises.rst.txt new file mode 100644 index 0000000..4aa70a7 --- /dev/null +++ b/branch/ignore/_sources/exercises.rst.txt @@ -0,0 +1,10 @@ +Exercise list +============= + +This is a list of all exercises and solutions in this lesson, mainly +as a reference for helpers and instructors. This list is +automatically generated from all of the other pages in the lesson. +Any single teaching event will probably cover only a subset of these, +depending on their interests. + +.. exerciselist:: diff --git a/branch/ignore/_sources/future.md.txt b/branch/ignore/_sources/future.md.txt new file mode 100644 index 0000000..edb0dec --- /dev/null +++ b/branch/ignore/_sources/future.md.txt @@ -0,0 +1,55 @@ +# Possibilities for Carpentries + +```{keypoints} +- Carpentries is currently designed around small workshops, so many of these ideas can't directly apply +- Yet **many of these tools and also team teaching can still be used** +- You can run your own breakout room for any of our workshops +- Join as observer if you want to see our workshop organization and tools in action +``` + +CodeRefinery workshops can be a good progression step after taking a +Carpentries workshop. + +Helping out at a CodeRefinery workshop as exercise lead can be a good +progression step for those who have helped out at a Carpentries workshop or who +have taken the Carpentries instructor training. + + +# CodeRefinery's plans + +```{keypoints} +- We are continuing to focus on online-first with local breakout rooms +- We welcome people joining us, either individually or as an organization +- Still interested in collaboration with Carpentries +- We need to become better at marketing and outreach +``` + + +## Biggest open problems + +- How to give helpers and contributors more credit and visibility +- How to promote/engage new members +- What are we? Non-profit? Institution collaboration network? Selling services? +- Funding and sustainability (but we have ideas: collaboration network) + + +## How you can join + +Individual level: + +- Join [CodeRefinery + chat](https://coderefinery.github.io/manuals/chat/) +- Lead a team, co-teach, or help organize a workshop +- Generally provide marketing and outreach + +Organization level: +- Have your organization join CodeRefinery +- Officially co-advertise and co-teach workshops +- Run local breakout rooms and join a workshop as a team +- Send an observer to a workshop + + +## Aside: Nordic-RSE (research software engineers) + +- [Nordic-RSE online unconference 2022](https://nordic-rse.org/events/2022-online-unconference/) +- [Bi-weekly meetings](https://nordic-rse.org/events/meeting/#community-discussions-biweekly) diff --git a/branch/ignore/_sources/guide.rst.txt b/branch/ignore/_sources/guide.rst.txt new file mode 100644 index 0000000..e05b967 --- /dev/null +++ b/branch/ignore/_sources/guide.rst.txt @@ -0,0 +1,14 @@ +Instructor's guide +------------------ + +In a lesson that was further developed, this would include an +instructor's guide that mentioned: + +* Background of why the course is how it is +* Recommendations of teaching it +* Known pitfalls of teaching it, so that other instructors can avoid + them +* Possibly how to contribute, long-term plans, etc. + +For example, see `git-intro's instructor guide +`__. diff --git a/branch/ignore/_sources/hackmd.rst.txt b/branch/ignore/_sources/hackmd.rst.txt new file mode 100644 index 0000000..1347785 --- /dev/null +++ b/branch/ignore/_sources/hackmd.rst.txt @@ -0,0 +1,66 @@ +HackMD +====== + +The name "HackMD" doesn't do this concept justice, nor do the more +common descriptions of "shared notes" or "collaborative document". It +is a full replacement for chat: perhaps it could be called **random +access chat** or **parallel 2D chat** ? + +**HackMD** itself is a web service for collaborative documents in +Markdown. This isn't special to HackMD, but we have used it for its +scalability, markdown support, and privacy in the "view" mode. + + + +Primary articles +---------------- + +* HackMD instructors for the audience: https://coderefinery.github.io/manuals/hackmd-mechanics/ +* HackMD manager role description: https://coderefinery.github.io/manuals/hackmd-helper/ +* Example published HackMD after six 3-hour CodeRefinery sessions: https://coderefinery.github.io/2022-03-22-workshop/questions/ + + + +Advantages +---------- + +* Synchronous questions, no disadvantage for quiet people. +* Anonymous questions. +* Parallel answers by a large number of helpers. +* Easier to go back and review past questions during Q&A sessions + (compared to scrolling through chat), for example finding important + or unanswered questions. +* The above can make a course feel much more interactive than it would + otherwise. + + + +Disadvantages +------------- + +* *Overwhelming* flood of information + + * But you wanted more interaction, right? + * Co-teaching helps here, one person can focus on watching. + * Students must be warned to be deliberate about where they focus + their attention (different learners have different interests). + +* It is another tool to use + + * Not required for basic learners, learners can begin using when + they are comfortable. + + + +Exercise +-------- + +.. exercise:: + + * Actively use HackMD during this course. + * Observe how the instructors integrate it during the course + itself, and can immediately respond to the questions. + * Observe how instructors occasionally mention and screenshare + HackMD to validate to the audience that it is being watched. + * Keep HackMD open. Can you balance it and watching. Does it + increase or decrease engagement? diff --git a/branch/ignore/_sources/index.rst.txt b/branch/ignore/_sources/index.rst.txt new file mode 100644 index 0000000..1c8841c --- /dev/null +++ b/branch/ignore/_sources/index.rst.txt @@ -0,0 +1,148 @@ +Community teaching training +=========================== + +.. admonition:: Under development (mid 2022) + + As of mid-2022, this material has been reworked for our summer workshop and + for the CarpentryCon 2022 workshop. The material will continue to be + improved before a longer training session in the autumn. + + This material is the new version of our previous `Instructor + training `__. + + +What this course covers +----------------------- + +In 2020, we got farther from our offices but closer to each other. If +you could adapt to the circumstances, a huge number of possibilities +were opened - in particular with collaborative teaching. In this +training, you will learn how we use them. Teaching from 2019 is +almost obsolete - join us to learn more. + +- **Tools of teaching**: how to make the most out of online (and + other) teaching. +- **Workshop organization, collaboratively**: our vision of teaching + together outside of our silos. +- **Socio-technical factors**: social and technical barriers to + learning, why you need to care, and what you can do about them. +- **Lesson development, collaboratively**: how to design lessons and + teaching materials so that they can be open and shared. + + +Who is the course for? +---------------------- + +Teaching is a profession, but also something that everyone needs to be +able to do to some degree, since everyone has their own personal +specialties they will either teach or mentor. + +This course can be relevant for different learner personas: + +- **You run a practical teaching program** at your institution (for example + as part of a research computing group) and would like to learn best + practices for collaborative teaching, so that you aren't re-inventing + the same thing over and over again. + +- **You are a technical specialist** who is frustrated with the way you + currently try to teach others who need to use your software or + infrastructure. You can't spend too much time to become a + professional, but you know you need something more than what you've + been doing. Thus, you would like to adopt some of the best practices of + designing and teaching interactive, hands-on workshops. + +- **You've been teaching alone**, but would like to join a collaboration + network for more co-teaching and to reduce the amount of duplication + of effort. + +- **You are interested in teaching CodeRefinery lessons**, and would like a + comprehensive kick-start to how CodeRefinery works, either to join us, + or teach its lessons with us or independently. + + +.. toctree:: + :maxdepth: 1 + :caption: Preparation + + preparation + + +.. toctree:: + :maxdepth: 1 + :caption: Introduction + + welcome + about-coderefinery + + +.. toctree:: + :maxdepth: 1 + :caption: Teaching tools + + teaching-online + team-teaching + hackmd + teams + livestreaming + instructor-tech-setup + video-recording + video-editing + + distributed + + +.. toctree:: + :maxdepth: 1 + :caption: Workshop organization + + why-teach-together + distributed + collaboration-models + workshop-roles + + +.. toctree:: + :maxdepth: 1 + :caption: Social-technical considerations + + why-are-computers-hard + diversity-and-inclusion + Accessibility and usability (placeholder) + Mentoring (placeholder) + + +.. toctree:: + :maxdepth: 1 + :caption: Lesson design and development + + lessons-with-version-control + backward-lesson-design + + +.. toctree:: + :maxdepth: 1 + :caption: Wrap-up, future, and getting involved + + future + + +.. toctree:: + :maxdepth: 1 + :caption: Reference + + other-resources + guide + exercises + + +.. toctree:: + :maxdepth: 1 + :caption: Old contents - we need to move/merge + + 02-teaching-philosophies.md + 03-teaching-style.md + workshops-online.md + teaching-strategies + teaching-practice.md + +test diff --git a/branch/ignore/_sources/instructor-tech-setup.md.txt b/branch/ignore/_sources/instructor-tech-setup.md.txt new file mode 100644 index 0000000..676f52e --- /dev/null +++ b/branch/ignore/_sources/instructor-tech-setup.md.txt @@ -0,0 +1,93 @@ +# Instructor tech setup + +```{keypoints} +- Screenshare: **portrait layout** instead of sharing entire screen +- Prompt: **adjust your prompt** to make commands easy to read +- **Readability** and beauty is important: adjust your setup for your audience +- **Share the history** of your commands +- Get set up a **few days in advance** and get an outside reviewer +``` + + +## Screenshare + +Compare the following two screen-shares (you can find many more in +[the coderefinery manuals](https://coderefinery.github.io/manuals/instructor-tech-online/): + +```{figure} https://coderefinery.github.io/manuals/_images/screenshare-fullhd.png +:width: 80% + +FullHD. +``` + +```{figure} https://coderefinery.github.io/manuals/_images/s10-kickstart-prompt-log.png +:width: 45% + +Portrait, latest proposed best practices. +``` + +Share a portrait layout (left or right half of your screen) +instead of sharing entire screen. + +Motivation: +- This makes it easier for you to look at some other notes or to coordinate + with other instructors at the same time + without distracting with too much information. +- This makes it possible for participants to have something else open in the + other screen half: terminal or browser or notebook. + + +## Adjust your prompt/configuration/colors + +Adjust your prompt to make commands easy to read. What looks good for your own +work (many terminals, small font, extensions, shortcuts, color scheme) is +usually not the best for other people watching you. Adjust your setup for your +audience. Remove distractions. + +You *need* to spend some time getting set up before you teach. 10 minutes +before the session starts is typically too late. Get set up a **few days in +advance** and get an outside reviewer. + +```{discussion} Should instructors be forced to have a consistent screenshare? + +There are pros and cons to all instructors using the same screenshare and prompt. + +- What are the advantages? +- What are the opportunities of instructors showing different setups? +- How does it depend on the lesson and the experience of learners? +``` + + +## Share the history of your commands + +Even if you type slowly it is almost impossible to follow every command. We +all get distracted or want to read up on something or while following a command +fails on the learner laptop while instructor gets no error. + +Add pauses and share the commands that you have typed so that one can catch up. + + +## More examples and how to set it up + +- Generally making your screen look good (prompt, remove distractions, + command line history, etc): + +- Online setup for screen-shares: + + + +## Exercises + +```{exercise} Evaluate screen captures + +Evaluate screenshots within the [instructor tech +setup](https://coderefinery.github.io/manuals/instructor-tech-online/) lesson. +Use the collaborative document to make a list of the trade-offs of each one. +Which one do you prefer? Which are useful in each situation? +``` + +```{exercise} Set up your own environment + +Set up your screen to teach something. Get some feedback from +another learner. We will discuss among the class. +``` diff --git a/branch/ignore/_sources/lessons-with-version-control.md.txt b/branch/ignore/_sources/lessons-with-version-control.md.txt new file mode 100644 index 0000000..82bed4e --- /dev/null +++ b/branch/ignore/_sources/lessons-with-version-control.md.txt @@ -0,0 +1,106 @@ +# Lesson development with version control + +So, we want to practically share. We have these minimum requirements: + +* Someone can get the preferred form of modification, to improve + without limitation. + +* It is trivial to track differences and send the changes back to the + source, with little cost to the original maintainer. + +Especially with the second of these, version control in an online +platform seems to be the only reasonable option. + + +## Version control and static site generators + +CodeRefinery and the Carpentries use git and Github to develop +lessons. The general procedure is this: + +* Version control to store the raw files in text format +* A static website compiler to convert them to HTML files +* Serving to the public via Github Pages (but this could be replaced + with other systems) + +This allows for true collaborative development and community +contributions. + +Carpentries uses a custom website complierer based on R, CodeRefinery +uses the Sphinx documentation engine which is used in many different +projects for documentation. CodeRefinery's use of a standard tool +allows us to build on a huge and growing ecosystem of extensions and +themes, and promotes local reuse. + +The exact static website generator used isn't so important, as long as +some form of version control is used. + +A open-source license is the last bit to consider: without a license, +it can't be reused and passed on, and there is little incentive for +someone to contribute. + + +## CodeRefinery lesson tools + +CodeRefinery uses the following tools to actually make its lessons +right now: + +* [Sphinx](https://www.sphinx-doc.org/) (a common documentation + generator, widely used in open source projects in general) +* The [sphinx-lesson](https://github.com/coderefinery/sphinx-lesson), which is more of + a small collection of other extensions than new development itself. +* Github for hosting lessons: +* Github Actions and Github Pages for building and web serving our + lessons. + + +## Exercises + +```{exercise} Contribute to a sample lesson +* Open this very lesson in GitHub (it uses the same format as + typical CodeRefinery lessons): + + +* Browse the files and understand the general idea. Check out at + least these and use HackMD to record their functions: + + * .github/workflows/sphinx.yml + * content/conf.py + * content/index.rst + * content/lessons-with-version-control.rst + +* If you want, try to make a pull request to this lesson. It + doesn't have to have any significant content, it can be a pure + test pull request. +``` + +```{exercise} (advanced) Create your own lesson +Use the +[sphinx-lesson-template](https://github.com/coderefinery/sphinx-lesson-template) +to create a new lesson of your choice. Alternatively, use the current +Carpentries system, or some other system of your choice. +``` + + +## Recommendations and lessons learned + +- Convert feedback about lessons and suggestions for improvements into *issues* + so that these don't get lost. +- Make your lesson citable: get a DOI. +- Credit contributors (not only Git commits). +- Instructor guide is essential for new instructors. +- Lesson changes should be accompanied with instructor guide changes (it's like + a documentation for the lesson material). +- Apply and validate {ref}`backwards-lesson-design` again and again. +- Make it possible to try out new ideas (by making the lesson branch-able). +- Before making larger changes, talk with somebody and discuss these changes. +- For substantial changes we recommend to first open an issue and describe your + idea and collect feedback before you start with an extensive rewrite. +- For things still under construction, open a draft pull request to collect + feedback and to signal to others what you are working on. + + +## See also + +- [CodeRefinery git-intro](https://coderefinery.github.io/git-intro/) +- [CodeRefinery git-collaborative](https://coderefinery.github.io/git-collaborative/) +- [Carpentries lesson development](https://docs.carpentries.org/topic_folders/lesson_development/index.html) diff --git a/branch/ignore/_sources/livestreaming.rst.txt b/branch/ignore/_sources/livestreaming.rst.txt new file mode 100644 index 0000000..3ccf56e --- /dev/null +++ b/branch/ignore/_sources/livestreaming.rst.txt @@ -0,0 +1,84 @@ +Livestreaming +============= + +In a large lecture, in effect, you don't interact with most people - +not even close. Yet, trying to force this limited interaction greatly +limits our possible reach, and keeps us in an awkward state of +expecting live interaction yet usually receiving minimal. When we try +this online, it forces a closed + +Teaching via livestreaming allows us to: + +* Reach a near-unlimited number of people +* Fully embrace online tools for interaction, instead of asking people + to speak up. This equalizes the participation for shy or passive + participants. +* By being large, be more efficient and use the extra resources for + meaningful interactions in small groups. + + + +Primary articles +---------------- + +* CodeRefinery MOOC strategy: + https://coderefinery.github.io/manuals/coderefinery-mooc/ +* Intro to livestream teaching: + https://coderefinery.github.io/manuals/livestream-teaching/ +* Broadcaster role description (hints on the actual tools): + https://coderefinery.github.io/manuals/broadcaster/ +* OBS (open broadcaster software) and livestream crash course: + https://coderefinery.github.io/manuals/obs/ + + +Summary +------- + +* There are actually three levels here. + + * In-person + * Online meeting + * Online livestream + +.. figure:: https://coderefinery.github.io/manuals/_images/mooc-diagram.png + + The general presence and information flow within the MOOC strategy. + +* CodeRefinery livestreams via Twitch, but Twitch is not an essential + aspect. + +* We can invite anyone in the world, no risk of disruptions from + trolls. + +* This has enabled us to fully embrace strategies such as HackMD and + co-teaching. + + * While we tried these in-person, they didn't work well since the + loud, extroverted people would dominate. + + + +Tech details +~~~~~~~~~~~~ + +* We stream by using OBS to capture a Zoom meeting. We can switch + between a gallery view, screenshare, and mixed. + +* Dedicated instructor Zoom meeting - no learners. Thus, no chance of + privacy violations. + + * Learners can attend different ways: a) independently online b) + in-person breakout room c) Zoom breakout rooms. + +* We don't have time to get into details here... see the linked + documents and also join us for in-person experience while we improve + our materials more. + + + +Exercises +--------- + +.. exercise:: (advanced) Set up and install OBS as a livestreaming tool. + + This exercise is open-ended. diff --git a/branch/ignore/_sources/other-resources.md.txt b/branch/ignore/_sources/other-resources.md.txt new file mode 100644 index 0000000..0b04ff9 --- /dev/null +++ b/branch/ignore/_sources/other-resources.md.txt @@ -0,0 +1,23 @@ +# Other resources + +- The future of teaching" (35 min content only, 45 min with Q&A, or 15 min reading). + [Watch it on YouTube](https://www.youtube.com/watch?v=S9Jor12Cxdc) + or [read it](https://hackmd.io/KRqQirJ_Rn2SHcE-t1iAUg) if you prefer. +- [The old "CodeRefinery instructor training" + program](https://coderefinery.github.io/instructor-training/): this is + replaced by what you are reading now. +- [CodeRefinery manuals](https://coderefinery.github.io/manuals/) +- Our gradual pathway to instructor from the manuals: + [helper intro](https://coderefinery.github.io/manuals/helper-intro/) and + [instructor intro](https://coderefinery.github.io/manuals/instructor-intro/). +- [Carpentries instructor training](https://carpentries.org/instructors/): + more intensive, but focused only on teaching. +- [Carpentries curriculum development handbook](https://cdh.carpentries.org/) +- [Teaching Tech Together](https://teachtogether.tech/): a book + about similar topics by someone involved in Carpentries. +- [Carpentries general organizational documentation](https://docs.carpentries.org/) +- [How to help someone use a computer, by Phil Agre](https://www.librarian.net/stax/4965/how-to-help-someone-use-a-computer-by-phil-agre/). + Summary: Most of our teaching challenge is helping people to overcome bad user + interface design. +- [The Science of Learning](https://carpentries.github.io/instructor-training/files/papers/science-of-learning-2015.pdf): + provides a brief overview of some key evidence-based results in teaching. diff --git a/branch/ignore/_sources/placeholder.rst.txt b/branch/ignore/_sources/placeholder.rst.txt new file mode 100644 index 0000000..09e5355 --- /dev/null +++ b/branch/ignore/_sources/placeholder.rst.txt @@ -0,0 +1,2 @@ +Placeholder +=========== diff --git a/branch/ignore/_sources/preparation.md.txt b/branch/ignore/_sources/preparation.md.txt new file mode 100644 index 0000000..86b7596 --- /dev/null +++ b/branch/ignore/_sources/preparation.md.txt @@ -0,0 +1,46 @@ +# Pre-workshop preparation + +These things will help you get the most out of this workshop, by +giving you a broad overview at the beginning that you might only get +later on in the lesson. + +Don't worry if you don't have time to do everything here. The most +important ones are listed first. + + +## Read "How to help someone use a computer" (5 min) + +[How to help someone use a computer, by Phil +Agre](https://www.librarian.net/stax/4965/how-to-help-someone-use-a-computer-by-phil-agre/). +Summary: Most of our teaching challenge is helping people to overcome bad user +interface design. + + +## Browse a CodeRefinery lesson (5 min) + +Please take 5 minutes and go through a [CodeRefinery +lesson](https://coderefinery.org/lessons/) and understand the general +layout. Don't go in-depth to any of the material (unless you want, +obviously). We would recommend +[git-intro](https://coderefinery.github.io/git-intro/) if you don't +have a preference. + + +## (optional) Watch "The future of teaching" (35 min content only, 45 min with Q&A, or 15 min reading) + +The "The Future of Teaching" talk is a summary of many things in this +course. You could watch it as a preparation (or if you are reading on +your own, as a summary). This is low priority, since we will cover +most of these things in the course itself. +[Watch it on YouTube](https://www.youtube.com/watch?v=S9Jor12Cxdc) +or [read it](https://hackmd.io/KRqQirJ_Rn2SHcE-t1iAUg) if you prefer. + + +## (optional) Read "The science of learning" (20 min) + +Read this short paper [The Science of +Learning](https://carpentries.github.io/instructor-training/files/papers/science-of-learning-2015.pdf) +which provides a brief overview of some key evidence-based results in +teaching. This paper is also used by [The +Carpentries](https://carpentries.org/) for their Instructor Training +workshops. diff --git a/branch/ignore/_sources/teaching-online.md.txt b/branch/ignore/_sources/teaching-online.md.txt new file mode 100644 index 0000000..1c33476 --- /dev/null +++ b/branch/ignore/_sources/teaching-online.md.txt @@ -0,0 +1,27 @@ +# Teaching online + +Is online teaching better or worse? As usual for that question, "it's +all a trade-off". We believe that many people tried to directly +translate in-person strategies to online, and teaching suffered. In +some ways, this even revealed the flaws of in-person pedagogy (remove +some interaction and not much is left other than an info-dump). + +```{exercise} +Using HackMD, brainstorm advantages and disadvantages of online and +in-person teaching. For each disadvantage of each, think of ways to compensate. + +``` + +* We won't elaborate more here right now - most of the rest of the + course somehow relates to online teaching! +* We will see many techniques which compensate for some of the + disadvantages in the section **tools of teaching**. +* **Workshop organization** will discuss new collaborative + opportunities with online teaching. + + + +## See also + +* The rest of this course +* CodeRefinery manuals: https://coderefinery.github.io/manuals/ diff --git a/branch/ignore/_sources/teaching-practice.md.txt b/branch/ignore/_sources/teaching-practice.md.txt new file mode 100644 index 0000000..1323c86 --- /dev/null +++ b/branch/ignore/_sources/teaching-practice.md.txt @@ -0,0 +1,76 @@ +# Teaching practice and feedback + +Goals of the teaching practice: + +- In groups of 4-5 persons we will practice teaching a **5-minute segment + of a lesson of your choice**. +- The section you pick should require **screen sharing** and be of some + **demonstration or follow-along task** (preferably using a shell) to also + practice having a good screen-sharing setup. +- We will practice giving **constructive feedback**. +- We will practice improving our 5-minute segment by taking the feedback into account. +- In both session you can teach the same topic/segment but if you prefer you can also + change the topic/aspect for the second session. + +--- + +## Instructor demo + +- In order to demonstrate the goals of this section, the instructor + will make a 5-minute demo for your evaluation. +- It is designed to include some good and bad practices for you to + notice. + +--- + +## Teaching demos part 1 + +In group rooms, 50 minutes. + +```{challenge} +- We organize the breakout rooms to not only discuss one lesson/topic so that it is more interesting + to listen and also probably we will all get more useful feedback. +- Give each other **constructive verbal feedback** on the teaching demos, for example + using [this demo rubric](https://carpentries.github.io/instructor-training/demos_rubric/). +- Write down questions (in the collaborative document) that you would like to + discuss in the main room or interesting conclusions which you would like to + share with others. +``` + +## Teaching demos, part 2 + +In group rooms, 50 minutes. + +```{challenge} +- In the second round we distribute the rooms differently so that you can + present it to a **new group of workshop participants** and can receive new + feedback. +- Ask for feedback and one/few point(s) you want to improve. +- In your second trial check whether you feel the demonstration improved. +- Share your lessons learned in the collaborative document. +- Give us also feedback on this exercise format. Was it useful? What can we improve? +``` + +--- + +## Discussion + +```{discussion} Main room discussion + - We discuss questions and conclusions which came up during the group work session. +``` + +--- + +## Optional: feedback for two live-coding examples + +```{challenge} +Teaching by live coding is a +[performance art which requires practice](https://teachtogether.tech/#s:performance-exercises). +This exercise highlights some typical pitfalls that most instructors +fall into sooner or later, and also shows how to avoid them. +Watch closely since we will be giving feedback! +- Watch these two videos: [video 1](https://youtu.be/bXxBeNkKmJE) and + [video 2](https://youtu.be/SkPmwe_WjeY) +- What was better in video 1 and what was better in video 2? +- Please give feedback in the shared workshop document. +``` diff --git a/branch/ignore/_sources/teaching-strategies.md.txt b/branch/ignore/_sources/teaching-strategies.md.txt new file mode 100644 index 0000000..2e93a21 --- /dev/null +++ b/branch/ignore/_sources/teaching-strategies.md.txt @@ -0,0 +1,220 @@ +# How to teach online + +```{objectives} +- Understand the benefits and disadvantage of online teaching, + compared to in-person + +- Set up a good screen share + +- Understand the benefits and disadvantages of team teaching + +- Prepare for the teaching practice +``` + + +## Why teaching mechanics matter + +- When you teach, you are mainly showing a basic example for the + learner to follow along +- The learner has a *lot* more to think about than you do, so you need + to minimize the possible distractions and unnecessary weirdness. +- A learner will often only one small screen, limiting the number of + things that they can think about. +- You are must faster than learners (5 times possibly?) You have to + do things to slow yourself down. +- It's easy to save these mechanics until the end, and then you run + out of time. + + + + +## Shell sharing + +```{discussion} Discussion: what goes into a good shell share or demonstration? + +When you are following along with a type-along demonstration, what +things: + +- Are useful to make it easy to follow along +- Make it harder to follow along + +Answer in the collaborative notes +``` + +When doing any demonstration, there are difficulties: + +- If one misses something, you can't rewind to see it - is there any + way to catch up? +- The learner must get oriented with the whole picture, while + instructor knows precisely where to focus. + +A good **shell share** has some of the following properties: + +- Large font +- Shell history, available separately from the main shell window +- Closely matches the type-along instructions + +We have a collection of shell sharing systems: +- We will look over [lesson presentation +hints](https://coderefinery.github.io/manuals/instructor-tech-setup/#terminal-history-window). +- There are other things you can copy +- Whatever you do, do *something*. + +```{discussion} +The instructor will demonstrate several shell-sharing systems. You +will use this in the teaching practice. +``` + + + +## Screen sharing + +`````{discussion} + +Look at the various [screen layouts in the CodeRefinery +manuals](https://coderefinery.github.io/manuals/instructor-tech-setup/#screen-sharing). +Use the HackMD to comment about what which are better or worse. + +````{output} HackMD prototype +:class: dropdown +``` +- S1 + - good: + - bad: +- S2 + - good: + - bad: +- S3 + - good: + - bad: +- S4 + - good: + - bad: +- Student layouts: + - ... +- Instructor layouts: + - ... +``` +```` +````` + +- Many learners will have a smaller screen than you. +- You should plan for learners with only one small screen. +- A learner will **need to focus on both your screen share and their + work**. +- Sharing your a whole screen is almost always a bad idea, if you want + the learners to do anything at the same time. +- If you constrict yourself, then your experience is more similar to + that of a learner. + +Vertical sharing: +- CodeRefinery has recently started trialing a **vertical share** + system, where you share a vertical half of your screen. +- This allows learners with one screen to display your screen + side-by-side with their learn +- Zoom provides a "Share a part of screen" that is good for this. + + + +## Meta-talk + +Don't just teach, also make sure you guide the learners through the +course. + +- You know what you just discussed, and what is coming next, but + learners are often stuck thinking about now. +- Give a lot of "meta-talk" that is not just about the topic you are + teaching, but how you are teaching it. +- Examples + - **Why** you are doing each episode + - What is the purpose of each exercise + - Clearly state what someone should accomplish in each exercise and + how long it will take - don't assume this is obvious. + - What is the point of each lesson. How much should people expect + to get from it? Should you follow everything, or are some things + advanced and optional? Make that clear. + + + +## Teach teaching + +- Demonstration-based teaching require two different types of focus: + - Doing the mechanical steps as a demonstration + - Explaining why you are doing it +- This is a lot for one person to keep in mind, so can multiple people + work together for this? +- Team teaching idea: + - One person is doing the demonstrations + - One person is giving the commentary about what they are doing + - The lecture becomes a discussion between two people instead. + +Advantages: +- This reduces the pressure on each person (reduces demo effect) +- You are less likely to forget things +- It slows you down in teaching +- It makes the lesson more interesting to listen to +- One person can follow questions +- Great for introducing new instructors (which half is easier to start + with?) + +Disadvantage: +- Requires two people's time +- Requires coordination when preparing (slows you down in preparation) +- Unfamiliar concept to most people + + + +## Questions + +- Questions are great, and important for any practical and interactive + class +- But questions in main room doesn't scale to very large rooms. +- CodeRefinery strategy: HackMD for questions + - Chat is not good enough, you can't reply to old things + - HackMD allows threaded replies and follow up later + - You need some other helpers to watch HackMD and answer, and bring + things up to you. And let you know how things are going. + - Learners can ask anonymously + - Learners don't have to worry about interrupting the flow. + - Disadvantage: can produce information overload, warn people to not + follow too closely + - With too few people, it can turn out to be very quiet. +- We will learn more about HackMD questions tomorrow in + {doc}`workshops-online`. + +```{seealso} +* {doc}`workshops-online` +* [HackMD +mechanics](https://coderefinery.github.io/manuals/hackmd-mechanics/) +and [HackMD +helpers](https://coderefinery.github.io/manuals/hackmd-helper/) on +CodeRefinery manulas. +``` + + + +## Teaching practice + +In {doc}`teaching-practice`, you will break into groups and try to +apply these strategies to a five-minute example session. + + + +## See also + +In this lesson: + +* {doc}`workshops-online` + +CodeRefinery manuals: + +* [Instructor tech + setup](https://coderefinery.github.io/manuals/instructor-tech-setup/) +* [Lesson preparation + hints](https://coderefinery.github.io/manuals/presenting/) (more + focused on in-person) +* [Instructor + introduction](https://coderefinery.github.io/manuals/presenting/) - + has a lot of tips for new instructors, but also more things about + the workshop. +* [Workshop prep call](https://coderefinery.github.io/manuals/workshop-prep-call/) diff --git a/branch/ignore/_sources/team-teaching.rst.txt b/branch/ignore/_sources/team-teaching.rst.txt new file mode 100644 index 0000000..b6531b3 --- /dev/null +++ b/branch/ignore/_sources/team-teaching.rst.txt @@ -0,0 +1,82 @@ +Team teaching +============= + +One of the most significant improvemest of our teaching has been the +concept of **co-teaching**. + +.. admonition:: Co-teaching + + Wikipedia: Co-teaching or team teaching is the division of labor + between educators to plan, organize, instruct and make assessments + on the same group of students, generally in the a common + classroom,[1] and often with a strong focus on those teaching as a + team complementing one another's particular skills or other + strengths. + +*This is not strictly an effect of moving online*. However, the +larger number of instructors and larger audiences make this practical +on a wide scale. + + + +Primary article +--------------- + +https://coderefinery.github.io/manuals/team-teaching/ + + + +Benefits +-------- + +* The course seems very interactive, much more so than expecting + students to speak up. The co-teacher can take on the "voice of the + audience". +* Quicker preparation time since co-teachers can rely on each other in + unexpected situations. +* One co-teacher can be effectively learning at the same time and thus + acting as the "voice of the audience" in another way. +* Great way to onboard new instructors - extensive training and + preparation no longer needed. +* More active minds means better able to watch and react to other + feedback, such as HackMD or chat. +* Less workload - one person does not have to prepare perfectly, any + uncertainty can usually be quickly answered by the other. + + + +Strategies +---------- + +In reality, these strategies are mixed and matched even within a +lesson, and there are many things between these: + +* One person gives lectures, one does the typing during demos. +* "Interview": One primarily doing the "teaching", one guiding by + asking questions - either as an interviewer or as a virtual learner. + +Things that don't work (are not team teaching): + +* Dividing up a lesson into parts, each person gives different parts + independently. + + + +Exercises +--------- + +.. exercise:: + + Divide into groups of two or three. Choose one of the two models + in the team-teaching page, and quickly (5 min) prepare a short + topic (3-5 min) to team teach. You can quickly scan the + "preparation" section at the bottom. + + The challenge is not just to give the lesson, but to prepare the + lesson quickly and rely on each other to give a good lesson anyway. + + +See also +-------- + +(none yet) diff --git a/branch/ignore/_sources/teams.rst.txt b/branch/ignore/_sources/teams.rst.txt new file mode 100644 index 0000000..cf03ccb --- /dev/null +++ b/branch/ignore/_sources/teams.rst.txt @@ -0,0 +1,106 @@ +Teams +===== + +Everyone wants interaction in courses, yet when a group size gets too +large, it doesn't have much interaction. A event in a physical space +naturally makes teams based on who is nearby. When done online, this +needs to be more explicit. + + + +Primary articles +---------------- + +* Exercise leader role description: + https://coderefinery.github.io/manuals/exercise-leaders/ +* Local breakout rooms: + https://coderefinery.github.io/manuals/local-breakout-rooms/?highlight=teams + + + +Basic concepts +-------------- + +- Teams are pre-assigned +- **Exercise leaders** (aka helpers) assigned per team +- Teams stay together during the whole workshop. +- Learners can sign up either alone... +- ... or they can sign up with **a pre-made team**: people who know + each. "bring your own breakout room": + + - When two people in a work group learn a skill, uptake within the + group is often much higher. Thus, we strongly encourage pre-made + teams that know each other. + + - Teams that all come from the same group or field, with a helper + from that field, can transition to help + + + +Online +------ + +In the best online implementations, our teams have these properties: + +- Coordination of breakout rooms is a *lot* of work. +- In zoom, we could request learners to rename to ``(N) Learner + Name``, and then quickly assign people. Now, you can have learners + self-select their rooms. But will they actually do this, or stay in + main room? + +- One helper is assigned per team. + + - In fact, we would limit the number of registrations to 5× the + number of helpers so that all teams have a helper + +- Our registration system (indico) is capable of mailing personalized + messages per person with their team information. This is quite a + bit of work to manage. + +But they have these disadvantages: + +- Much, much harder registration coordination, almost to the point of + being impossible. +- Number of attendees. +- Difficulties when attendees drop out partway through a course. + + + +In-person +--------- + +Teams may natuarally form based on setting location, but + +- Teams may happen naturally by sitting at the same table +- Do teams stay the same day after day? +- Do teams get arranged in a manner useful for learning? +- Do you have one helper per team? +- Do you encourage people to interact explicitly enough? +- Do you ensure that no one gets left out in the crowd? Are the teams + explicit enough? + + + +Discussion: what we actually do +------------------------------- + +- For large enough CodeRefinery workshops, assign teams with one + helper each. Deal with re-adjustment +- The livestream option allows everyone else to follow along. +- In other workshops, create breakout rooms but somehow try let people + self-assign. Most don't. +- For large workshops without enough staff help, livestream and + encourage people to form their own teams and watch themselves - we + don't actually need to be involved. +- Teams can be delegated to a local organizer. + + + +Exercises +--------- + +.. exercise:: Teams + + Consider these questions: + + - Should teams have similar or different people in them? diff --git a/branch/ignore/_sources/video-editing.rst.txt b/branch/ignore/_sources/video-editing.rst.txt new file mode 100644 index 0000000..869a34b --- /dev/null +++ b/branch/ignore/_sources/video-editing.rst.txt @@ -0,0 +1,404 @@ +Video editing +============= + +Video recordings could be useful for people attending a course later, +but also are (perhaps more) useful for **immediate review and catching +up after missing a day in a workshop**. For this, they need to be +released immediately, within a few hours of the workshop. +CodeRefinery can do this. + +Hypothesis: videos must be processed the same evening as they were +recorded, otherwise (it may never happen) or (it's too late to be +useful). To do that, we have to make processing *good enough* (not +perfect) and *fast* and *distributeable* + + +Primary articles +---------------- +* Video editor role description: + https://coderefinery.github.io/manuals/video-editor/ +* ffmpeg-editlist: the primary tool: https://github.com/coderefinery/ffmpeg-editlist + + * Example YAML editlists: + https://github.com/AaltoSciComp/video-editlists-asc + + +Summary +------- + +* Basic principle: privacy is more important than any other factor. + If we can't guarantee privacy, we can't release videos at all. + + - Disclaimers such as "if you don't want to appear in a recording, + leave your video off and don't say anything", since a) accidents + happen especially when coming back from breakout rooms. b) it + creates an incentive to not interact or participate in the course. + +* Livestreaming is important here: by separating the instruction from + the audience audio/video, there is no privacy risk in the raw + recording. They could be released or shared unprocessed. + +* Our overall priorities + + 1) No learner (or anyone not staff) video, audio, names, etc. are + present in the recordings. + 2) Good descriptions. + 3) Removing breaks and other dead time. + 4) Splitting videos into useful chunks (e.g. per-episode), perhaps + equal with the next one: + 5) Good Table of Contents information so learners can jump to the + right spots (this also helps with “good description”.) + +* `ffmpeg-editlist + `__ allows us to + define an edit in a text file (crowdsourceable on Github), and then + generate videos very quickly. + + + +Exercises +--------- + +Exercise A +~~~~~~~~~~ + +These exercises will take you through the whole sequence. + +.. exercise:: Editing-1: Get your sample video + + Download a sample video: + + * Video (raw): http://users.aalto.fi/~darstr1/sample-video/ffmpeg-editlist-demo-kickstart-2023.mkv + * Whisper subtitles (of raw video): + http://users.aalto.fi/~darstr1/sample-video/ffmpeg-editlist-demo-kickstart-2023.srt + * `Schedule of workshop + `__ + (day 1, 11:35--12:25) - used for making the descriptions. + + +.. exercise:: Editing-2: Run Whisper to generate raw subtitles and test video. + + First off, install Whisper and generate the base subtitles, based + on the. Since this is probably too much to expect for a short + lesson, they are provided for you (above), but if you want you can + try using Whisper, or generating the subtitles some other way. + + You can start generating subtitles now, while you do the next + steps, so that they are ready by the time you are ready to apply + the editlist. ffmpeg-editlist can also slice up the subtitles from + the main video to make subtitles for each segment you cut out. + + Whisper is left as an exercise to the reader. + + .. solution:: + + Example Whisper command: + + .. code-block:: + + whisper --device cuda --output_format srt --initial_prompt="Welcome to CodeRefinery day four." --lang en --condition_on_previous_text False INPUT.mkv + + An initial prompt like this make Whisper more likely to output + full sentences, instead of a stream of words with no + punctuation. + + +.. exercise:: Editing-3: Create the basic editlist.yaml file + + Install `ffmpeg-editlist + `__ and try to + follow its instructions, to create an edit with these features: + + * The input definition. + * Two output sections: the "Intro to the course", and "From data + storage to your science" talks (Remember it said the recording + started at 11:35... look at the schedule for hints on when it + might start!). This should have a start/end timestamp from the + *original* video. + + A basic example: + + .. code-block:: yaml + + - input: day1-raw.mkv + + # This is the output from one section. Your result should have two of these sections. + - output: part1.mkv + title: something + description: >- + some long + description of the + segment + editlist: + - start: 10:00 # start timestamp of the section, in *original* video + - end: 20:00 # end timestamp of the section, in the *original* video + + .. solution:: + + This is an excerpt from our `actual editlist file of this course + `__ + + .. code-block:: yaml + + - input: day1-obs.mkv + + - output: day1-intro.mkv + title: 1.2 Introduction + description: >- + General introduction to the workshop. + + https://scicomp.aalto.fi/training/kickstart/intro/ + + editlist: + - start: 00:24:10 + - end: 00:37:31 + + + - output: day1-from-data-storage-to-your-science.mkv + title: "1.3 From data storage to your science" + description: >- + Data is how most computational work starts, whether it is + externally collected, simulation code, or generated. And these + days, you can work on data even remotely, and these workflows + aren't obvious. We discuss how data storage choices lead to + computational workflows. + + https://hackmd.io/@AaltoSciComp/SciCompIntro + + editlist: + - start: 00:37:43 + - end: 00:50:05 + + +.. admonition:: Discussion: what makes a video easy to edit? + :class: discussion + + * Clear speaking and have high audio quality. + * For subtitle generation: Separate sentences cleanly, otherwise it + gets in a "stream of words" instead of "punctuated sentences" + mode. + * Clearly screen-sharing the place you are at, including section + name. + * Clear transitions, "OK, now let's move on to the next lesson, + LESSON-NAME. Going back to the main page, we see it here." + * Clearly indicate where the transitions are + * Hover mouse cursor over the area you are currently talking about. + * Scroll screen when you move on to a new topic. + * Accurate course webpage and sticking to the schedule + + All of these are also good for learners. By editing videos, you + become an advocate for good teaching overall. + + +.. exercise:: Editing-4: Run ffmpeg-editlist + + Install ffmpeg-editlist: ``pip install ffmpeg-editlist[srt]`` (you + may want to use a virtual environment, but these are very minimal + dependencies). + + The ``ffmpeg`` command line tool must be available in your + ``PATH``. + + .. solution:: + + It can be run with (where ``.`` is the directory containing the + input files): + + .. code-block:: console + + $ ffmpeg-editlist editlist.yaml . + + Just running like this is quick and works, but the stream may be + garbled in the first few seconds (because it's missing a key + frame). (A future exercise will go over fixing this. + Basically, add the ``--reencode`` option, which re-encodes the + video (this is **slow**). Don't do it yet. + + Look at the ``.info.txt`` files that come out. + + +.. exercise:: Editing-5: Add more features + + * Several chapter definitions.(re-run and you should see a + ``.info.txt`` file also generated). Video chapter definitions + are timestamps of the *original* video, that get translated to + timestamps of the *output* video. + + .. code-block:: yaml + + - output: part1.mkv + editlist: + - start: 10:00 + - -: Introduction # <-- New, `-` means "at start time" + - 10:45: Part 1 # <-- New + - 15:00: Part 2 # <-- New + - end: 20:00 + + Look at the ``.info.txt`` files that come out now. What is new in it? + + * Add in "workshop title", "workshop description", and see the + ``.info.txt`` files that come out now. This is ready for + copy-pasting into a YouTube description (first line is the title, + rest is the description). + + Look at the new ``.info.txt`` files. What is new? + + .. solution:: + + * This course actually didn't have chapters for the first day + sessions, but you can `see chapters for day 2 here + `__, + for example. + * `Example of the workshop description for this course + `__ + * Example info.txt file for the general introduction to the + course. The part after the ``-----`` is the workshop description. + + .. code-block:: + + 1.2 Introduction - HPC/SciComp Kickstart summer 2023 + + General introduction to the workshop. + + https://scicomp.aalto.fi/training/kickstart/intro/ + + 00:00 Begin introduction <-- Invented for the exercise demo, not real + 03:25 Ways to attend <-- Invented for the exercise demo, not real + 07:12 What if you get lost <-- Invented for the exercise demo, not real + + ----- + + This is part of the Aalto Scientific Computing "Getting + started with Scientific Computing and HPC Kickstart" 2023 + workshop. The videos are available to everyone, but may be + most useful to the people who attended the workshop and want + to review later. + + Playlist: + https://www.youtube.com/playlist?list=PLZLVmS9rf3nMKR2jMglaN4su3ojWtWMVw + + Workshop webpage: + https://scicomp.aalto.fi/training/scip/kickstart-2023/ + + Aalto Scientific Computing: https://scicomp.aalto.fi/ + + +.. exercise:: Editing-6: Subtitles + + Re-run ffmpeg-editlist with the ``--srt`` option (you have to + install it with ``pip install ffmpeg-editlist[srt]`` to pull in the + necessary dependency). Notice how ``.srt`` files come out now. + + Use some subtitle editor to edit the *original* subtitle file, to + fix up any transcription mistakes you may find. You could edit + directly, use ``subtitle-editor`` on Linux, or find some other + tool. + + What do you learn from editing the subtitles? + + .. solution:: + + ..code-block:: + + $ ffmpeg-editlist --srt editlist.yaml + + There should now be a ``.srt`` file also generated. It + generated by finding the ``.srt`` of the original video, and + cutting it the same way it cuts the video. Look and you see it + aligns with the original. + + This means that someone could have been working on fixing the + Whisper subtitles while someone else was doing the yaml-editing. + + +.. exercise:: Editing-6: Subtitles + + Re-run ffmpeg-editlist with the ``--srt`` option (you have to + install it with ``pip install ffmpeg-editlist[srt]`` to pull in the + necessary dependency). Notice how ``.srt`` files come out now. + + Use some subtitle editor to edit the *original* subtitle file, to + fix up any transcription mistakes you may find. You could edit + directly, use ``subtitle-editor`` on Linux, or find some other + tool. + + What do you learn from editing the subtitles? + + +.. exercise:: Editing-7: Generate the final output file. + + * Run ffmpeg-editlist with the ``--reencode`` option: this + re-encodes the video and makes sure that there is no black point + at the start. + + * If you re-run with ``--check``, it won't output a new video file, + but it *will* re-output the ``.info.txt`` and ``.srt`` files. + This is useful when you adjust descriptions or chapters. + + +.. admonition:: Discussion: how to distribute this? + :class: discussion + + Create a flowchat of all the parts that need to be done, and which + parts can be done in parallel. Don't forget things that you might + need to do before the workshop starts. + + How hard was this editing? Was it worth it? + + + +Exercise B +~~~~~~~~~~ + +This is similar to the above but more brief and not on a real example +video. + +.. exercise:: Use ffmpeg-editlist to edit this sample video + + Prerequisites: ``ffmpeg`` must be installed on your computer + outside of Python. Be able to install ffmpeg-editlist. This is + simple in a Python virtual environment, but if not the only + dependency is ``PyYAML``. + + * Download the sample video: http://users.aalto.fi/~darstr1/sample-video/sample-video-to-edit.raw.mkv + * Copy a sample editlist YAML + * Modify it to cut out the dead time at the beginning and the end. + * If desired, add a description and table-of-contents to the + video. + * Run ffmpeg-editlist to produce a processed video. + +.. solution:: + + .. code:: yaml + + - input: sample-video-to-edit.raw.mkv + - output: sample-video-to-edit.processed.mkv + description: > + editlist: + - start: 00:16 + - 00:15: demonstration + - 00:20: discussion + - stop: 00:25 + + .. code:: console + + $ ffmpeg-editlist editlist.yaml video/ -o video/ + + Along with the processed video, we get + ``sample-video-to-edit.processed.mkv.info.txt``:: + + This is a sample video + + + 00:00 Demonstration + 00:04 Discussion + + + +See also +-------- + +* ffmpeg-editlist demo: https://www.youtube.com/watch?v=thvMNTBJg2Y +* Full demo of producing videos (everything in these exercises): https://www.youtube.com/watch?v=_CoBNe-n2Ak +* Example YAML editlists: + https://github.com/AaltoSciComp/video-editlists-asc diff --git a/branch/ignore/_sources/video-recording.md.txt b/branch/ignore/_sources/video-recording.md.txt new file mode 100644 index 0000000..4c051dc --- /dev/null +++ b/branch/ignore/_sources/video-recording.md.txt @@ -0,0 +1,64 @@ +# Video recording + +```{keypoints} +- We don't expect many people to watch the recording from scratch later (but + some do) (some might look afterwards a few pieces, cmp. reading a book vs + look ing sth up from a book) +- Learners getting an "instant replay" to review, or to **make up for a lost day**, is great. +- Privacy is more important than any other factor +- **Recording only works if privacy is guaranteed and effort is low**. + This is only possible with the **instructor-audience split setup** of livestreaming. +``` + + +## We try to release videos on the same day + +Video recordings could be useful for people attending a course later, but also +are (perhaps more) useful for **immediate review and catching up after missing +a day in a workshop**. + +For this, they need to be released immediately, within a few hours of the +workshop (see {doc}`video-editing`). CodeRefinery can do this. + +For the videos to be released soon we need to make sure we guarantee privacy of +learners (see below). Our livestream setup makes the privacy guarantee easy at +the cost of separating instructors and learners into different video rooms. + +Good preparation and documentation helps to make video recording and video +editing easier. + + +## Privacy is more important than any other factor + +If we can't guarantee privacy, we can't release videos at all. + +Some events add a disclaimers such as "if you don't want to appear +in a recording, leave your video off and don't say anything". We +would prefer not to do this, since: +- we *know* accidents happen (especially when coming back from breakout rooms) +- it creates an incentive to not interact by voice/video +- it could pressure participants to not object in order "to not be difficult" + +**Livestreaming solves this for us**: + +- By separating the instruction from + the audience audio/video, there is no privacy risk in the raw + recording. They could be released or shared unprocessed. + +- Recording with Zoom in a large meeting with all the instructors and + learners is simple, but not good for privacy: there are always + mistakes, reviewing takes too long. + +- Livestream platforms also provide instant recordings of the whole + stream, and some make instant replays possible. This could remove + the need for making our own videos, since one of the most important + cases is this instant replay idea. + + +## Broadcasting role and setup + +In the live-streaming setup, the Broadcasting role is central to video +recording. + +Broadcaster description (most is not directly about recording): + diff --git a/branch/ignore/_sources/welcome.md.txt b/branch/ignore/_sources/welcome.md.txt new file mode 100644 index 0000000..a3b9e8c --- /dev/null +++ b/branch/ignore/_sources/welcome.md.txt @@ -0,0 +1,65 @@ +# Welcome and introduction + +```{discussion} What do we want to get out of this workshop +- Introduction of instructors and helpers +- Each instructor can say what we want to get out of the instructor training +- But we want to know from everybody and collect these in the live notes +``` + +--- + +## Goals for this workshop + +```{discussion} Goals for this instructor training +- **Inspire teachers and staff who have to teach indirectly as part of + their job**: use best practices for the modern world, especially + for online teaching. +- **Promote collaboration in teaching**: less going alone. +- **Promote CodeRefinery sustainability**: form a network that can + work together to share the work and benefits. +``` + + +### Giving confidence + +> *Goal number one should be that we give participants the confidence to +> independently apply the tools or knowledge learnt. This is more important +> that giving a "complete" overview.* [Lucy Whalley gave this great comment at one of our workshops] + +- You don't have to know everything to use (or teach) something. +- For the large majority of topics we teach, there are many resources online + which provide how-to guides or tutorials. And the Stack Overflow answer bank + isn't getting any smaller. So we need to ask why do people attend in-person + sessions if there is information freely available? Our impression is that + it is for confidence building, identity formation, perhaps signposting to + resources. +- This also links with building a welcoming/inclusive environment: for example, + imposter syndrome, which disproportionately affects under-represented groups + ([link](https://www.ncda.org/aws/NCDA/pt/sd/news_article/245005/_PARENT/CC_layout_details/false)), + can manifest as low self-confidence --> building the confidence of + students in the classroom may lead to a more diverse community. + +--- + +## Tools for this workshop + +We often start workshops with these: +- [HackMD mechanics and controls](https://coderefinery.github.io/manuals/hackmd-mechanics/) +- [Zoom mechanics and controls](https://coderefinery.github.io/manuals/zoom-mechanics/) (but this got less relevant + since starting teaching via live-streaming where participants only interact via HackMD) + +--- + +## Code of Conduct + +- We follow [The CodeRefinery Code of + Conduct](https://coderefinery.org/about/code-of-conduct/). +- This is a hands-on, interactive workshop. + - Be kind to each other and help each other as best you can. + - If you can't help someone or there is some problem, let someone know. + - If you notice something that prevents you from learning as well as you can, let us know and don't suffer silently. +- It's also about the little things: + - volume + - font size + - generally confusing instructor + - **not enough breaks** diff --git a/branch/ignore/_sources/why-are-computers-hard.rst.txt b/branch/ignore/_sources/why-are-computers-hard.rst.txt new file mode 100644 index 0000000..a36b27a --- /dev/null +++ b/branch/ignore/_sources/why-are-computers-hard.rst.txt @@ -0,0 +1,65 @@ +Why are computers hard? +======================= + +Most of the time, when teaching, our difficulty is not what you expect. + + + +Initial reading +--------------- + +Read the following: + +.. admonition:: How to help someone use a computer, by Phil Agre + + https://www.librarian.net/stax/4965/how-to-help-someone-use-a-computer-by-phil-agre/ + +Of each of the points made, how many are related to: + +* The computing itself +* The user interface +* The ability of the user to work in the computing environment +* Something else + + + +Usability +--------- + +As said in the text above: + + Most user interfaces are terrible. When people make mistakes it’s + usually the fault of the interface. You’ve forgotten how many ways + you’ve learned to adapt to bad interfaces. You’ve forgotten how + many things you once assumed that the interface would be able to + do for you. + + + +Deep abstraction layers +----------------------- + +Most technology is built on abstraction layers, for good reason. They +help simplify implementation and understanding. + + +.. exercise:: + + Think of a tool or technology that is easy to understand and use if + you understand the underlying abstraction layers, but is almost + impossible otherwise. + + + +Conclusion: what are we teaching, then? +--------------------------------------- + +As teachers of computing, we fill a critical role that is more +determined by our audience, than the technology we are teaching. + + + +See also +-------- + +(none yet) diff --git a/branch/ignore/_sources/why-teach-together.rst.txt b/branch/ignore/_sources/why-teach-together.rst.txt new file mode 100644 index 0000000..c2831c3 --- /dev/null +++ b/branch/ignore/_sources/why-teach-together.rst.txt @@ -0,0 +1,84 @@ +Why teach together? +=================== + +We usually say so much about the value of collaboration. Despite us +saying this, our teaching is still far too alone. Covid-19 gave us a +kick that reduced our barriers and led to lasting changes in how we +taught (eventually leading to this very course). + +Open Science / FAIR data is heavily emphazised these days. But let's +add a "C" to FAIR: "collaborative". Instead of people doing their own +thing and releasing, develop, iterate, and maintain **collaboratively**. + + + +Ways to teach together +---------------------- + +* Develop materials together - avoid duplication. +* :doc:`team-teaching` +* Extensive use of helpers and team leaders. +* HackMD for parallel and mass answers. + + + +Advantages +---------- + +* You need to teach anyway, less effort if you combine. +* If done right, minimal extra effort for others to receive benefit (+ + you get publicity). +* Many of the previously presented teaching strategies work best in + large courses - this makes the course more engaging than a small + event with minimal interaction. +* More engaging for the audience. +* Easier on-boarding of new instructors (less "scary" to teach a new course + with other instructors). + + +Challenges and disadvantages +---------------------------- + +* Coordination + + * Finding suitable partners with the same vision + * Coordination efforts (if others don't understand the vision). + +* Materials + + * May not be perfectly tuned to your own audience + * May not iterate as fast as you need + +* Co-teaching + + * Difficulty in finding co-teachers + * Required effort of syncing among staff + * It might revert to independent teaching if you aren't careful. + +* HackMD + + * Can possibly overload both student and teacher. + + + +Exercises +--------- + +.. exercise:: What similarities do we have? + + Using HackMD, make two lists: + + * What courses do you think your local community would benefit + from, which you don't currently have? `+1` other people's items + which are also relevant to you. + + * Which courses are you thinking of preparing for your local + community? `+1` other people's items which you would be + interested in helping out with. + + + +See also +-------- + +* :doc:`collaboration-models` diff --git a/branch/ignore/_sources/workshop-roles.rst.txt b/branch/ignore/_sources/workshop-roles.rst.txt new file mode 100644 index 0000000..351b994 --- /dev/null +++ b/branch/ignore/_sources/workshop-roles.rst.txt @@ -0,0 +1,77 @@ +.. _workshop-roles: + +Workshop roles +============== + +Running massive workshops requires a lot of people. We have a variety +of roles with different levels of support. + +As usual, roles are a plan, and a plans are made to be updated. + + + +Primary articles +---------------- + +* Workshop roles: https://coderefinery.github.io/manuals/roles-overview/ + + + +Summary +------- + +Lower levels mean "top level sometimes split into some of these +sub-roles". + +* **Instructor coordinator:** coordinates schedule and instructors + + * **Instructor:** Teaches along with a co-teacher. + + * **Expert helper:** Spare person, usually watching HackMD but also + rotates among breakout rooms. Often instructs some lessons. + + * **Director:** Manages the flow of the schedule during the + workshop, introduces each lesson, etc. (often the instructor + coordinator) + + * **Broadcaster:** Manages the livestreaming + + * **Video editor:** Edits and publishes videos the day of the + workshop. + +* **Registration coordinator:** coordinates registration, helpers, and + breakout rooms. + + * **Exercise leader coordinator:** Onboards exercise leaders + * **Host:** Manages the learner breakout rooms, learner questions, + etc. (often the registration coordinator) + * **Advertisement coordinator:** Advertises and outreaches + +* Under both registration coordinator and instructor coordinator + + * **HackMD manager:** always watches and formats HackMD and + publishes it same-day. "Eyes on the ground" via HackMD and chat + and quickly communicates important information to instructor and + registration coordinators. + +* **Learner:** attends and learns +* **Exercise leader:** serves as a guide to the team, receives small + amount of training before the workshop. + + + +Exercises +--------- + +.. exercise:: How many people teach in your workshops? + + * Using HackMD, make a histogram of how many (instructors + + organizers) you typically have in your workshops. + * List some of the common roles you have used. + + + +See also +-------- + +(none yet) diff --git a/branch/ignore/_sources/workshops-online.md.txt b/branch/ignore/_sources/workshops-online.md.txt new file mode 100644 index 0000000..abf5222 --- /dev/null +++ b/branch/ignore/_sources/workshops-online.md.txt @@ -0,0 +1,256 @@ +--- +layout: episode +title: "Lessons learned from running online and in-person workshops" +teaching: 20 +exercises: 10 +questions: + - "What are the steps for organizing a CodeRefinery workshop?" + - "What can I learn about running my own workshop?" + - "What have we learned from running large online workshops?" +objectives: + - "Learn how to use the manuals to organize and teach a workshop." +keypoints: + - "There are many aspects to consider to deliver a successful workshop." + - "CodeRefinery maintains a number of manuals - use them when preparing a workshop." +--- + +> ## Workshop manuals +> CodeRefinery maintains a number of [workshop manuals](https://github.com/coderefinery/manuals/) +> with most of the "primary" information. This episode condenses this +> into a quick overview. +{: .callout} + + +# Running a workshop: online + + +## Online teaching discussion + +```{discussion} Discussion: Online vs in-person + +In notes: +- Compare and contrast the benefits of online teaching with + in-person: {advantage, disadvantage} × {content, presentation} +- How do you have to prepare differently? +- What are your own experiences? +``` + + + +## Case study: Mega-CodeRefinery and Finland HPC Kickstart + +- Mega-CodeRefinery + - Audience of around 90-100 + - "bring your own breakout room" (see below) + - 3 days/week, 6 days total + - Lessons as normal in CodeRefinery +- HPC Kickstart + - 250 registered, ~180 max participants + - Multi-university: local differences made this much harder to manage. + - Breakout rooms not pre-planned. + +Mega-CodeRefinery worked very well, HPC kickstart didn't - but not +because of the size. + + + +## General workshop arrangements + +> ## Manuals link +> - [before the +> workshop](https://github.com/coderefinery/manuals/blob/master/workshop-administration.md#before-the-workshop) +{: .callout} + +- Select a coordinator, recruit instructors (at least 3 is important), + find helpers +- Find a good lecture room: + [requirements](https://github.com/coderefinery/manuals/blob/master/workshop-requirements-inperson.md) +- Set up workshop webpage using the [Github, template + repository](https://github.com/coderefinery/template-workshop-webpage]: + [see + manuals](https://github.com/coderefinery/manuals/blob/master/workshop-administration.md#set-up-workshop-page) +- Advertising the workshop +- Communication with registered participants + + + +## CodeRefinery online scaling strategy + +- We started online workshops in 2020 March, for the obvious reasons. +- First, we started with two "normal size" (20 people) practice + workshops +- Then we did a 100 person workshop. It went well, but there is less + tolerance for problems. + + +### Basic preparation + +- You need more breaks are needed +- People have a way of doing too many things and not focusing. +- "[How to attend an online + workshop](https://coderefinery.github.io/manuals/how-to-attend-online/)" + guide to prepare learners + +### Basic platform: Zoom + +- Zoom (not the most ethical, but worked well and was available) +- [Zoom mechanics: instructions for + students](https://coderefinery.github.io/manuals/zoom-mechanics/). + - Mostly things that are known + - We don't use Zoom interaction features much anymore + (faster/slower/etc), but breakout rooms and HackMD instead +- See also: [Online training + manual](https://coderefinery.github.io/manuals/online-training/) + (which is getting a bit old compared to what is below). + +### Breakout rooms, bring your own team + +- Breakout rooms are + - Static: same people across whole workshop + - Contain one helper per room (see below) +- Team registration: accept a "team" field when registering, people on the + same team are put together. + - Gives motivations for learners to bring their colleagues and + learn together. + - More than one person learning together greatly increases update +- You need a powerful enough registration system to assign rooms and + email them to people! +- We ask people to name themselves "(N) Firstname Lastname" or "(N,H) + Firstname Lastname" for helpers. Then it is fast to assign them to + their designated breakout rooms. +- See also: [Breakout room + mechanics](https://coderefinery.github.io/manuals/breakout-rooms-helping/) + + +### Helper training + +- Each breakout room has a helper +- Helper should be a little bit familiar, but not expected to be able + to answer all questions. +- Special, custom [helper + training](https://coderefinery.github.io/manuals/helper-intro/) + since helpers make or break the workshop +- Helper recruitment: + - Our networks + - Team registration: if a team registers with their own helper, then + they are guaranteed to get in together. "bring your own breakout + room" + - Former learners, ask them to come back. +- Two helper trainings the week before the workshop. + +### Staff roles + +To reduce stress on any one person, we clearly define the different +roles and try to avoid overlap. We actually have enough people for +all of these, so it works well. + +- Workshop coordinator + - Registration, etc. +- Zoom host + - Handles registration, breakout rooms, recording, Zoom chat. +- HackMD helper + - Dedicated to watching HackMD and answering questions quickly. + - [Host on manuals](https://coderefinery.github.io/manuals/host/) +- Expert helpers + - "Spare hands" who rotate between breakout rooms and make sure + helpers are doing well. + - Give feedback to instructor about how breakout rooms are going. + - Take the place of missing helpers. + - Easy way for any people with a bit of spare time to help out. + - [Expert helpers in workshop](https://coderefinery.github.io/manuals/expert-helpers/) +- Instructors + - Teach, they shouldn't overlap with the above roles (but serve as + expert helpers other times). + - Usually also improve the lesson a bit before teaching + - [General staff intro in manuals](https://coderefinery.github.io/manuals/instructor-intro/) +- Workshop preparation meeting + - Get together, introduce roles, kickstart instructors + - [Workshop prep meeting in manuals](https://coderefinery.github.io/manuals/workshop-prep-call/) + + +### HackMD + +- We've been using it here +- Chat doesn't work wen large, written + document does. +- HackMD can just about scale to ~100 person workshop. Recommend + learners keep it in view mode while not editing. +- Voice questions are still allowed, but will be recorded. Staff + raise important questions from HackMD to the instructor immediately. +- HackMD also allows communication when in breakout rooms. +- You can get multiple answers, and answers can be improved over + time. +- [HackMD + mechanics](https://coderefinery.github.io/manuals/hackmd-mechanics/) + and [HackMD + helpers](https://coderefinery.github.io/manuals/hackmd-helper/). + +### Recording and streaming + +- When you have 100 people, main room is quiet anyway: you don't lose + much by recording. + - Questions anonymously in HackMD, privacy loss is not so bad +- Breakout rooms are never recorded +- Streaming + - We streamed via Twitch: https://twitch.tv/coderefinery + - We typically get 5-40 viewers. + - Zoom can directly send the stream to Twitch: no extra software + needed. + - Twitch archives videos for 14 days, which allows learners to get + an instant reply (we get hundreds of views in the next days). + - So while possibly not useful for new people to learn, the instant + reply *is* very useful. Instructor can also work on problems in + main stream during breakout rooms, which learners can watch + later. + - Streamers also have access to HackMD to ask questions. +- Certain tricks needed to keep learners from appearing in recording + or stream + - "Spotlight video", host does not go to gallery view, uses dual + monitor mode. We are still figuring this out. + +### Installation time + +- People *have* to be ready once we start, or else everything fails. +- Two installation help times the week before. +- Every email emphasizes that you have to be prepared, and "requires" + you to attend workshops (but really it's only) +- Installation instructions include *steps to verify* +- Installation instructions also include *video demonstrations* of + installation and verification. +- We haven't had that many installation problems, but also we keep the + requirements simple. +- Helper introduction is right before software install time, so + helpers can stay and help with install if they want. +- *Design to be easy to install and get set up.* + +### Other notes + +- Make breakout sessions as long as possible: 10 minutes is really too + short. 20 minutes is a good minimum time. +- Be very clear about exercise expectations +- Keep HackMD updated as a log. +- Don't combine breaks and breakout times. +- The more people you have, the more diverse audience you have and the + more people overwhelmed and under whelmed. + + + +## Workshop collaborations + +Why limit ourselves to CodeRefinery workshop? Why not use our network +and techniquess for more + +- Case study: [Python for Scientific + Computing](https://aaltoscicomp.github.io/python-for-scicomp/) + - Started by Aalto + - Announced to CodeRefinery, five more instructors from three + countries joined. + - Rapid collaboration, taught course shortly later. + - Announced to all institutions. Some places had physical rooms, + some were pure online + - Also streamed + - It was much more fun and less stressful to work together + +- We want to continue this kind of collaboration in other workshops. + + diff --git a/branch/ignore/_static/_sphinx_javascript_frameworks_compat.js b/branch/ignore/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 0000000..8141580 --- /dev/null +++ b/branch/ignore/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/branch/ignore/_static/basic.css b/branch/ignore/_static/basic.css new file mode 100644 index 0000000..30fee9d --- /dev/null +++ b/branch/ignore/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/branch/ignore/_static/check-solid.svg b/branch/ignore/_static/check-solid.svg new file mode 100644 index 0000000..92fad4b --- /dev/null +++ b/branch/ignore/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/branch/ignore/_static/clipboard.min.js b/branch/ignore/_static/clipboard.min.js new file mode 100644 index 0000000..54b3c46 --- /dev/null +++ b/branch/ignore/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/branch/ignore/_static/copybutton.css b/branch/ignore/_static/copybutton.css new file mode 100644 index 0000000..f1916ec --- /dev/null +++ b/branch/ignore/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/branch/ignore/_static/copybutton.js b/branch/ignore/_static/copybutton.js new file mode 100644 index 0000000..2ea7ff3 --- /dev/null +++ b/branch/ignore/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/branch/ignore/_static/copybutton_funcs.js b/branch/ignore/_static/copybutton_funcs.js new file mode 100644 index 0000000..dbe1aaa --- /dev/null +++ b/branch/ignore/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/branch/ignore/_static/css/badge_only.css b/branch/ignore/_static/css/badge_only.css new file mode 100644 index 0000000..c718cee --- /dev/null +++ b/branch/ignore/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/branch/ignore/_static/css/fonts/Roboto-Slab-Bold.woff b/branch/ignore/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/branch/ignore/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/branch/ignore/_static/css/fonts/Roboto-Slab-Bold.woff2 b/branch/ignore/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/branch/ignore/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/branch/ignore/_static/css/fonts/Roboto-Slab-Regular.woff b/branch/ignore/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/branch/ignore/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/branch/ignore/_static/css/fonts/Roboto-Slab-Regular.woff2 b/branch/ignore/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/branch/ignore/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/branch/ignore/_static/css/fonts/fontawesome-webfont.eot b/branch/ignore/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/branch/ignore/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/branch/ignore/_static/css/fonts/fontawesome-webfont.svg b/branch/ignore/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/branch/ignore/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/branch/ignore/_static/css/fonts/fontawesome-webfont.ttf b/branch/ignore/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/branch/ignore/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/branch/ignore/_static/css/fonts/fontawesome-webfont.woff b/branch/ignore/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/branch/ignore/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/branch/ignore/_static/css/fonts/fontawesome-webfont.woff2 b/branch/ignore/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/branch/ignore/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/branch/ignore/_static/css/fonts/lato-bold-italic.woff b/branch/ignore/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/branch/ignore/_static/css/fonts/lato-bold-italic.woff differ diff --git a/branch/ignore/_static/css/fonts/lato-bold-italic.woff2 b/branch/ignore/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/branch/ignore/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/branch/ignore/_static/css/fonts/lato-bold.woff b/branch/ignore/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/branch/ignore/_static/css/fonts/lato-bold.woff differ diff --git a/branch/ignore/_static/css/fonts/lato-bold.woff2 b/branch/ignore/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/branch/ignore/_static/css/fonts/lato-bold.woff2 differ diff --git a/branch/ignore/_static/css/fonts/lato-normal-italic.woff b/branch/ignore/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/branch/ignore/_static/css/fonts/lato-normal-italic.woff differ diff --git a/branch/ignore/_static/css/fonts/lato-normal-italic.woff2 b/branch/ignore/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/branch/ignore/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/branch/ignore/_static/css/fonts/lato-normal.woff b/branch/ignore/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/branch/ignore/_static/css/fonts/lato-normal.woff differ diff --git a/branch/ignore/_static/css/fonts/lato-normal.woff2 b/branch/ignore/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/branch/ignore/_static/css/fonts/lato-normal.woff2 differ diff --git a/branch/ignore/_static/css/theme.css b/branch/ignore/_static/css/theme.css new file mode 100644 index 0000000..19a446a --- /dev/null +++ b/branch/ignore/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/branch/ignore/_static/doctools.js b/branch/ignore/_static/doctools.js new file mode 100644 index 0000000..d06a71d --- /dev/null +++ b/branch/ignore/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/branch/ignore/_static/documentation_options.js b/branch/ignore/_static/documentation_options.js new file mode 100644 index 0000000..87fc516 --- /dev/null +++ b/branch/ignore/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'dirhtml', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/branch/ignore/_static/file.png b/branch/ignore/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/branch/ignore/_static/file.png differ diff --git a/branch/ignore/_static/jquery.js b/branch/ignore/_static/jquery.js new file mode 100644 index 0000000..c4c6022 --- /dev/null +++ b/branch/ignore/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!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(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=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,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).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 w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\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(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.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,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){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 H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.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--)b.attrHandle[n[r]]=t}function pe(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 de(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 d=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")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.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}},b.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[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.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},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),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(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.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},j=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)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(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==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(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?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{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 G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.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("(^|"+M+")"+e+"("+M+"|$)"))&&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:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.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 S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(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").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.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),m(t)&&(t=t.call(e,n,S.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)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.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"===S.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"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.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)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.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?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.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)}}),S.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){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/ignore/_static/js/html5shiv.min.js b/branch/ignore/_static/js/html5shiv.min.js new file mode 100644 index 0000000..cd1c674 --- /dev/null +++ b/branch/ignore/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/ignore/_static/js/theme.js b/branch/ignore/_static/js/theme.js new file mode 100644 index 0000000..1fddb6e --- /dev/null +++ b/branch/ignore/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/branch/ignore/_static/minipres.js b/branch/ignore/_static/minipres.js new file mode 100644 index 0000000..ad11c87 --- /dev/null +++ b/branch/ignore/_static/minipres.js @@ -0,0 +1,223 @@ +// Add goTo method to elements +// http://stackoverflow.com/questions/4801655/how-to-go-to-a-specific-element-on-page +(function($) { + $.fn.goTo = function() { + $('html, body').animate({ + scrollTop: $(this).offset().top //+ 'px' + }, 'fast'); + return this; // for chaining... + } +})(jQuery); + +// NO good way to do this!. Copy a hack from here +// https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript +// https://stackoverflow.com/a/2880929 +var urlParams; +(window.onpopstate = function () { + var match, + pl = /\+/g, // Regex for replacing addition symbol with a space + search = /([^&=]+)=?([^&]*)/g, + decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, + query = window.location.search.substring(1); + urlParams = {}; + while (match = search.exec(query)) + urlParams[decode(match[1])] = decode(match[2]); +})(); + +// Select heading levels +var maxHeading = urlParams['h'] +if (maxHeading === undefined) maxHeading = 2 +var headingLevels = []; +for (h=2 ; h (sections.length-1) ) { + // if we would scroll past bottom, or above top, do nothing + return; + } + + console.log('xxxxxx'); + var targetSection = sections[targetPos]; + console.log(targetSection, typeof(targetSection)); + + // Return targetSection top and height + var secProperties = section_top_and_height(targetSection); + var top = secProperties['top']; + var height = secProperties['height'] + var win_height = window.innerHeight; + //console.info(top, height, win_height) + + var scroll_to = 0; + if (height >= win_height || height == 0) { + scroll_to = top; + } else { + scroll_to = top - (win_height-height)/3.; + } + //console.info(top, height, win_height, scroll_to) + + $('html, body').animate({ + scrollTop: scroll_to //+ 'px' + }, 'fast'); + +} + + +function minipres() { + /* Enable the minipres mode: + - call the hide() function + - set up the scrolling listener + */ + document.addEventListener('keydown', function (event) { + switch(event.which) { + case 37: // left + switch_slide(-1); + event.preventDefault(); + return false; + break; + //case 38: // up + case 39: // right + switch_slide(+1); + event.preventDefault(); + return false; + break; + //case 40: // down + default: + return; // exit this handler for other keys + } + }, true) + + hide() + + // Increase space between sections + //$("div .section").css('margin-bottom', '50%'); + $(sectionSelector).css('margin-top', '50%'); + + // Reduce size/color of other sections + if (hiddenSectionSelector.length > 0) { + var hideNodes = $(hiddenSectionSelector); + console.log(typeof hideNodes, hideNodes); + for (node in hideNodes) { + console.log("a", typeof node, node); + node = hideNodes[node]; // what's right way to iterate values? + console.log("b", typeof node, node); + if (node.parentNode && node.parentNode.className == "section") { + node = node.parentNode; + console.log("c", typeof node, node); + //node.css['transform'] = 'scale(.5)'; + //node.css['transform-origin'] = 'top center'; + $(node).css('color', 'lightgrey'); + //$(node).css('font-size', '20%'); + //$(node).css('visibility', 'collapse'); + //ntahousnatouhasno; + } + } + } +} + +function hide() { + /* Hide all non-essential elements on the page + */ + + // This is for sphinx_rst_theme and readthedocs + $(".wy-nav-side").remove(); + $(".wy-nav-content-wrap").css('margin-left', 0); + $('.rst-versions').remove(); // readthedocs version selector + + // Add other formats here. +} + + +var slideshow = minipres; + +if (window.location.search.match(/[?&](minipres|slideshow|pres)([=&]|$)/) ) { + //minipres() + window.addEventListener("load", minipres); +} else if (window.location.search.match(/[?&](plain)([=&]|$)/) ) { + window.addEventListener("load", hide); +} diff --git a/branch/ignore/_static/minus.png b/branch/ignore/_static/minus.png new file mode 100644 index 0000000..d96755f Binary files /dev/null and b/branch/ignore/_static/minus.png differ diff --git a/branch/ignore/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css b/branch/ignore/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css new file mode 100644 index 0000000..3356631 --- /dev/null +++ b/branch/ignore/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css @@ -0,0 +1,2342 @@ +/* Variables */ +:root { + --mystnb-source-bg-color: #f7f7f7; + --mystnb-stdout-bg-color: #fcfcfc; + --mystnb-stderr-bg-color: #fdd; + --mystnb-traceback-bg-color: #fcfcfc; + --mystnb-source-border-color: #ccc; + --mystnb-source-margin-color: green; + --mystnb-stdout-border-color: #f7f7f7; + --mystnb-stderr-border-color: #f7f7f7; + --mystnb-traceback-border-color: #ffd6d6; + --mystnb-hide-prompt-opacity: 70%; + --mystnb-source-border-radius: .4em; + --mystnb-source-border-width: 1px; +} + +/* Whole cell */ +div.container.cell { + padding-left: 0; + margin-bottom: 1em; +} + +/* Removing all background formatting so we can control at the div level */ +.cell_input div.highlight, +.cell_output pre, +.cell_input pre, +.cell_output .output { + border: none; + box-shadow: none; +} + +.cell_output .output pre, +.cell_input pre { + margin: 0px; +} + +/* Input cells */ +div.cell div.cell_input, +div.cell details.above-input>summary { + padding-left: 0em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + background-color: var(--mystnb-source-bg-color); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; + border-radius: var(--mystnb-source-border-radius); +} + +div.cell_input>div, +div.cell_output div.output>div.highlight { + margin: 0em !important; + border: none !important; +} + +/* All cell outputs */ +.cell_output { + padding-left: 1em; + padding-right: 0em; + margin-top: 1em; +} + +/* Text outputs from cells */ +.cell_output .output.text_plain, +.cell_output .output.traceback, +.cell_output .output.stream, +.cell_output .output.stderr { + margin-top: 1em; + margin-bottom: 0em; + box-shadow: none; +} + +.cell_output .output.text_plain, +.cell_output .output.stream { + background: var(--mystnb-stdout-bg-color); + border: 1px solid var(--mystnb-stdout-border-color); +} + +.cell_output .output.stderr { + background: var(--mystnb-stderr-bg-color); + border: 1px solid var(--mystnb-stderr-border-color); +} + +.cell_output .output.traceback { + background: var(--mystnb-traceback-bg-color); + border: 1px solid var(--mystnb-traceback-border-color); +} + +/* Collapsible cell content */ +div.cell details.above-input div.cell_input { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-top: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; +} + +div.cell div.cell_input.above-output-prompt { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +div.cell details.above-input>summary { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; + padding-left: 1em; + margin-bottom: 0; +} + +div.cell details.above-output>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.below-input>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-top: none; + border-bottom-left-radius: var(--mystnb-source-border-radius); + border-bottom-right-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.hide>summary>span { + opacity: var(--mystnb-hide-prompt-opacity); +} + +div.cell details.hide[open]>summary>span.collapsed { + display: none; +} + +div.cell details.hide:not([open])>summary>span.expanded { + display: none; +} + +@keyframes collapsed-fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} +div.cell details.hide[open]>summary~* { + -moz-animation: collapsed-fade-in 0.3s ease-in-out; + -webkit-animation: collapsed-fade-in 0.3s ease-in-out; + animation: collapsed-fade-in 0.3s ease-in-out; +} + +/* Math align to the left */ +.cell_output .MathJax_Display { + text-align: left !important; +} + +/* Pandas tables. Pulled from the Jupyter / nbsphinx CSS */ +div.cell_output table { + border: none; + border-collapse: collapse; + border-spacing: 0; + color: black; + font-size: 1em; + table-layout: fixed; +} + +div.cell_output thead { + border-bottom: 1px solid black; + vertical-align: bottom; +} + +div.cell_output tr, +div.cell_output th, +div.cell_output td { + text-align: right; + vertical-align: middle; + padding: 0.5em 0.5em; + line-height: normal; + white-space: normal; + max-width: none; + border: none; +} + +div.cell_output th { + font-weight: bold; +} + +div.cell_output tbody tr:nth-child(odd) { + background: #f5f5f5; +} + +div.cell_output tbody tr:hover { + background: rgba(66, 165, 245, 0.2); +} + +/** source code line numbers **/ +span.linenos { + opacity: 0.5; +} + +/* Inline text from `paste` operation */ + +span.pasted-text { + font-weight: bold; +} + +span.pasted-inline img { + max-height: 2em; +} + +tbody span.pasted-inline img { + max-height: none; +} + +/* Font colors for translated ANSI escape sequences +Color values are copied from Jupyter Notebook +https://github.com/jupyter/notebook/blob/52581f8eda9b319eb0390ac77fe5903c38f81e3e/notebook/static/notebook/less/ansicolors.less#L14-L21 +Background colors from +https://nbsphinx.readthedocs.io/en/latest/code-cells.html#ANSI-Colors +*/ +div.highlight .-Color-Bold { + font-weight: bold; +} + +div.highlight .-Color[class*=-Black] { + color: #3E424D +} + +div.highlight .-Color[class*=-Red] { + color: #E75C58 +} + +div.highlight .-Color[class*=-Green] { + color: #00A250 +} + +div.highlight .-Color[class*=-Yellow] { + color: #DDB62B +} + +div.highlight .-Color[class*=-Blue] { + color: #208FFB +} + +div.highlight .-Color[class*=-Magenta] { + color: #D160C4 +} + +div.highlight .-Color[class*=-Cyan] { + color: #60C6C8 +} + +div.highlight .-Color[class*=-White] { + color: #C5C1B4 +} + +div.highlight .-Color[class*=-BGBlack] { + background-color: #3E424D +} + +div.highlight .-Color[class*=-BGRed] { + background-color: #E75C58 +} + +div.highlight .-Color[class*=-BGGreen] { + background-color: #00A250 +} + +div.highlight .-Color[class*=-BGYellow] { + background-color: #DDB62B +} + +div.highlight .-Color[class*=-BGBlue] { + background-color: #208FFB +} + +div.highlight .-Color[class*=-BGMagenta] { + background-color: #D160C4 +} + +div.highlight .-Color[class*=-BGCyan] { + background-color: #60C6C8 +} + +div.highlight .-Color[class*=-BGWhite] { + background-color: #C5C1B4 +} + +/* Font colors for 8-bit ANSI */ + +div.highlight .-Color[class*=-C0] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC0] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C1] { + color: #800000 +} + +div.highlight .-Color[class*=-BGC1] { + background-color: #800000 +} + +div.highlight .-Color[class*=-C2] { + color: #008000 +} + +div.highlight .-Color[class*=-BGC2] { + background-color: #008000 +} + +div.highlight .-Color[class*=-C3] { + color: #808000 +} + +div.highlight .-Color[class*=-BGC3] { + background-color: #808000 +} + +div.highlight .-Color[class*=-C4] { + color: #000080 +} + +div.highlight .-Color[class*=-BGC4] { + background-color: #000080 +} + +div.highlight .-Color[class*=-C5] { + color: #800080 +} + +div.highlight .-Color[class*=-BGC5] { + background-color: #800080 +} + +div.highlight .-Color[class*=-C6] { + color: #008080 +} + +div.highlight .-Color[class*=-BGC6] { + background-color: #008080 +} + +div.highlight .-Color[class*=-C7] { + color: #C0C0C0 +} + +div.highlight .-Color[class*=-BGC7] { + background-color: #C0C0C0 +} + +div.highlight .-Color[class*=-C8] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC8] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C9] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC9] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C10] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC10] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C11] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC11] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C12] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC12] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C13] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC13] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C14] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC14] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C15] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC15] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C16] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC16] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C17] { + color: #00005F +} + +div.highlight .-Color[class*=-BGC17] { + background-color: #00005F +} + +div.highlight .-Color[class*=-C18] { + color: #000087 +} + +div.highlight .-Color[class*=-BGC18] { + background-color: #000087 +} + +div.highlight .-Color[class*=-C19] { + color: #0000AF +} + +div.highlight .-Color[class*=-BGC19] { + background-color: #0000AF +} + +div.highlight .-Color[class*=-C20] { + color: #0000D7 +} + +div.highlight .-Color[class*=-BGC20] { + background-color: #0000D7 +} + +div.highlight .-Color[class*=-C21] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC21] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C22] { + color: #005F00 +} + +div.highlight .-Color[class*=-BGC22] { + background-color: #005F00 +} + +div.highlight .-Color[class*=-C23] { + color: #005F5F +} + +div.highlight .-Color[class*=-BGC23] { + background-color: #005F5F +} + +div.highlight .-Color[class*=-C24] { + color: #005F87 +} + +div.highlight .-Color[class*=-BGC24] { + background-color: #005F87 +} + +div.highlight .-Color[class*=-C25] { + color: #005FAF +} + +div.highlight .-Color[class*=-BGC25] { + background-color: #005FAF +} + +div.highlight .-Color[class*=-C26] { + color: #005FD7 +} + +div.highlight .-Color[class*=-BGC26] { + background-color: #005FD7 +} + +div.highlight .-Color[class*=-C27] { + color: #005FFF +} + +div.highlight .-Color[class*=-BGC27] { + background-color: #005FFF +} + +div.highlight .-Color[class*=-C28] { + color: #008700 +} + +div.highlight .-Color[class*=-BGC28] { + background-color: #008700 +} + +div.highlight .-Color[class*=-C29] { + color: #00875F +} + +div.highlight .-Color[class*=-BGC29] { + background-color: #00875F +} + +div.highlight .-Color[class*=-C30] { + color: #008787 +} + +div.highlight .-Color[class*=-BGC30] { + background-color: #008787 +} + +div.highlight .-Color[class*=-C31] { + color: #0087AF +} + +div.highlight .-Color[class*=-BGC31] { + background-color: #0087AF +} + +div.highlight .-Color[class*=-C32] { + color: #0087D7 +} + +div.highlight .-Color[class*=-BGC32] { + background-color: #0087D7 +} + +div.highlight .-Color[class*=-C33] { + color: #0087FF +} + +div.highlight .-Color[class*=-BGC33] { + background-color: #0087FF +} + +div.highlight .-Color[class*=-C34] { + color: #00AF00 +} + +div.highlight .-Color[class*=-BGC34] { + background-color: #00AF00 +} + +div.highlight .-Color[class*=-C35] { + color: #00AF5F +} + +div.highlight .-Color[class*=-BGC35] { + background-color: #00AF5F +} + +div.highlight .-Color[class*=-C36] { + color: #00AF87 +} + +div.highlight .-Color[class*=-BGC36] { + background-color: #00AF87 +} + +div.highlight .-Color[class*=-C37] { + color: #00AFAF +} + +div.highlight .-Color[class*=-BGC37] { + background-color: #00AFAF +} + +div.highlight .-Color[class*=-C38] { + color: #00AFD7 +} + +div.highlight .-Color[class*=-BGC38] { + background-color: #00AFD7 +} + +div.highlight .-Color[class*=-C39] { + color: #00AFFF +} + +div.highlight .-Color[class*=-BGC39] { + background-color: #00AFFF +} + +div.highlight .-Color[class*=-C40] { + color: #00D700 +} + +div.highlight .-Color[class*=-BGC40] { + background-color: #00D700 +} + +div.highlight .-Color[class*=-C41] { + color: #00D75F +} + +div.highlight .-Color[class*=-BGC41] { + background-color: #00D75F +} + +div.highlight .-Color[class*=-C42] { + color: #00D787 +} + +div.highlight .-Color[class*=-BGC42] { + background-color: #00D787 +} + +div.highlight .-Color[class*=-C43] { + color: #00D7AF +} + +div.highlight .-Color[class*=-BGC43] { + background-color: #00D7AF +} + +div.highlight .-Color[class*=-C44] { + color: #00D7D7 +} + +div.highlight .-Color[class*=-BGC44] { + background-color: #00D7D7 +} + +div.highlight .-Color[class*=-C45] { + color: #00D7FF +} + +div.highlight .-Color[class*=-BGC45] { + background-color: #00D7FF +} + +div.highlight .-Color[class*=-C46] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC46] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C47] { + color: #00FF5F +} + +div.highlight .-Color[class*=-BGC47] { + background-color: #00FF5F +} + +div.highlight .-Color[class*=-C48] { + color: #00FF87 +} + +div.highlight .-Color[class*=-BGC48] { + background-color: #00FF87 +} + +div.highlight .-Color[class*=-C49] { + color: #00FFAF +} + +div.highlight .-Color[class*=-BGC49] { + background-color: #00FFAF +} + +div.highlight .-Color[class*=-C50] { + color: #00FFD7 +} + +div.highlight .-Color[class*=-BGC50] { + background-color: #00FFD7 +} + +div.highlight .-Color[class*=-C51] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC51] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C52] { + color: #5F0000 +} + +div.highlight .-Color[class*=-BGC52] { + background-color: #5F0000 +} + +div.highlight .-Color[class*=-C53] { + color: #5F005F +} + +div.highlight .-Color[class*=-BGC53] { + background-color: #5F005F +} + +div.highlight .-Color[class*=-C54] { + color: #5F0087 +} + +div.highlight .-Color[class*=-BGC54] { + background-color: #5F0087 +} + +div.highlight .-Color[class*=-C55] { + color: #5F00AF +} + +div.highlight .-Color[class*=-BGC55] { + background-color: #5F00AF +} + +div.highlight .-Color[class*=-C56] { + color: #5F00D7 +} + +div.highlight .-Color[class*=-BGC56] { + background-color: #5F00D7 +} + +div.highlight .-Color[class*=-C57] { + color: #5F00FF +} + +div.highlight .-Color[class*=-BGC57] { + background-color: #5F00FF +} + +div.highlight .-Color[class*=-C58] { + color: #5F5F00 +} + +div.highlight .-Color[class*=-BGC58] { + background-color: #5F5F00 +} + +div.highlight .-Color[class*=-C59] { + color: #5F5F5F +} + +div.highlight .-Color[class*=-BGC59] { + background-color: #5F5F5F +} + +div.highlight .-Color[class*=-C60] { + color: #5F5F87 +} + +div.highlight .-Color[class*=-BGC60] { + background-color: #5F5F87 +} + +div.highlight .-Color[class*=-C61] { + color: #5F5FAF +} + +div.highlight .-Color[class*=-BGC61] { + background-color: #5F5FAF +} + +div.highlight .-Color[class*=-C62] { + color: #5F5FD7 +} + +div.highlight .-Color[class*=-BGC62] { + background-color: #5F5FD7 +} + +div.highlight .-Color[class*=-C63] { + color: #5F5FFF +} + +div.highlight .-Color[class*=-BGC63] { + background-color: #5F5FFF +} + +div.highlight .-Color[class*=-C64] { + color: #5F8700 +} + +div.highlight .-Color[class*=-BGC64] { + background-color: #5F8700 +} + +div.highlight .-Color[class*=-C65] { + color: #5F875F +} + +div.highlight .-Color[class*=-BGC65] { + background-color: #5F875F +} + +div.highlight .-Color[class*=-C66] { + color: #5F8787 +} + +div.highlight .-Color[class*=-BGC66] { + background-color: #5F8787 +} + +div.highlight .-Color[class*=-C67] { + color: #5F87AF +} + +div.highlight .-Color[class*=-BGC67] { + background-color: #5F87AF +} + +div.highlight .-Color[class*=-C68] { + color: #5F87D7 +} + +div.highlight .-Color[class*=-BGC68] { + background-color: #5F87D7 +} + +div.highlight .-Color[class*=-C69] { + color: #5F87FF +} + +div.highlight .-Color[class*=-BGC69] { + background-color: #5F87FF +} + +div.highlight .-Color[class*=-C70] { + color: #5FAF00 +} + +div.highlight .-Color[class*=-BGC70] { + background-color: #5FAF00 +} + +div.highlight .-Color[class*=-C71] { + color: #5FAF5F +} + +div.highlight .-Color[class*=-BGC71] { + background-color: #5FAF5F +} + +div.highlight .-Color[class*=-C72] { + color: #5FAF87 +} + +div.highlight .-Color[class*=-BGC72] { + background-color: #5FAF87 +} + +div.highlight .-Color[class*=-C73] { + color: #5FAFAF +} + +div.highlight .-Color[class*=-BGC73] { + background-color: #5FAFAF +} + +div.highlight .-Color[class*=-C74] { + color: #5FAFD7 +} + +div.highlight .-Color[class*=-BGC74] { + background-color: #5FAFD7 +} + +div.highlight .-Color[class*=-C75] { + color: #5FAFFF +} + +div.highlight .-Color[class*=-BGC75] { + background-color: #5FAFFF +} + +div.highlight .-Color[class*=-C76] { + color: #5FD700 +} + +div.highlight .-Color[class*=-BGC76] { + background-color: #5FD700 +} + +div.highlight .-Color[class*=-C77] { + color: #5FD75F +} + +div.highlight .-Color[class*=-BGC77] { + background-color: #5FD75F +} + +div.highlight .-Color[class*=-C78] { + color: #5FD787 +} + +div.highlight .-Color[class*=-BGC78] { + background-color: #5FD787 +} + +div.highlight .-Color[class*=-C79] { + color: #5FD7AF +} + +div.highlight .-Color[class*=-BGC79] { + background-color: #5FD7AF +} + +div.highlight .-Color[class*=-C80] { + color: #5FD7D7 +} + +div.highlight .-Color[class*=-BGC80] { + background-color: #5FD7D7 +} + +div.highlight .-Color[class*=-C81] { + color: #5FD7FF +} + +div.highlight .-Color[class*=-BGC81] { + background-color: #5FD7FF +} + +div.highlight .-Color[class*=-C82] { + color: #5FFF00 +} + +div.highlight .-Color[class*=-BGC82] { + background-color: #5FFF00 +} + +div.highlight .-Color[class*=-C83] { + color: #5FFF5F +} + +div.highlight .-Color[class*=-BGC83] { + background-color: #5FFF5F +} + +div.highlight .-Color[class*=-C84] { + color: #5FFF87 +} + +div.highlight .-Color[class*=-BGC84] { + background-color: #5FFF87 +} + +div.highlight .-Color[class*=-C85] { + color: #5FFFAF +} + +div.highlight .-Color[class*=-BGC85] { + background-color: #5FFFAF +} + +div.highlight .-Color[class*=-C86] { + color: #5FFFD7 +} + +div.highlight .-Color[class*=-BGC86] { + background-color: #5FFFD7 +} + +div.highlight .-Color[class*=-C87] { + color: #5FFFFF +} + +div.highlight .-Color[class*=-BGC87] { + background-color: #5FFFFF +} + +div.highlight .-Color[class*=-C88] { + color: #870000 +} + +div.highlight .-Color[class*=-BGC88] { + background-color: #870000 +} + +div.highlight .-Color[class*=-C89] { + color: #87005F +} + +div.highlight .-Color[class*=-BGC89] { + background-color: #87005F +} + +div.highlight .-Color[class*=-C90] { + color: #870087 +} + +div.highlight .-Color[class*=-BGC90] { + background-color: #870087 +} + +div.highlight .-Color[class*=-C91] { + color: #8700AF +} + +div.highlight .-Color[class*=-BGC91] { + background-color: #8700AF +} + +div.highlight .-Color[class*=-C92] { + color: #8700D7 +} + +div.highlight .-Color[class*=-BGC92] { + background-color: #8700D7 +} + +div.highlight .-Color[class*=-C93] { + color: #8700FF +} + +div.highlight .-Color[class*=-BGC93] { + background-color: #8700FF +} + +div.highlight .-Color[class*=-C94] { + color: #875F00 +} + +div.highlight .-Color[class*=-BGC94] { + background-color: #875F00 +} + +div.highlight .-Color[class*=-C95] { + color: #875F5F +} + +div.highlight .-Color[class*=-BGC95] { + background-color: #875F5F +} + +div.highlight .-Color[class*=-C96] { + color: #875F87 +} + +div.highlight .-Color[class*=-BGC96] { + background-color: #875F87 +} + +div.highlight .-Color[class*=-C97] { + color: #875FAF +} + +div.highlight .-Color[class*=-BGC97] { + background-color: #875FAF +} + +div.highlight .-Color[class*=-C98] { + color: #875FD7 +} + +div.highlight .-Color[class*=-BGC98] { + background-color: #875FD7 +} + +div.highlight .-Color[class*=-C99] { + color: #875FFF +} + +div.highlight .-Color[class*=-BGC99] { + background-color: #875FFF +} + +div.highlight .-Color[class*=-C100] { + color: #878700 +} + +div.highlight .-Color[class*=-BGC100] { + background-color: #878700 +} + +div.highlight .-Color[class*=-C101] { + color: #87875F +} + +div.highlight .-Color[class*=-BGC101] { + background-color: #87875F +} + +div.highlight .-Color[class*=-C102] { + color: #878787 +} + +div.highlight .-Color[class*=-BGC102] { + background-color: #878787 +} + +div.highlight .-Color[class*=-C103] { + color: #8787AF +} + +div.highlight .-Color[class*=-BGC103] { + background-color: #8787AF +} + +div.highlight .-Color[class*=-C104] { + color: #8787D7 +} + +div.highlight .-Color[class*=-BGC104] { + background-color: #8787D7 +} + +div.highlight .-Color[class*=-C105] { + color: #8787FF +} + +div.highlight .-Color[class*=-BGC105] { + background-color: #8787FF +} + +div.highlight .-Color[class*=-C106] { + color: #87AF00 +} + +div.highlight .-Color[class*=-BGC106] { + background-color: #87AF00 +} + +div.highlight .-Color[class*=-C107] { + color: #87AF5F +} + +div.highlight .-Color[class*=-BGC107] { + background-color: #87AF5F +} + +div.highlight .-Color[class*=-C108] { + color: #87AF87 +} + +div.highlight .-Color[class*=-BGC108] { + background-color: #87AF87 +} + +div.highlight .-Color[class*=-C109] { + color: #87AFAF +} + +div.highlight .-Color[class*=-BGC109] { + background-color: #87AFAF +} + +div.highlight .-Color[class*=-C110] { + color: #87AFD7 +} + +div.highlight .-Color[class*=-BGC110] { + background-color: #87AFD7 +} + +div.highlight .-Color[class*=-C111] { + color: #87AFFF +} + +div.highlight .-Color[class*=-BGC111] { + background-color: #87AFFF +} + +div.highlight .-Color[class*=-C112] { + color: #87D700 +} + +div.highlight .-Color[class*=-BGC112] { + background-color: #87D700 +} + +div.highlight .-Color[class*=-C113] { + color: #87D75F +} + +div.highlight .-Color[class*=-BGC113] { + background-color: #87D75F +} + +div.highlight .-Color[class*=-C114] { + color: #87D787 +} + +div.highlight .-Color[class*=-BGC114] { + background-color: #87D787 +} + +div.highlight .-Color[class*=-C115] { + color: #87D7AF +} + +div.highlight .-Color[class*=-BGC115] { + background-color: #87D7AF +} + +div.highlight .-Color[class*=-C116] { + color: #87D7D7 +} + +div.highlight .-Color[class*=-BGC116] { + background-color: #87D7D7 +} + +div.highlight .-Color[class*=-C117] { + color: #87D7FF +} + +div.highlight .-Color[class*=-BGC117] { + background-color: #87D7FF +} + +div.highlight .-Color[class*=-C118] { + color: #87FF00 +} + +div.highlight .-Color[class*=-BGC118] { + background-color: #87FF00 +} + +div.highlight .-Color[class*=-C119] { + color: #87FF5F +} + +div.highlight .-Color[class*=-BGC119] { + background-color: #87FF5F +} + +div.highlight .-Color[class*=-C120] { + color: #87FF87 +} + +div.highlight .-Color[class*=-BGC120] { + background-color: #87FF87 +} + +div.highlight .-Color[class*=-C121] { + color: #87FFAF +} + +div.highlight .-Color[class*=-BGC121] { + background-color: #87FFAF +} + +div.highlight .-Color[class*=-C122] { + color: #87FFD7 +} + +div.highlight .-Color[class*=-BGC122] { + background-color: #87FFD7 +} + +div.highlight .-Color[class*=-C123] { + color: #87FFFF +} + +div.highlight .-Color[class*=-BGC123] { + background-color: #87FFFF +} + +div.highlight .-Color[class*=-C124] { + color: #AF0000 +} + +div.highlight .-Color[class*=-BGC124] { + background-color: #AF0000 +} + +div.highlight .-Color[class*=-C125] { + color: #AF005F +} + +div.highlight .-Color[class*=-BGC125] { + background-color: #AF005F +} + +div.highlight .-Color[class*=-C126] { + color: #AF0087 +} + +div.highlight .-Color[class*=-BGC126] { + background-color: #AF0087 +} + +div.highlight .-Color[class*=-C127] { + color: #AF00AF +} + +div.highlight .-Color[class*=-BGC127] { + background-color: #AF00AF +} + +div.highlight .-Color[class*=-C128] { + color: #AF00D7 +} + +div.highlight .-Color[class*=-BGC128] { + background-color: #AF00D7 +} + +div.highlight .-Color[class*=-C129] { + color: #AF00FF +} + +div.highlight .-Color[class*=-BGC129] { + background-color: #AF00FF +} + +div.highlight .-Color[class*=-C130] { + color: #AF5F00 +} + +div.highlight .-Color[class*=-BGC130] { + background-color: #AF5F00 +} + +div.highlight .-Color[class*=-C131] { + color: #AF5F5F +} + +div.highlight .-Color[class*=-BGC131] { + background-color: #AF5F5F +} + +div.highlight .-Color[class*=-C132] { + color: #AF5F87 +} + +div.highlight .-Color[class*=-BGC132] { + background-color: #AF5F87 +} + +div.highlight .-Color[class*=-C133] { + color: #AF5FAF +} + +div.highlight .-Color[class*=-BGC133] { + background-color: #AF5FAF +} + +div.highlight .-Color[class*=-C134] { + color: #AF5FD7 +} + +div.highlight .-Color[class*=-BGC134] { + background-color: #AF5FD7 +} + +div.highlight .-Color[class*=-C135] { + color: #AF5FFF +} + +div.highlight .-Color[class*=-BGC135] { + background-color: #AF5FFF +} + +div.highlight .-Color[class*=-C136] { + color: #AF8700 +} + +div.highlight .-Color[class*=-BGC136] { + background-color: #AF8700 +} + +div.highlight .-Color[class*=-C137] { + color: #AF875F +} + +div.highlight .-Color[class*=-BGC137] { + background-color: #AF875F +} + +div.highlight .-Color[class*=-C138] { + color: #AF8787 +} + +div.highlight .-Color[class*=-BGC138] { + background-color: #AF8787 +} + +div.highlight .-Color[class*=-C139] { + color: #AF87AF +} + +div.highlight .-Color[class*=-BGC139] { + background-color: #AF87AF +} + +div.highlight .-Color[class*=-C140] { + color: #AF87D7 +} + +div.highlight .-Color[class*=-BGC140] { + background-color: #AF87D7 +} + +div.highlight .-Color[class*=-C141] { + color: #AF87FF +} + +div.highlight .-Color[class*=-BGC141] { + background-color: #AF87FF +} + +div.highlight .-Color[class*=-C142] { + color: #AFAF00 +} + +div.highlight .-Color[class*=-BGC142] { + background-color: #AFAF00 +} + +div.highlight .-Color[class*=-C143] { + color: #AFAF5F +} + +div.highlight .-Color[class*=-BGC143] { + background-color: #AFAF5F +} + +div.highlight .-Color[class*=-C144] { + color: #AFAF87 +} + +div.highlight .-Color[class*=-BGC144] { + background-color: #AFAF87 +} + +div.highlight .-Color[class*=-C145] { + color: #AFAFAF +} + +div.highlight .-Color[class*=-BGC145] { + background-color: #AFAFAF +} + +div.highlight .-Color[class*=-C146] { + color: #AFAFD7 +} + +div.highlight .-Color[class*=-BGC146] { + background-color: #AFAFD7 +} + +div.highlight .-Color[class*=-C147] { + color: #AFAFFF +} + +div.highlight .-Color[class*=-BGC147] { + background-color: #AFAFFF +} + +div.highlight .-Color[class*=-C148] { + color: #AFD700 +} + +div.highlight .-Color[class*=-BGC148] { + background-color: #AFD700 +} + +div.highlight .-Color[class*=-C149] { + color: #AFD75F +} + +div.highlight .-Color[class*=-BGC149] { + background-color: #AFD75F +} + +div.highlight .-Color[class*=-C150] { + color: #AFD787 +} + +div.highlight .-Color[class*=-BGC150] { + background-color: #AFD787 +} + +div.highlight .-Color[class*=-C151] { + color: #AFD7AF +} + +div.highlight .-Color[class*=-BGC151] { + background-color: #AFD7AF +} + +div.highlight .-Color[class*=-C152] { + color: #AFD7D7 +} + +div.highlight .-Color[class*=-BGC152] { + background-color: #AFD7D7 +} + +div.highlight .-Color[class*=-C153] { + color: #AFD7FF +} + +div.highlight .-Color[class*=-BGC153] { + background-color: #AFD7FF +} + +div.highlight .-Color[class*=-C154] { + color: #AFFF00 +} + +div.highlight .-Color[class*=-BGC154] { + background-color: #AFFF00 +} + +div.highlight .-Color[class*=-C155] { + color: #AFFF5F +} + +div.highlight .-Color[class*=-BGC155] { + background-color: #AFFF5F +} + +div.highlight .-Color[class*=-C156] { + color: #AFFF87 +} + +div.highlight .-Color[class*=-BGC156] { + background-color: #AFFF87 +} + +div.highlight .-Color[class*=-C157] { + color: #AFFFAF +} + +div.highlight .-Color[class*=-BGC157] { + background-color: #AFFFAF +} + +div.highlight .-Color[class*=-C158] { + color: #AFFFD7 +} + +div.highlight .-Color[class*=-BGC158] { + background-color: #AFFFD7 +} + +div.highlight .-Color[class*=-C159] { + color: #AFFFFF +} + +div.highlight .-Color[class*=-BGC159] { + background-color: #AFFFFF +} + +div.highlight .-Color[class*=-C160] { + color: #D70000 +} + +div.highlight .-Color[class*=-BGC160] { + background-color: #D70000 +} + +div.highlight .-Color[class*=-C161] { + color: #D7005F +} + +div.highlight .-Color[class*=-BGC161] { + background-color: #D7005F +} + +div.highlight .-Color[class*=-C162] { + color: #D70087 +} + +div.highlight .-Color[class*=-BGC162] { + background-color: #D70087 +} + +div.highlight .-Color[class*=-C163] { + color: #D700AF +} + +div.highlight .-Color[class*=-BGC163] { + background-color: #D700AF +} + +div.highlight .-Color[class*=-C164] { + color: #D700D7 +} + +div.highlight .-Color[class*=-BGC164] { + background-color: #D700D7 +} + +div.highlight .-Color[class*=-C165] { + color: #D700FF +} + +div.highlight .-Color[class*=-BGC165] { + background-color: #D700FF +} + +div.highlight .-Color[class*=-C166] { + color: #D75F00 +} + +div.highlight .-Color[class*=-BGC166] { + background-color: #D75F00 +} + +div.highlight .-Color[class*=-C167] { + color: #D75F5F +} + +div.highlight .-Color[class*=-BGC167] { + background-color: #D75F5F +} + +div.highlight .-Color[class*=-C168] { + color: #D75F87 +} + +div.highlight .-Color[class*=-BGC168] { + background-color: #D75F87 +} + +div.highlight .-Color[class*=-C169] { + color: #D75FAF +} + +div.highlight .-Color[class*=-BGC169] { + background-color: #D75FAF +} + +div.highlight .-Color[class*=-C170] { + color: #D75FD7 +} + +div.highlight .-Color[class*=-BGC170] { + background-color: #D75FD7 +} + +div.highlight .-Color[class*=-C171] { + color: #D75FFF +} + +div.highlight .-Color[class*=-BGC171] { + background-color: #D75FFF +} + +div.highlight .-Color[class*=-C172] { + color: #D78700 +} + +div.highlight .-Color[class*=-BGC172] { + background-color: #D78700 +} + +div.highlight .-Color[class*=-C173] { + color: #D7875F +} + +div.highlight .-Color[class*=-BGC173] { + background-color: #D7875F +} + +div.highlight .-Color[class*=-C174] { + color: #D78787 +} + +div.highlight .-Color[class*=-BGC174] { + background-color: #D78787 +} + +div.highlight .-Color[class*=-C175] { + color: #D787AF +} + +div.highlight .-Color[class*=-BGC175] { + background-color: #D787AF +} + +div.highlight .-Color[class*=-C176] { + color: #D787D7 +} + +div.highlight .-Color[class*=-BGC176] { + background-color: #D787D7 +} + +div.highlight .-Color[class*=-C177] { + color: #D787FF +} + +div.highlight .-Color[class*=-BGC177] { + background-color: #D787FF +} + +div.highlight .-Color[class*=-C178] { + color: #D7AF00 +} + +div.highlight .-Color[class*=-BGC178] { + background-color: #D7AF00 +} + +div.highlight .-Color[class*=-C179] { + color: #D7AF5F +} + +div.highlight .-Color[class*=-BGC179] { + background-color: #D7AF5F +} + +div.highlight .-Color[class*=-C180] { + color: #D7AF87 +} + +div.highlight .-Color[class*=-BGC180] { + background-color: #D7AF87 +} + +div.highlight .-Color[class*=-C181] { + color: #D7AFAF +} + +div.highlight .-Color[class*=-BGC181] { + background-color: #D7AFAF +} + +div.highlight .-Color[class*=-C182] { + color: #D7AFD7 +} + +div.highlight .-Color[class*=-BGC182] { + background-color: #D7AFD7 +} + +div.highlight .-Color[class*=-C183] { + color: #D7AFFF +} + +div.highlight .-Color[class*=-BGC183] { + background-color: #D7AFFF +} + +div.highlight .-Color[class*=-C184] { + color: #D7D700 +} + +div.highlight .-Color[class*=-BGC184] { + background-color: #D7D700 +} + +div.highlight .-Color[class*=-C185] { + color: #D7D75F +} + +div.highlight .-Color[class*=-BGC185] { + background-color: #D7D75F +} + +div.highlight .-Color[class*=-C186] { + color: #D7D787 +} + +div.highlight .-Color[class*=-BGC186] { + background-color: #D7D787 +} + +div.highlight .-Color[class*=-C187] { + color: #D7D7AF +} + +div.highlight .-Color[class*=-BGC187] { + background-color: #D7D7AF +} + +div.highlight .-Color[class*=-C188] { + color: #D7D7D7 +} + +div.highlight .-Color[class*=-BGC188] { + background-color: #D7D7D7 +} + +div.highlight .-Color[class*=-C189] { + color: #D7D7FF +} + +div.highlight .-Color[class*=-BGC189] { + background-color: #D7D7FF +} + +div.highlight .-Color[class*=-C190] { + color: #D7FF00 +} + +div.highlight .-Color[class*=-BGC190] { + background-color: #D7FF00 +} + +div.highlight .-Color[class*=-C191] { + color: #D7FF5F +} + +div.highlight .-Color[class*=-BGC191] { + background-color: #D7FF5F +} + +div.highlight .-Color[class*=-C192] { + color: #D7FF87 +} + +div.highlight .-Color[class*=-BGC192] { + background-color: #D7FF87 +} + +div.highlight .-Color[class*=-C193] { + color: #D7FFAF +} + +div.highlight .-Color[class*=-BGC193] { + background-color: #D7FFAF +} + +div.highlight .-Color[class*=-C194] { + color: #D7FFD7 +} + +div.highlight .-Color[class*=-BGC194] { + background-color: #D7FFD7 +} + +div.highlight .-Color[class*=-C195] { + color: #D7FFFF +} + +div.highlight .-Color[class*=-BGC195] { + background-color: #D7FFFF +} + +div.highlight .-Color[class*=-C196] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC196] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C197] { + color: #FF005F +} + +div.highlight .-Color[class*=-BGC197] { + background-color: #FF005F +} + +div.highlight .-Color[class*=-C198] { + color: #FF0087 +} + +div.highlight .-Color[class*=-BGC198] { + background-color: #FF0087 +} + +div.highlight .-Color[class*=-C199] { + color: #FF00AF +} + +div.highlight .-Color[class*=-BGC199] { + background-color: #FF00AF +} + +div.highlight .-Color[class*=-C200] { + color: #FF00D7 +} + +div.highlight .-Color[class*=-BGC200] { + background-color: #FF00D7 +} + +div.highlight .-Color[class*=-C201] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC201] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C202] { + color: #FF5F00 +} + +div.highlight .-Color[class*=-BGC202] { + background-color: #FF5F00 +} + +div.highlight .-Color[class*=-C203] { + color: #FF5F5F +} + +div.highlight .-Color[class*=-BGC203] { + background-color: #FF5F5F +} + +div.highlight .-Color[class*=-C204] { + color: #FF5F87 +} + +div.highlight .-Color[class*=-BGC204] { + background-color: #FF5F87 +} + +div.highlight .-Color[class*=-C205] { + color: #FF5FAF +} + +div.highlight .-Color[class*=-BGC205] { + background-color: #FF5FAF +} + +div.highlight .-Color[class*=-C206] { + color: #FF5FD7 +} + +div.highlight .-Color[class*=-BGC206] { + background-color: #FF5FD7 +} + +div.highlight .-Color[class*=-C207] { + color: #FF5FFF +} + +div.highlight .-Color[class*=-BGC207] { + background-color: #FF5FFF +} + +div.highlight .-Color[class*=-C208] { + color: #FF8700 +} + +div.highlight .-Color[class*=-BGC208] { + background-color: #FF8700 +} + +div.highlight .-Color[class*=-C209] { + color: #FF875F +} + +div.highlight .-Color[class*=-BGC209] { + background-color: #FF875F +} + +div.highlight .-Color[class*=-C210] { + color: #FF8787 +} + +div.highlight .-Color[class*=-BGC210] { + background-color: #FF8787 +} + +div.highlight .-Color[class*=-C211] { + color: #FF87AF +} + +div.highlight .-Color[class*=-BGC211] { + background-color: #FF87AF +} + +div.highlight .-Color[class*=-C212] { + color: #FF87D7 +} + +div.highlight .-Color[class*=-BGC212] { + background-color: #FF87D7 +} + +div.highlight .-Color[class*=-C213] { + color: #FF87FF +} + +div.highlight .-Color[class*=-BGC213] { + background-color: #FF87FF +} + +div.highlight .-Color[class*=-C214] { + color: #FFAF00 +} + +div.highlight .-Color[class*=-BGC214] { + background-color: #FFAF00 +} + +div.highlight .-Color[class*=-C215] { + color: #FFAF5F +} + +div.highlight .-Color[class*=-BGC215] { + background-color: #FFAF5F +} + +div.highlight .-Color[class*=-C216] { + color: #FFAF87 +} + +div.highlight .-Color[class*=-BGC216] { + background-color: #FFAF87 +} + +div.highlight .-Color[class*=-C217] { + color: #FFAFAF +} + +div.highlight .-Color[class*=-BGC217] { + background-color: #FFAFAF +} + +div.highlight .-Color[class*=-C218] { + color: #FFAFD7 +} + +div.highlight .-Color[class*=-BGC218] { + background-color: #FFAFD7 +} + +div.highlight .-Color[class*=-C219] { + color: #FFAFFF +} + +div.highlight .-Color[class*=-BGC219] { + background-color: #FFAFFF +} + +div.highlight .-Color[class*=-C220] { + color: #FFD700 +} + +div.highlight .-Color[class*=-BGC220] { + background-color: #FFD700 +} + +div.highlight .-Color[class*=-C221] { + color: #FFD75F +} + +div.highlight .-Color[class*=-BGC221] { + background-color: #FFD75F +} + +div.highlight .-Color[class*=-C222] { + color: #FFD787 +} + +div.highlight .-Color[class*=-BGC222] { + background-color: #FFD787 +} + +div.highlight .-Color[class*=-C223] { + color: #FFD7AF +} + +div.highlight .-Color[class*=-BGC223] { + background-color: #FFD7AF +} + +div.highlight .-Color[class*=-C224] { + color: #FFD7D7 +} + +div.highlight .-Color[class*=-BGC224] { + background-color: #FFD7D7 +} + +div.highlight .-Color[class*=-C225] { + color: #FFD7FF +} + +div.highlight .-Color[class*=-BGC225] { + background-color: #FFD7FF +} + +div.highlight .-Color[class*=-C226] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC226] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C227] { + color: #FFFF5F +} + +div.highlight .-Color[class*=-BGC227] { + background-color: #FFFF5F +} + +div.highlight .-Color[class*=-C228] { + color: #FFFF87 +} + +div.highlight .-Color[class*=-BGC228] { + background-color: #FFFF87 +} + +div.highlight .-Color[class*=-C229] { + color: #FFFFAF +} + +div.highlight .-Color[class*=-BGC229] { + background-color: #FFFFAF +} + +div.highlight .-Color[class*=-C230] { + color: #FFFFD7 +} + +div.highlight .-Color[class*=-BGC230] { + background-color: #FFFFD7 +} + +div.highlight .-Color[class*=-C231] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC231] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C232] { + color: #080808 +} + +div.highlight .-Color[class*=-BGC232] { + background-color: #080808 +} + +div.highlight .-Color[class*=-C233] { + color: #121212 +} + +div.highlight .-Color[class*=-BGC233] { + background-color: #121212 +} + +div.highlight .-Color[class*=-C234] { + color: #1C1C1C +} + +div.highlight .-Color[class*=-BGC234] { + background-color: #1C1C1C +} + +div.highlight .-Color[class*=-C235] { + color: #262626 +} + +div.highlight .-Color[class*=-BGC235] { + background-color: #262626 +} + +div.highlight .-Color[class*=-C236] { + color: #303030 +} + +div.highlight .-Color[class*=-BGC236] { + background-color: #303030 +} + +div.highlight .-Color[class*=-C237] { + color: #3A3A3A +} + +div.highlight .-Color[class*=-BGC237] { + background-color: #3A3A3A +} + +div.highlight .-Color[class*=-C238] { + color: #444444 +} + +div.highlight .-Color[class*=-BGC238] { + background-color: #444444 +} + +div.highlight .-Color[class*=-C239] { + color: #4E4E4E +} + +div.highlight .-Color[class*=-BGC239] { + background-color: #4E4E4E +} + +div.highlight .-Color[class*=-C240] { + color: #585858 +} + +div.highlight .-Color[class*=-BGC240] { + background-color: #585858 +} + +div.highlight .-Color[class*=-C241] { + color: #626262 +} + +div.highlight .-Color[class*=-BGC241] { + background-color: #626262 +} + +div.highlight .-Color[class*=-C242] { + color: #6C6C6C +} + +div.highlight .-Color[class*=-BGC242] { + background-color: #6C6C6C +} + +div.highlight .-Color[class*=-C243] { + color: #767676 +} + +div.highlight .-Color[class*=-BGC243] { + background-color: #767676 +} + +div.highlight .-Color[class*=-C244] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC244] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C245] { + color: #8A8A8A +} + +div.highlight .-Color[class*=-BGC245] { + background-color: #8A8A8A +} + +div.highlight .-Color[class*=-C246] { + color: #949494 +} + +div.highlight .-Color[class*=-BGC246] { + background-color: #949494 +} + +div.highlight .-Color[class*=-C247] { + color: #9E9E9E +} + +div.highlight .-Color[class*=-BGC247] { + background-color: #9E9E9E +} + +div.highlight .-Color[class*=-C248] { + color: #A8A8A8 +} + +div.highlight .-Color[class*=-BGC248] { + background-color: #A8A8A8 +} + +div.highlight .-Color[class*=-C249] { + color: #B2B2B2 +} + +div.highlight .-Color[class*=-BGC249] { + background-color: #B2B2B2 +} + +div.highlight .-Color[class*=-C250] { + color: #BCBCBC +} + +div.highlight .-Color[class*=-BGC250] { + background-color: #BCBCBC +} + +div.highlight .-Color[class*=-C251] { + color: #C6C6C6 +} + +div.highlight .-Color[class*=-BGC251] { + background-color: #C6C6C6 +} + +div.highlight .-Color[class*=-C252] { + color: #D0D0D0 +} + +div.highlight .-Color[class*=-BGC252] { + background-color: #D0D0D0 +} + +div.highlight .-Color[class*=-C253] { + color: #DADADA +} + +div.highlight .-Color[class*=-BGC253] { + background-color: #DADADA +} + +div.highlight .-Color[class*=-C254] { + color: #E4E4E4 +} + +div.highlight .-Color[class*=-BGC254] { + background-color: #E4E4E4 +} + +div.highlight .-Color[class*=-C255] { + color: #EEEEEE +} + +div.highlight .-Color[class*=-BGC255] { + background-color: #EEEEEE +} diff --git a/branch/ignore/_static/plus.png b/branch/ignore/_static/plus.png new file mode 100644 index 0000000..7107cec Binary files /dev/null and b/branch/ignore/_static/plus.png differ diff --git a/branch/ignore/_static/pygments.css b/branch/ignore/_static/pygments.css new file mode 100644 index 0000000..84ab303 --- /dev/null +++ b/branch/ignore/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/branch/ignore/_static/searchtools.js b/branch/ignore/_static/searchtools.js new file mode 100644 index 0000000..7918c3f --- /dev/null +++ b/branch/ignore/_static/searchtools.js @@ -0,0 +1,574 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + `Search finished, found ${resultCount} page(s) matching the search query.` + ); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent !== undefined) return docContent.textContent; + console.warn( + "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + /** + * execute search (requires search index to be loaded) + */ + query: (query) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + // array of [docname, title, anchor, descr, score, filename] + let results = []; + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + let score = Math.round(100 * queryLower.length / title.length) + results.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id] of foundEntries) { + let score = Math.round(100 * queryLower.length / entry.length) + results.push([ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // lookup as object + objectTerms.forEach((term) => + results.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item))); + + // now sort the results by score (in opposite order of appearance, since the + // display function below uses pop() to retrieve items) and then + // alphabetically + results.sort((a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; + }); + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + results = results.reverse(); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord) && !terms[word]) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord) && !titleTerms[word]) + arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); + }); + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1) + fileMap.get(file).push(word); + else fileMap.set(file, [word]); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords) => { + const text = Search.htmlToText(htmlText); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/branch/ignore/_static/sphinx_highlight.js b/branch/ignore/_static/sphinx_highlight.js new file mode 100644 index 0000000..8a96c69 --- /dev/null +++ b/branch/ignore/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/branch/ignore/_static/sphinx_lesson.css b/branch/ignore/_static/sphinx_lesson.css new file mode 100644 index 0000000..14b20c6 --- /dev/null +++ b/branch/ignore/_static/sphinx_lesson.css @@ -0,0 +1,51 @@ +/* sphinx_lesson.css */ + +body.wy-body-for-nav img.with-border { + border: 2px solid; +} + +.rst-content .admonition-no-content { + padding-bottom: 0px; +} + +.rst-content .demo > .admonition-title::before { + content: "\01F440"; /* Eyes */ } +.rst-content .type-along > .admonition-title::before { + content: "\02328\0FE0F"; /* Keyboard */ } +.rst-content .exercise > .admonition-title::before { + content: "\0270D\0FE0F"; /* Hand */ } +.rst-content .solution > .admonition-title::before { + content: "\02714\0FE0E"; /* Check mark */ } +.rst-content .homework > .admonition-title::before { + content: "\01F4DD"; /* Memo */ } +.rst-content .discussion > .admonition-title::before { + content: "\01F4AC"; /* Speech balloon */ } +.rst-content .questions > .admonition-title::before { + content: "\02753\0FE0E"; /* Question mark */ } +.rst-content .prerequisites > .admonition-title::before { + content: "\02699"; /* Gear */ } +.rst-content .seealso > .admonition-title::before { + content: "\027A1\0FE0E"; /* Question mark */ } + + +/* instructor-note */ +.rst-content .instructor-note { + background: #e7e7e7; +} +.rst-content .instructor-note > .admonition-title { + background: #6a6a6a; +} +.rst-content .instructor-note > .admonition-title::before { + content: ""; +} + + +/* sphinx_toggle_button, make the font white */ +.rst-content .toggle.admonition button.toggle-button { + color: white; +} + +/* sphinx-togglebutton, remove underflow when toggled to hidden mode */ +.rst-content .admonition.toggle-hidden { + padding-bottom: 0px; +} diff --git a/branch/ignore/_static/sphinx_rtd_theme_ext_color_contrast.css b/branch/ignore/_static/sphinx_rtd_theme_ext_color_contrast.css new file mode 100644 index 0000000..e68feb8 --- /dev/null +++ b/branch/ignore/_static/sphinx_rtd_theme_ext_color_contrast.css @@ -0,0 +1,47 @@ +/* The following are for web accessibility of sphinx_rtd_theme: they + * solve some of the most frequent contrast issues. Remove when this + * solved: + * https://github.com/readthedocs/sphinx_rtd_theme/issues/971 + */ +/* background: #fcfcfc, note boxes #E7F2FA */ +a { color: #2573A7; } /* original #2980B9, #1F5C84; */ +body { color: #242424; } /* original #404040, #383838 */ +.wy-side-nav-search>a, .wy-side-nav-search .wy-dropdown>a { + color: #ffffff; +} /* original #fcfcfc */ +footer { color: #737373; } /* original gray=#808080*/ +footer span.commit code, footer span.commit .rst-content tt, .rst-content footer span.commit tt { + color: #737373; +} /* original gray=#808080*/ +.rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal { + color: #AB2314; +} +/* Sidebar background */ +.wy-side-nav-search { background-color: #277CB4;} + +/* Same, but for pygments */ +.highlight .ch { color: #3E7A89; } /* #! line */ +.highlight .c1 { color: #3E7A89; } /* also comments */ +.highlight .nv { color: #AD3ECC; } /* variable */ +.highlight .gp { color: #B45608; } /* prompt character, $*/ +.highlight .si { color: #3975B1; } /* ${} variable text */ +.highlight .nc { color: #0C78A7; } + +/* Sphinx admonitions */ +/* warning */ +.wy-alert.wy-alert-warning .wy-alert-title, .rst-content .wy-alert-warning.note .wy-alert-title, .rst-content .attention .wy-alert-title, .rst-content .caution .wy-alert-title, .rst-content .wy-alert-warning.danger .wy-alert-title, .rst-content .wy-alert-warning.error .wy-alert-title, .rst-content .wy-alert-warning.hint .wy-alert-title, .rst-content .wy-alert-warning.important .wy-alert-title, .rst-content .wy-alert-warning.tip .wy-alert-title, .rst-content .warning .wy-alert-title, .rst-content .wy-alert-warning.seealso .wy-alert-title, .rst-content .admonition-todo .wy-alert-title, .rst-content .wy-alert-warning.admonition .wy-alert-title, .wy-alert.wy-alert-warning .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-warning .admonition-title, .rst-content .wy-alert-warning.note .admonition-title, .rst-content .attention .admonition-title, .rst-content .caution .admonition-title, .rst-content .wy-alert-warning.danger .admonition-title, .rst-content .wy-alert-warning.error .admonition-title, .rst-content .wy-alert-warning.hint .admonition-title, .rst-content .wy-alert-warning.important .admonition-title, .rst-content .wy-alert-warning.tip .admonition-title, .rst-content .warning .admonition-title, .rst-content .wy-alert-warning.seealso .admonition-title, .rst-content .admonition-todo .admonition-title, .rst-content .wy-alert-warning.admonition .admonition-title { + background: #B15E16; } +/* important */ +.wy-alert.wy-alert-success .wy-alert-title, .rst-content .wy-alert-success.note .wy-alert-title, .rst-content .wy-alert-success.attention .wy-alert-title, .rst-content .wy-alert-success.caution .wy-alert-title, .rst-content .wy-alert-success.danger .wy-alert-title, .rst-content .wy-alert-success.error .wy-alert-title, .rst-content .hint .wy-alert-title, .rst-content .important .wy-alert-title, .rst-content .tip .wy-alert-title, .rst-content .wy-alert-success.warning .wy-alert-title, .rst-content .wy-alert-success.seealso .wy-alert-title, .rst-content .wy-alert-success.admonition-todo .wy-alert-title, .rst-content .wy-alert-success.admonition .wy-alert-title, .wy-alert.wy-alert-success .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-success .admonition-title, .rst-content .wy-alert-success.note .admonition-title, .rst-content .wy-alert-success.attention .admonition-title, .rst-content .wy-alert-success.caution .admonition-title, .rst-content .wy-alert-success.danger .admonition-title, .rst-content .wy-alert-success.error .admonition-title, .rst-content .hint .admonition-title, .rst-content .important .admonition-title, .rst-content .tip .admonition-title, .rst-content .wy-alert-success.warning .admonition-title, .rst-content .wy-alert-success.seealso .admonition-title, .rst-content .wy-alert-success.admonition-todo .admonition-title, .rst-content .wy-alert-success.admonition .admonition-title { + background: #12826C; } +/* seealso, note, etc */ +.wy-alert.wy-alert-info .wy-alert-title, .rst-content .note .wy-alert-title, .rst-content .wy-alert-info.attention .wy-alert-title, .rst-content .wy-alert-info.caution .wy-alert-title, .rst-content .wy-alert-info.danger .wy-alert-title, .rst-content .wy-alert-info.error .wy-alert-title, .rst-content .wy-alert-info.hint .wy-alert-title, .rst-content .wy-alert-info.important .wy-alert-title, .rst-content .wy-alert-info.tip .wy-alert-title, .rst-content .wy-alert-info.warning .wy-alert-title, .rst-content .seealso .wy-alert-title, .rst-content .wy-alert-info.admonition-todo .wy-alert-title, .rst-content .wy-alert-info.admonition .wy-alert-title, .wy-alert.wy-alert-info .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-info .admonition-title, .rst-content .note .admonition-title, .rst-content .wy-alert-info.attention .admonition-title, .rst-content .wy-alert-info.caution .admonition-title, .rst-content .wy-alert-info.danger .admonition-title, .rst-content .wy-alert-info.error .admonition-title, .rst-content .wy-alert-info.hint .admonition-title, .rst-content .wy-alert-info.important .admonition-title, .rst-content .wy-alert-info.tip .admonition-title, .rst-content .wy-alert-info.warning .admonition-title, .rst-content .seealso .admonition-title, .rst-content .wy-alert-info.admonition-todo .admonition-title, .rst-content .wy-alert-info.admonition .admonition-title { + background: #277CB4; } +/* error, danger */ +.rst-content .danger .admonition-title, .rst-content .danger .wy-alert-title, .rst-content .error .admonition-title, .rst-content .error .wy-alert-title, .rst-content .wy-alert-danger.admonition-todo .admonition-title, .rst-content .wy-alert-danger.admonition-todo .wy-alert-title, .rst-content .wy-alert-danger.admonition .admonition-title, .rst-content .wy-alert-danger.admonition .wy-alert-title, .rst-content .wy-alert-danger.attention .admonition-title, .rst-content .wy-alert-danger.attention .wy-alert-title, .rst-content .wy-alert-danger.caution .admonition-title, .rst-content .wy-alert-danger.caution .wy-alert-title, .rst-content .wy-alert-danger.hint .admonition-title, .rst-content .wy-alert-danger.hint .wy-alert-title, .rst-content .wy-alert-danger.important .admonition-title, .rst-content .wy-alert-danger.important .wy-alert-title, .rst-content .wy-alert-danger.note .admonition-title, .rst-content .wy-alert-danger.note .wy-alert-title, .rst-content .wy-alert-danger.seealso .admonition-title, .rst-content .wy-alert-danger.seealso .wy-alert-title, .rst-content .wy-alert-danger.tip .admonition-title, .rst-content .wy-alert-danger.tip .wy-alert-title, .rst-content .wy-alert-danger.warning .admonition-title, .rst-content .wy-alert-danger.warning .wy-alert-title, .rst-content .wy-alert.wy-alert-danger .admonition-title, .wy-alert.wy-alert-danger .rst-content .admonition-title, .wy-alert.wy-alert-danger .wy-alert-title { + background: #e31704; +} + +/* Generic admonition titles */ +.wy-alert-title, .rst-content .admonition-title { + background: #277CB4; } diff --git a/branch/ignore/_static/tabs.css b/branch/ignore/_static/tabs.css new file mode 100644 index 0000000..957ba60 --- /dev/null +++ b/branch/ignore/_static/tabs.css @@ -0,0 +1,89 @@ +.sphinx-tabs { + margin-bottom: 1rem; +} + +[role="tablist"] { + border-bottom: 1px solid #a0b3bf; +} + +.sphinx-tabs-tab { + position: relative; + font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; + color: #1D5C87; + line-height: 24px; + margin: 0; + font-size: 16px; + font-weight: 400; + background-color: rgba(255, 255, 255, 0); + border-radius: 5px 5px 0 0; + border: 0; + padding: 1rem 1.5rem; + margin-bottom: 0; +} + +.sphinx-tabs-tab[aria-selected="true"] { + font-weight: 700; + border: 1px solid #a0b3bf; + border-bottom: 1px solid white; + margin: -1px; + background-color: white; +} + +.sphinx-tabs-tab:focus { + z-index: 1; + outline-offset: 1px; +} + +.sphinx-tabs-panel { + position: relative; + padding: 1rem; + border: 1px solid #a0b3bf; + margin: 0px -1px -1px -1px; + border-radius: 0 0 5px 5px; + border-top: 0; + background: white; +} + +.sphinx-tabs-panel.code-tab { + padding: 0.4rem; +} + +.sphinx-tab img { + margin-bottom: 24 px; +} + +/* Dark theme preference styling */ + +@media (prefers-color-scheme: dark) { + body[data-theme="auto"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); + } + + body[data-theme="auto"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); + } + + body[data-theme="auto"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 1px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); + } +} + +/* Explicit dark theme styling */ + +body[data-theme="dark"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); +} + +body[data-theme="dark"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); +} + +body[data-theme="dark"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 2px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); +} diff --git a/branch/ignore/_static/tabs.js b/branch/ignore/_static/tabs.js new file mode 100644 index 0000000..48dc303 --- /dev/null +++ b/branch/ignore/_static/tabs.js @@ -0,0 +1,145 @@ +try { + var session = window.sessionStorage || {}; +} catch (e) { + var session = {}; +} + +window.addEventListener("DOMContentLoaded", () => { + const allTabs = document.querySelectorAll('.sphinx-tabs-tab'); + const tabLists = document.querySelectorAll('[role="tablist"]'); + + allTabs.forEach(tab => { + tab.addEventListener("click", changeTabs); + }); + + tabLists.forEach(tabList => { + tabList.addEventListener("keydown", keyTabs); + }); + + // Restore group tab selection from session + const lastSelected = session.getItem('sphinx-tabs-last-selected'); + if (lastSelected != null) selectNamedTabs(lastSelected); +}); + +/** + * Key focus left and right between sibling elements using arrows + * @param {Node} e the element in focus when key was pressed + */ +function keyTabs(e) { + const tab = e.target; + let nextTab = null; + if (e.keyCode === 39 || e.keyCode === 37) { + tab.setAttribute("tabindex", -1); + // Move right + if (e.keyCode === 39) { + nextTab = tab.nextElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.firstElementChild; + } + // Move left + } else if (e.keyCode === 37) { + nextTab = tab.previousElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.lastElementChild; + } + } + } + + if (nextTab !== null) { + nextTab.setAttribute("tabindex", 0); + nextTab.focus(); + } +} + +/** + * Select or deselect clicked tab. If a group tab + * is selected, also select tab in other tabLists. + * @param {Node} e the element that was clicked + */ +function changeTabs(e) { + // Use this instead of the element that was clicked, in case it's a child + const notSelected = this.getAttribute("aria-selected") === "false"; + const positionBefore = this.parentNode.getBoundingClientRect().top; + const notClosable = !this.parentNode.classList.contains("closeable"); + + deselectTabList(this); + + if (notSelected || notClosable) { + selectTab(this); + const name = this.getAttribute("name"); + selectNamedTabs(name, this.id); + + if (this.classList.contains("group-tab")) { + // Persist during session + session.setItem('sphinx-tabs-last-selected', name); + } + } + + const positionAfter = this.parentNode.getBoundingClientRect().top; + const positionDelta = positionAfter - positionBefore; + // Scroll to offset content resizing + window.scrollTo(0, window.scrollY + positionDelta); +} + +/** + * Select tab and show associated panel. + * @param {Node} tab tab to select + */ +function selectTab(tab) { + tab.setAttribute("aria-selected", true); + + // Show the associated panel + document + .getElementById(tab.getAttribute("aria-controls")) + .removeAttribute("hidden"); +} + +/** + * Hide the panels associated with all tabs within the + * tablist containing this tab. + * @param {Node} tab a tab within the tablist to deselect + */ +function deselectTabList(tab) { + const parent = tab.parentNode; + const grandparent = parent.parentNode; + + Array.from(parent.children) + .forEach(t => t.setAttribute("aria-selected", false)); + + Array.from(grandparent.children) + .slice(1) // Skip tablist + .forEach(panel => panel.setAttribute("hidden", true)); +} + +/** + * Select grouped tabs with the same name, but no the tab + * with the given id. + * @param {Node} name name of grouped tab to be selected + * @param {Node} clickedId id of clicked tab + */ +function selectNamedTabs(name, clickedId=null) { + const groupedTabs = document.querySelectorAll(`.sphinx-tabs-tab[name="${name}"]`); + const tabLists = Array.from(groupedTabs).map(tab => tab.parentNode); + + tabLists + .forEach(tabList => { + // Don't want to change the tabList containing the clicked tab + const clickedTab = tabList.querySelector(`[id="${clickedId}"]`); + if (clickedTab === null ) { + // Select first tab with matching name + const tab = tabList.querySelector(`.sphinx-tabs-tab[name="${name}"]`); + deselectTabList(tab); + selectTab(tab); + } + }) +} + +if (typeof exports === 'undefined') { + exports = {}; +} + +exports.keyTabs = keyTabs; +exports.changeTabs = changeTabs; +exports.selectTab = selectTab; +exports.deselectTabList = deselectTabList; +exports.selectNamedTabs = selectNamedTabs; diff --git a/branch/ignore/_static/togglebutton.css b/branch/ignore/_static/togglebutton.css new file mode 100644 index 0000000..54a6787 --- /dev/null +++ b/branch/ignore/_static/togglebutton.css @@ -0,0 +1,160 @@ +/** + * Admonition-based toggles + */ + +/* Visibility of the target */ +.admonition.toggle .admonition-title ~ * { + transition: opacity .3s, height .3s; +} + +/* Toggle buttons inside admonitions so we see the title */ +.admonition.toggle { + position: relative; +} + +/* Titles should cut off earlier to avoid overlapping w/ button */ +.admonition.toggle .admonition-title { + padding-right: 25%; + cursor: pointer; +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:hover { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 1%); +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:active { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 3%); +} + +/* Remove extra whitespace below the admonition title when hidden */ +.admonition.toggle-hidden { + padding-bottom: 0; +} + +.admonition.toggle-hidden .admonition-title { + margin-bottom: 0; +} + +/* hides all the content of a page until de-toggled */ +.admonition.toggle-hidden .admonition-title ~ * { + height: 0; + margin: 0; + opacity: 0; + visibility: hidden; +} + +/* General button style and position*/ +button.toggle-button { + /** + * Background and shape. By default there's no background + * but users can style as they wish + */ + background: none; + border: none; + outline: none; + + /* Positioning just inside the admonition title */ + position: absolute; + right: 0.5em; + padding: 0px; + border: none; + outline: none; +} + +/* Display the toggle hint on wide screens */ +@media (min-width: 768px) { + button.toggle-button.toggle-button-hidden:before { + content: attr(data-toggle-hint); /* This will be filled in by JS */ + font-size: .8em; + align-self: center; + } +} + +/* Icon behavior */ +.tb-icon { + transition: transform .2s ease-out; + height: 1.5em; + width: 1.5em; + stroke: currentColor; /* So that we inherit the color of other text */ +} + +/* The icon should point right when closed, down when open. */ +/* Open */ +.admonition.toggle button .tb-icon { + transform: rotate(90deg); +} + +/* Closed */ +.admonition.toggle button.toggle-button-hidden .tb-icon { + transform: rotate(0deg); +} + +/* With details toggles, we don't rotate the icon so it points right */ +details.toggle-details .tb-icon { + height: 1.4em; + width: 1.4em; + margin-top: 0.1em; /* To center the button vertically */ +} + + +/** + * Details-based toggles. + * In this case, we wrap elements with `.toggle` in a details block. + */ + +/* Details blocks */ +details.toggle-details { + margin: 1em 0; +} + + +details.toggle-details summary { + display: flex; + align-items: center; + cursor: pointer; + list-style: none; + border-radius: .2em; + border-left: 3px solid #1976d2; + background-color: rgb(204 204 204 / 10%); + padding: 0.2em 0.7em 0.3em 0.5em; /* Less padding on left because the SVG has left margin */ + font-size: 0.9em; +} + +details.toggle-details summary:hover { + background-color: rgb(204 204 204 / 20%); +} + +details.toggle-details summary:active { + background: rgb(204 204 204 / 28%); +} + +.toggle-details__summary-text { + margin-left: 0.2em; +} + +details.toggle-details[open] summary { + margin-bottom: .5em; +} + +details.toggle-details[open] summary .tb-icon { + transform: rotate(90deg); +} + +details.toggle-details[open] summary ~ * { + animation: toggle-fade-in .3s ease-out; +} + +@keyframes toggle-fade-in { + from {opacity: 0%;} + to {opacity: 100%;} +} + +/* Print rules - we hide all toggle button elements at print */ +@media print { + /* Always hide the summary so the button doesn't show up */ + details.toggle-details summary { + display: none; + } +} \ No newline at end of file diff --git a/branch/ignore/_static/togglebutton.js b/branch/ignore/_static/togglebutton.js new file mode 100644 index 0000000..215a7ee --- /dev/null +++ b/branch/ignore/_static/togglebutton.js @@ -0,0 +1,187 @@ +/** + * Add Toggle Buttons to elements + */ + +let toggleChevron = ` + + + +`; + +var initToggleItems = () => { + var itemsToToggle = document.querySelectorAll(togglebuttonSelector); + console.log(`[togglebutton]: Adding toggle buttons to ${itemsToToggle.length} items`) + // Add the button to each admonition and hook up a callback to toggle visibility + itemsToToggle.forEach((item, index) => { + if (item.classList.contains("admonition")) { + // If it's an admonition block, then we'll add a button inside + // Generate unique IDs for this item + var toggleID = `toggle-${index}`; + var buttonID = `button-${toggleID}`; + + item.setAttribute('id', toggleID); + if (!item.classList.contains("toggle")){ + item.classList.add("toggle"); + } + // This is the button that will be added to each item to trigger the toggle + var collapseButton = ` + `; + + title = item.querySelector(".admonition-title") + title.insertAdjacentHTML("beforeend", collapseButton); + thisButton = document.getElementById(buttonID); + + // Add click handlers for the button + admonition title (if admonition) + admonitionTitle = document.querySelector(`#${toggleID} > .admonition-title`) + if (admonitionTitle) { + // If an admonition, then make the whole title block clickable + admonitionTitle.addEventListener('click', toggleClickHandler); + admonitionTitle.dataset.target = toggleID + admonitionTitle.dataset.button = buttonID + } else { + // If not an admonition then we'll listen for the button click + thisButton.addEventListener('click', toggleClickHandler); + } + + // Now hide the item for this toggle button unless explicitly noted to show + if (!item.classList.contains("toggle-shown")) { + toggleHidden(thisButton); + } + } else { + // If not an admonition, wrap the block in a
block + // Define the structure of the details block and insert it as a sibling + var detailsBlock = ` +
+ + ${toggleChevron} + ${toggleHintShow} + +
`; + item.insertAdjacentHTML("beforebegin", detailsBlock); + + // Now move the toggle-able content inside of the details block + details = item.previousElementSibling + details.appendChild(item) + item.classList.add("toggle-details__container") + + // Set up a click trigger to change the text as needed + details.addEventListener('click', (click) => { + let parent = click.target.parentElement; + if (parent.tagName.toLowerCase() == "details") { + summary = parent.querySelector("summary"); + details = parent; + } else { + summary = parent; + details = parent.parentElement; + } + // Update the inner text for the proper hint + if (details.open) { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintShow; + } else { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintHide; + } + + }); + + // If we have a toggle-shown class, open details block should be open + if (item.classList.contains("toggle-shown")) { + details.click(); + } + } + }) +}; + +// This should simply add / remove the collapsed class and change the button text +var toggleHidden = (button) => { + target = button.dataset['target'] + var itemToToggle = document.getElementById(target); + if (itemToToggle.classList.contains("toggle-hidden")) { + itemToToggle.classList.remove("toggle-hidden"); + button.classList.remove("toggle-button-hidden"); + } else { + itemToToggle.classList.add("toggle-hidden"); + button.classList.add("toggle-button-hidden"); + } +} + +var toggleClickHandler = (click) => { + // Be cause the admonition title is clickable and extends to the whole admonition + // We only look for a click event on this title to trigger the toggle. + + if (click.target.classList.contains("admonition-title")) { + button = click.target.querySelector(".toggle-button"); + } else if (click.target.classList.contains("tb-icon")) { + // We've clicked the icon and need to search up one parent for the button + button = click.target.parentElement; + } else if (click.target.tagName == "polyline") { + // We've clicked the SVG elements inside the button, need to up 2 layers + button = click.target.parentElement.parentElement; + } else if (click.target.classList.contains("toggle-button")) { + // We've clicked the button itself and so don't need to do anything + button = click.target; + } else { + console.log(`[togglebutton]: Couldn't find button for ${click.target}`) + } + target = document.getElementById(button.dataset['button']); + toggleHidden(target); +} + +// If we want to blanket-add toggle classes to certain cells +var addToggleToSelector = () => { + const selector = ""; + if (selector.length > 0) { + document.querySelectorAll(selector).forEach((item) => { + item.classList.add("toggle"); + }) + } +} + +// Helper function to run when the DOM is finished +const sphinxToggleRunWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} +sphinxToggleRunWhenDOMLoaded(addToggleToSelector) +sphinxToggleRunWhenDOMLoaded(initToggleItems) + +/** Toggle details blocks to be open when printing */ +if (toggleOpenOnPrint == "true") { + window.addEventListener("beforeprint", () => { + // Open the details + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.dataset["togglestatus"] = el.open; + el.open = true; + }); + + // Open the admonitions + document.querySelectorAll(".admonition.toggle.toggle-hidden").forEach((el) => { + console.log(el); + el.querySelector("button.toggle-button").click(); + el.dataset["toggle_after_print"] = "true"; + }); + }); + window.addEventListener("afterprint", () => { + // Re-close the details that were closed + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.open = el.dataset["togglestatus"] == "true"; + delete el.dataset["togglestatus"]; + }); + + // Re-close the admonition toggle buttons + document.querySelectorAll(".admonition.toggle").forEach((el) => { + if (el.dataset["toggle_after_print"] == "true") { + el.querySelector("button.toggle-button").click(); + delete el.dataset["toggle_after_print"]; + } + }); + }); +} diff --git a/branch/ignore/about-coderefinery/index.html b/branch/ignore/about-coderefinery/index.html new file mode 100644 index 0000000..2a7fd9c --- /dev/null +++ b/branch/ignore/about-coderefinery/index.html @@ -0,0 +1,284 @@ + + + + + + + About the CodeRefinery project and CodeRefinery workshops — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • + Edit on GitHub +
  • +
+
+
+
+
+ +
+

About the CodeRefinery project and CodeRefinery workshops

+
+

Keypoints

+
    +
  • Teaches intermediate-level software development tool lessons

  • +
  • Training network for other lessons, too

  • +
  • Publicly-funded discrete projects (3 projects actually) transitioning towards an open community project

  • +
  • We have online material, teaching, and exercise sessions

  • +
  • We want more people to work with us, and to work with more people

  • +
+
+

CodeRefinery is a +Nordic e-Infrastructure Collaboration (NeIC) +project that has started in October 2016 and is +funded until February 2025.

+

The funding from 2022-2025 is designed to keep this project active +beyond 2025 by forming a support network and building a community of +instructors and contributors.

+
+

History

+

The CodeRefinery project idea grew out of two SeSE courses given at KTH Stockholm in 2014 and 2016:

+ +

The project proposal was submitted to NeIC in 2015, accepted in 2015, and started in 2016.

+

We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form.

+
+
+

Main goals

+
    +
  • Develop and maintain training material on software best practices for researchers that already write code. Our material addresses all academic disciplines and tries to be as programming language-independent as possible.

  • +
  • Provide a code repository hosting service that is open and free for all researchers based in universities and research institutes from Nordic countries.

  • +
  • Provide training opportunities in the Nordics using Carpentries and CodeRefinery training materials.

  • +
  • Articulate and implement the CodeRefinery sustainability plan.

  • +
+
+
+

Impact

+

We collect feedback and survey results to measure our impact.

+

3-6 months after attending a workshop, past participants are asked to complete a short post-workshop survey. +The survey questions aim to establish what impact CodeRefinery workshops have on how past participants develop +research software.

+

Pre- and post-workshop survey results

+
    +
  • Overall quality of research software has improved: more reusable, modular, reproducible and documented.

  • +
  • Collaboration on research software development has become easier

  • +
  • Past participants share their new knowledge with colleagues

  • +
  • Usage of several tools is improved, and new tools are adopted

  • +
+

Free-form answers +also suggest that workshops are having the intended effects on how people develop code. A common theme is:

+
+

I wish I had known this stuff already as a grad student 10+ years ago…

+
+

We would love to get suggestions on how we can better quantify our impact. This +would make it easier for us to convince institutions to partner with us and +also open up funding opportunities.

+
+
+

Target audience

+
+

Carpentries audience

+

The Carpentries aims to teach computational competence to learners through an applied approach, avoiding the theoretical and general in favor of the practical and specific.

+

Learners do not need to have any prior experience in programming. One major goal of a Carpentry workshop is to raise awareness on the tools researchers can learn/use to speed up their research.

+

By showing learners how to solve specific problems with specific tools and providing hands-on practice, learners develops confidence for future learning.

+
+

Novices

+

We often qualify Carpentry learners as novices: they do not know what they need to learn yet. A typical example is the usage of version control: the Carpentry git lesson aims to give a very high level conceptual overview of Git but it does not explain how it can be used in research projects.

+
+
+
+

CodeRefinery audience

+

In that sense, CodeRefinery workshops differ from Carpentry workshops as we assume our audience already writes code and scripts and we aim at teaching them best software practices.

+

Our learners usually do not have a good overview of best software practices but are aware of the need to learn them. Very often, they know the tools (Git, Jupyter, etc.) we are teaching but have difficulties to make the best use of them in their software development workflow.

+

Whenever we can, we should direct learners that do not have sufficient coding experience to Carpentries workshops.

+
+

Competent practitioners

+

We often qualify CodeRefinery learners as competent practitioners because they already have an understanding of their needs. +Novices and competent practitioners will be more clearly defined in the next section.

+
+
+

Best software practices for whom?

+

It can be useful to ask the question: best software practices for whom? +CodeRefinery teaches best software practices derived from producing and +shipping software. These practices are also very good for sharing software, +though our audience will probably not need to embrace all aspects of +software engineering.

+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/backward-lesson-design/index.html b/branch/ignore/backward-lesson-design/index.html new file mode 100644 index 0000000..51a3fc6 --- /dev/null +++ b/branch/ignore/backward-lesson-design/index.html @@ -0,0 +1,348 @@ + + + + + + + Backwards lesson design — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Backwards lesson design

+

It happens far too often: someone creates a lesson, but they think +about what is interesting to them, not what is important for the +learners. In fact, an earlier version of this instructor training had +this very issue.

+

It is critical to backwards design almost any piece of communication, +especially something as widespread as teaching.

+
+

The approach

+
    +
  • You don’t think about how to do something and try to explain it.

  • +
  • Avoid the typical approach “I want to show a number of things which I think are cool about +tool X - how do I press these into 90 minutes?”

  • +
  • Instead, you start defining your target audience by answering to questions +such What is the expected educational level of my audience?, Have they +been already exposed to the technologies I am planning to teach?, What +tools do they already use?, What are the main issues they are currently +experiencing?. It is important to discuss these points with a group of +colleagues, preferably from diverse backgrounds and institutions to reduce +biases. Once you clarified your target audience, it is useful to create +learner personas; that will help you during the development process by +providing concrete examples of potential learners showing up at your +workshops. For each learner personas, try to think of what is useful to +them: “What do they need to +remember/understand/apply/analyze/evaluate/create?”. +Asking and answering to these questions will allow you to define the +background knowledge (starting points) and goals (end points) of your +learners. Then, you create a sequence of exercises which test incrementally +progressing tasks and acquisition of the new skills (from starting to end +points).

  • +
  • Then, you write the minimum amount +of material to teach the gap between exercises.

  • +
+
+
+

The process

+

As described in “A lesson design process” in the book Teaching Tech +Together:

+
    +
  1. Understand your learners

  2. +
  3. Brainstorm rough ideas

  4. +
  5. Create an summative assessment to know your overall goal

    +
      +
    • CodeRefinery translation: think of the things your learners will +be able to do at the end of the lesson. Think simple! The +simpler the better. Think of three main points they will +remember, of which maybe one or two are a concrete skill.

    • +
    +
  6. +
  7. Create formative assessments to go from the starting point to this.

    +
      +
    • CodeRefinery translation: think of some engaging and active +exercises.

    • +
    +
  8. +
  9. Order the formative assessments (exercises) into a reasonable order.

  10. +
  11. Write just enough material to get from one assessment (exercise) to +another.

  12. +
  13. Describe the course so the learners know if it is relevant to them.

  14. +
+

We can’t emphasize enough how important it is to know your end +state and keep it simple.

+
+

Example: designing an HPC Carpentry lesson

+

Let’s take as an example the HPC Carpentry lesson

+

Target audience

+
    +
  • What is the expected educational level of my audience?

    +
      +
    • A PhD student, postdoc or young researcher.

    • +
    +
  • +
  • Have they been already exposed to the technologies I am planning to teach?

    +
      +
    • The word HPC is not new to them and they may have already used an HPC but are still not capable of giving a proper definition of HPC. In addition, we do not expect them to know much about parallelism and they cannot make any distinction between various available parallelism paradigms.

    • +
    +
  • +
  • What tools do they already use?

    +
      +
    • serial codes, multi-threaded codes, data parallelism; usually out-of-the-box tools.

    • +
    • they may have tried to “scale” their code (multiprocessing, threading, GPUs) with more or less success.

    • +
    +
  • +
  • What are the main issues they are currently experiencing?

    +
      +
    • they cannot solve their problems either because they would like to run the same code but with many different datasets or because their problem is larger (more computations/memory).

    • +
    • most of the time they know their codes can run on HPC (from the documentation) but never really had the opportunity to try it out.

    • +
    • Very few will have their own codes where they may have tried different things to speed it up (threading, task parallelism) but have no clear strategy.

    • +
    +
  • +
+

Learner persona

+
    +
  • Sonya is a 1st year PhD student: she recently moved to Oslo and joined the +Computational and Systems Neuroscience group. She will be using the +NEST, a simulator for spiking +neural network model. She used NEST during her master thesis but on her +small cluster: she never used an HPC resource and is really excited about it.

  • +
  • Robert is a field ecologist who obtained his PhD 6 months ago. He is now +working on a new project with Climate scientists and as a consequence will +need to run global climate models. He is not very familiar with command +line even though he attended a Software Carpentry workshop and the idea to +use HPC is a bit terrifying. He knows that he will get support from his +team who has extensive experience with HPC but would like to become more +independent and be able to run his own simulations (rather than copying +existing cases).

  • +
  • Jessica is a postdoc working on a project that investigates numerically the +complex dynamics arising at the tip of a fluid-driven rupture. Fluid +dynamics will be computed by a finite element method solving the +compressible Navier-Stokes equations on a moving mesh. She uses a code she +has developed during her PhD and that is based on existing libraries. She +has mostly ran it on a local desktop; her work during her PhD was very +limited due to the lack of computing resources and she is now very keen is +moving to HPC; she knows that it will requires some work, in particular to +parallelize her code. This HPC training will be her first experience with +HPC.

  • +
+

Learning outcomes

+
    +
  • Understand the difference between HPCs and other local/remote machines

  • +
  • Understand the notion of core, nodes, cluster, shared/distributed memory, etc.

  • +
  • Understand the notion of login nodes.

  • +
  • Understand the need for a scheduler and how to use it appropriately

  • +
  • Understand why optimising I/O is important on HPC and how to best use HPC filesystems

  • +
  • Understand the need to parallelize (or use existing parallel) codes and in which cases HPCs is a must (when communications is required)

  • +
  • Understand how to get your code ready to use on HPC (access to libraries, installation of your own libraries/software, etc.)

  • +
  • Understand that an HPC is an operational machine and is not meant for developing codes.

  • +
+

Exercises

+
    +
  • Get basic information such the number of CPUs, memory from your laptop and try to do the same on a HPC. Discuss outcomes.

  • +
  • Try to create files on the different filesystems on your HPC resource and access them.

  • +
  • Create different types of job scripts, submit and check outputs.

  • +
  • Make a concrete example to run a specific software on your HPC (something like GROMACS).

  • +
+
+
+
+

Exercises

+
+

Backwards-design a lesson/topic

+

Choose a simple lesson topic and apply backwards lesson design. You +won’t get all the way through, but come up with a logical +progression of exercises.

+

The section you pick should require screen sharing and be of some follow-along +task (preferably using a shell).

+

Some suggestions:

+
    +
  • Regular expressions

  • +
  • Making papers in LaTeX

  • +
  • Making figures in your favorite programming language

  • +
  • Linux shell basics

  • +
  • Something non-technical, such as painting a room

  • +
  • An instructor training for CodeRefinery

  • +
  • Some aspect from an already existing lesson

  • +
  • Introduction to high-performance computing (or an episode therein)

  • +
  • Unix shell in a HPC context (or an episode therein)

  • +
  • A lesson you always wanted to teach

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/collaboration-models/index.html b/branch/ignore/collaboration-models/index.html new file mode 100644 index 0000000..c4d1d68 --- /dev/null +++ b/branch/ignore/collaboration-models/index.html @@ -0,0 +1,251 @@ + + + + + + + Collaboration models — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Collaboration models

+
+

Model: CodeRefinery

+
    +
  • Before Covid-19, workshops were physically around the Nordics, +instructors would travel (or already be there).

    +
      +
    • Maximum size: ~40 people

    • +
    • High workload per person

    • +
    +
  • +
  • After several small scaling attempts, now we have:

    +
      +
    • Two large workshops per year - livestream format

    • +
    • Combined organization efforts

    • +
    • Instructors from each location - on average two lessons taught.

    • +
    • Locations with staff can have local breakout rooms: physical +place to help during exercises.

    • +
    +
  • +
  • Others in the world can register and interact using HackMD, but no +promises of help.

  • +
  • Content still available to anyone in the world: live + instant +replay.

  • +
  • Course page and material: +https://coderefinery.github.io/2022-03-22-workshop/

  • +
+
+
+

Model: Python for Scientific Computing

+
    +
  • Aalto Scientific Computing wanted to host a course, Python for +Scientific Computing

  • +
  • ASC came up with initial vision and announced it

  • +
  • ASC hosted an open initial meeting, inviting any interested +organizers or instructors

  • +
  • We went over the plan and refined the topics and schedule. We also +decided things such as the date, organizers, and instructors for +each lesson.

  • +
  • Registration was open to everyone in the world, non-Nordic +participants could watch via livestream.

  • +
  • People prepared their parts and came together and presented. +Organizers kept everything on track.

  • +
  • Compared to the amount of effort each person put in, the results +were great.

  • +
  • A 2021 version also happened and was even larger.

  • +
  • Course page: https://scicomp.aalto.fi/training/scip/python-for-scicomp/

  • +
  • Material: https://aaltoscicomp.github.io/python-for-scicomp/

  • +
+
+
+

Exercises

+
+

List successes and failures in collaborative teaching

+

Using HackMD, list some successes and failures in collaborative +teaching that you have experienced.

+
+
+

Recommendations for co-teaching

+

If you have experience with co-teaching, what approach/technique/trick +can you recommend a colleague who would like to try co-teaching for the +first time?

+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/distributed/index.html b/branch/ignore/distributed/index.html new file mode 100644 index 0000000..0ebf64c --- /dev/null +++ b/branch/ignore/distributed/index.html @@ -0,0 +1,220 @@ + + + + + + + Distributed workshop organization — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Distributed workshop organization

+
+

Keypoints

+
    +
  • If another university/organization wants to run the course, they can easily join our existing course at little cost/risk to them and to us.

  • +
  • Each organization that joins provides a great benefit to us (helpers, instructors).

  • +
  • They can reserve an in-person breakout room and provide mentors while watching the livestream: A great experience for their audience.

  • +
+
+
+

It is easier to join and follow than to start or lead

+

Organizing a course is time intensive and so is developing a course. Many +courses given in country A are also relevant in other countries and instead of +developing and possibly re-inventing courses independently in different places, +it is so much more rewarding to collaborate and share.

+

In our courses we wish and try to make it easier for teams and organizations +and universities to join, at little risk and cost to them, possibly for a short +period of time, possibly only as observer. Later observers can progress to +exercise leads, expert helpers, instructors, and co-organizers.

+

One model that we have successfully tried is that the course is delivered via +live-stream to all partners and all the partner needs to do is to reserve a +room and motivate few people to help local learners as exercise leads during +exercise sessions which can happen in-person.

+
+

Lessons learned from organizing larger workshops

+
    +
  • One person is needed to coordinate the registration process and this person should +not have teaching duties in addition to this role.

  • +
  • Generally it helps to have well-defined roles (see Workshop roles).

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/diversity-and-inclusion/index.html b/branch/ignore/diversity-and-inclusion/index.html new file mode 100644 index 0000000..7e7b397 --- /dev/null +++ b/branch/ignore/diversity-and-inclusion/index.html @@ -0,0 +1,232 @@ + + + + + + + Diversity and inclusion — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Diversity and inclusion

+

When we are teaching, we fill a critical role in between people and +technology. We are not un-involved technical staff teaching asocial +topics, but we are very connected to the social context of the tools. +Unfortunately, there are major demographic imbalances in most +computing.

+
+

Primary articles

+ +
+
+

Support services vs diversity

+

Study this presentation by Richard Darst:

+ +

Summary:

+
    +
  • Computing is hard and quite often our ability to learn quickly is +connected to our social group.

  • +
  • Good technical services serve the role of mentors

  • +
  • This mentorship helps to equalize

  • +
  • Our entire system of research should be configured for more +equality. Modernization usually takes it the other way.

  • +
+
+
+

Exercises

+
+

Reflect on how your job can be defined to promote diversity.

+

What are some (possibly surprising) ways that your job promote +diversity and equality among people of different backgrounds?

+
+
+
+

See also

+

(none yet)

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/exercises/index.html b/branch/ignore/exercises/index.html new file mode 100644 index 0000000..532100b --- /dev/null +++ b/branch/ignore/exercises/index.html @@ -0,0 +1,947 @@ + + + + + + + Exercise list — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Exercise list

+

This is a list of all exercises and solutions in this lesson, mainly +as a reference for helpers and instructors. This list is +automatically generated from all of the other pages in the lesson. +Any single teaching event will probably cover only a subset of these, +depending on their interests.

+
+

Teaching online

+

In teaching-online.md:

+
+

Exercise

+

Using HackMD, brainstorm advantages and disadvantages of online and +in-person teaching. For each disadvantage of each, think of ways to compensate.

+
+
+
+

Team teaching

+

In team-teaching.rst:

+
+

Exercise

+

Divide into groups of two or three. Choose one of the two models +in the team-teaching page, and quickly (5 min) prepare a short +topic (3-5 min) to team teach. You can quickly scan the +“preparation” section at the bottom.

+

The challenge is not just to give the lesson, but to prepare the +lesson quickly and rely on each other to give a good lesson anyway.

+
+
+
+

HackMD

+

In hackmd.rst:

+
+

Exercise

+
    +
  • Actively use HackMD during this course.

  • +
  • Observe how the instructors integrate it during the course +itself, and can immediately respond to the questions.

  • +
  • Observe how instructors occasionally mention and screenshare +HackMD to validate to the audience that it is being watched.

  • +
  • Keep HackMD open. Can you balance it and watching. Does it +increase or decrease engagement?

  • +
+
+
+
+

Teams

+

In teams.rst:

+
+

Teams

+

Consider these questions:

+
    +
  • Should teams have similar or different people in them?

  • +
+
+
+
+

Livestreaming

+

In livestreaming.rst:

+
+

(advanced) Set up and install OBS as a livestreaming tool.

+

This exercise is open-ended.

+
+
+
+

Instructor tech setup

+

In instructor-tech-setup.md:

+
+

Evaluate screen captures

+

Evaluate screenshots within the instructor tech +setup lesson. +Use the collaborative document to make a list of the trade-offs of each one. +Which one do you prefer? Which are useful in each situation?

+
+

In instructor-tech-setup.md:

+
+

Set up your own environment

+

Set up your screen to teach something. Get some feedback from +another learner. We will discuss among the class.

+
+
+
+

Video editing

+

In video-editing.rst:

+
+

Editing-1: Get your sample video

+

Download a sample video:

+
+
+
+

In video-editing.rst:

+
+

Editing-2: Run Whisper to generate raw subtitles and test video.

+

First off, install Whisper and generate the base subtitles, based +on the. Since this is probably too much to expect for a short +lesson, they are provided for you (above), but if you want you can +try using Whisper, or generating the subtitles some other way.

+

You can start generating subtitles now, while you do the next +steps, so that they are ready by the time you are ready to apply +the editlist. ffmpeg-editlist can also slice up the subtitles from +the main video to make subtitles for each segment you cut out.

+

Whisper is left as an exercise to the reader.

+ +
+

In video-editing.rst:

+
+

Editing-3: Create the basic editlist.yaml file

+

Install ffmpeg-editlist and try to +follow its instructions, to create an edit with these features:

+
    +
  • The input definition.

  • +
  • Two output sections: the “Intro to the course”, and “From data +storage to your science” talks (Remember it said the recording +started at 11:35… look at the schedule for hints on when it +might start!). This should have a start/end timestamp from the +original video.

  • +
+

A basic example:

+
- input: day1-raw.mkv
+
+# This is the output from one section.  Your result should have two of these sections.
+- output: part1.mkv
+  title: something
+  description: >-
+    some long
+    description of the
+    segment
+  editlist:
+    - start: 10:00    # start timestamp of the section, in *original* video
+    - end: 20:00      # end timestamp of the section, in the *original* video
+
+
+ +
+

In video-editing.rst:

+
+

Editing-4: Run ffmpeg-editlist

+

Install ffmpeg-editlist: pip install ffmpeg-editlist[srt] (you +may want to use a virtual environment, but these are very minimal +dependencies).

+

The ffmpeg command line tool must be available in your +PATH.

+ +
+

In video-editing.rst:

+
+

Editing-5: Add more features

+
    +
  • Several chapter definitions.(re-run and you should see a +.info.txt file also generated). Video chapter definitions +are timestamps of the original video, that get translated to +timestamps of the output video.

    +
    - output: part1.mkv
    +  editlist:
    +  - start: 10:00
    +  - -: Introduction    #  <-- New, `-` means "at start time"
    +  - 10:45: Part 1      #  <-- New
    +  - 15:00: Part 2      #  <-- New
    +  - end: 20:00
    +
    +
    +

    Look at the .info.txt files that come out now. What is new in it?

    +
  • +
  • Add in “workshop title”, “workshop description”, and see the +.info.txt files that come out now. This is ready for +copy-pasting into a YouTube description (first line is the title, +rest is the description).

    +

    Look at the new .info.txt files. What is new?

    +
  • +
+ +
+

In video-editing.rst:

+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+ +
+

In video-editing.rst:

+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+
+

In video-editing.rst:

+
+

Editing-7: Generate the final output file.

+
    +
  • Run ffmpeg-editlist with the --reencode option: this +re-encodes the video and makes sure that there is no black point +at the start.

  • +
  • If you re-run with --check, it won’t output a new video file, +but it will re-output the .info.txt and .srt files. +This is useful when you adjust descriptions or chapters.

  • +
+
+

In video-editing.rst:

+
+

Use ffmpeg-editlist to edit this sample video

+

Prerequisites: ffmpeg must be installed on your computer +outside of Python. Be able to install ffmpeg-editlist. This is +simple in a Python virtual environment, but if not the only +dependency is PyYAML.

+ +
+

In video-editing.rst:

+ +
+
+

Why teach together?

+

In why-teach-together.rst:

+
+

What similarities do we have?

+

Using HackMD, make two lists:

+
    +
  • What courses do you think your local community would benefit +from, which you don’t currently have? +1 other people’s items +which are also relevant to you.

  • +
  • Which courses are you thinking of preparing for your local +community? +1 other people’s items which you would be +interested in helping out with.

  • +
+
+
+
+

Collaboration models

+

In collaboration-models.rst:

+
+

List successes and failures in collaborative teaching

+

Using HackMD, list some successes and failures in collaborative +teaching that you have experienced.

+
+

In collaboration-models.rst:

+
+

Recommendations for co-teaching

+

If you have experience with co-teaching, what approach/technique/trick +can you recommend a colleague who would like to try co-teaching for the +first time?

+
+
+
+

Workshop roles

+

In workshop-roles.rst:

+
+

How many people teach in your workshops?

+
    +
  • Using HackMD, make a histogram of how many (instructors + +organizers) you typically have in your workshops.

  • +
  • List some of the common roles you have used.

  • +
+
+
+
+

Why are computers hard?

+

In why-are-computers-hard.rst:

+
+

Exercise

+

Think of a tool or technology that is easy to understand and use if +you understand the underlying abstraction layers, but is almost +impossible otherwise.

+
+
+
+

Diversity and inclusion

+

In diversity-and-inclusion.rst:

+
+

Reflect on how your job can be defined to promote diversity.

+

What are some (possibly surprising) ways that your job promote +diversity and equality among people of different backgrounds?

+
+
+
+

Lesson development with version control

+

In lessons-with-version-control.md:

+
+

Contribute to a sample lesson

+
    +
  • Open this very lesson in GitHub (it uses the same format as +typical CodeRefinery lessons): +https://github.com/coderefinery/community-teaching/

  • +
  • Browse the files and understand the general idea. Check out at +least these and use HackMD to record their functions:

    +
      +
    • .github/workflows/sphinx.yml

    • +
    • content/conf.py

    • +
    • content/index.rst

    • +
    • content/lessons-with-version-control.rst

    • +
    +
  • +
  • If you want, try to make a pull request to this lesson. It +doesn’t have to have any significant content, it can be a pure +test pull request.

  • +
+
+

In lessons-with-version-control.md:

+
+

(advanced) Create your own lesson

+

Use the +sphinx-lesson-template +to create a new lesson of your choice. Alternatively, use the current +Carpentries system, or some other system of your choice.

+
+
+
+

Backwards lesson design

+

In backward-lesson-design.md:

+
+

Backwards-design a lesson/topic

+

Choose a simple lesson topic and apply backwards lesson design. You +won’t get all the way through, but come up with a logical +progression of exercises.

+

The section you pick should require screen sharing and be of some follow-along +task (preferably using a shell).

+

Some suggestions:

+
    +
  • Regular expressions

  • +
  • Making papers in LaTeX

  • +
  • Making figures in your favorite programming language

  • +
  • Linux shell basics

  • +
  • Something non-technical, such as painting a room

  • +
  • An instructor training for CodeRefinery

  • +
  • Some aspect from an already existing lesson

  • +
  • Introduction to high-performance computing (or an episode therein)

  • +
  • Unix shell in a HPC context (or an episode therein)

  • +
  • A lesson you always wanted to teach

  • +
+
+
+
+

CodeRefinery teaching philosophies

+

In 02-teaching-philosophies.md:

+
+

Ice-breaker in groups (20 minutes)

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also +Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+

In 02-teaching-philosophies.md:

+
+

Anne Fouilloux

+

I regularly teach Carpentries workshops so I try to apply what I have learnt to CodeRefinery workshops. However, I know our target audience is very much different and that I need to adapt my teaching style. I am still trying to find what works best in which situations and this is why I like so much CodeRefinery workshops. We usually have a wider range of skills and very mixed backgrounds so we usually have to be more careful with the pace and time given for exercises.

+

Some considerations:

+
    +
  • I spend quite a lot of time reading the CodeRefinery material and practising myself exercises. I particularly like to read the instructor notes just before teaching: they usually highlight important aspects both for preparing and teaching.

  • +
  • I usually do not show too much in advance the material as I think it prevents asking questions. If you have less competent practitioners in the classroom, they can easily copy-paste to avoid slowing down the entire classroom.

  • +
  • Ideally, I’d like to give several exercises so anyone can work at its own pace. I find it is important that everybody gets something different from the workshop.

  • +
  • I love breaks as it gives us an opportunity to discuss with attendees on their research topics. I am especially interested to understand what software they write and how they plan to use what they learn during our workshops.

  • +
+
+

In 02-teaching-philosophies.md:

+
+

Bjørn Lindi

+

My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this “BLOB” (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the “BLOB”, to be able to share it with others.

+

In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic.

+

When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson.

+

Tools that I find useful in preparing a lesson is concept maps and Learner Personas, though I have develop to few them.

+ +
+

In 02-teaching-philosophies.md:

+
+

Thor Wikfeldt

+

I never want to leave any learner behind and I really don’t like seeing confused, blank faces in the classroom. +At the same time I sometimes worry about some participants getting bored if a lesson is progressing slowly. +This is always a difficult compromise and something I struggle with!

+

I try to focus on making concepts intuitive, to “make sense” to the learners. Of course this is usually +based on how I learned the topic myself and how it makes sense to me.

+

I try to establish connections between topics: “this thing here is similar to what we saw in the previous +lesson where we learned about X…”.

+

Before mastering a lesson by teaching in many times I try to “follow the script”. After becoming very +familiar with a lesson I start to improvise more and react more dynamically to questions, e.g. by taking a +detour to explain a confusing topic more clearly.

+

What I think I do too often: copy-paste code/text from lesson material. This can leave learners behind - +typing out the code and describing it is slower, but more learning takes place. More advanced learners +will hopefully “be compensated” by interesting advanced exercises which follow.

+
+

In 02-teaching-philosophies.md:

+
+

Stefan Negru

+

A lesson is a conversation, it is useful if both the trainer and the trainee are engaged. +For that reason I try to have, most of the time, a conversation with the classroom and +after we finish parts of a lesson, step back and see how we might use what we learned.

+

That brings me to another point I follow throughout the lessons, answering questions like:

+
    +
  • How can we apply in practice what we just learned?

  • +
  • Do you see yourself (the trainee) using that in practice, why or why not?

  • +
+

Most of the times those seem like open-ended questions to the trainees that just learned +something new, so I try to find examples, most of the times from personal experience.

+

Last thing is that analogies are important when I teach, I try to find analogies in order +to simplify a convoluted part of a lesson.

+
+

In 02-teaching-philosophies.md:

+
+

Radovan Bast

+

My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos.

+

My goal for a lesson is to spark curiosity to try things after the lesson, +both for the novices (“This looks like a useful tool, I want to try using it +after the workshop.”) and the more experienced participants (“Aha - I did not +know you could do this. I wonder whether I can make it work with X.”). I like +to start lessons with a question because this makes participants look up from +their browsers.

+

Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise.

+

For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate +the answer.

+

I try to avoid jargon and “war stories” from the professional developers’ +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid “customer”, +“production”, also a lot of Agile jargon is hard to relate to.

+

Less and clear is better than more and unclear. Simple examples are better +than complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +“simply”, “just”, “easy”. If participants take home one or two points from +a lesson, that’s for me success.

+

I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don’t want to +be surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or +slide. This allows me to skip and distill the essence and not read bullet +point by bullet point.

+

I try to never deviate from the script and if I do, be very explicit about +it.

+

A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel.

+

I find it very helpful if there is somebody else in the room who helps me +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson but when doing that to +others, I am often worried of interrupting their flow and timing too much.

+

A mistake I often do is to type too fast and in my mind I force myself +to slow down.

+
+

In 02-teaching-philosophies.md:

+
+

Sabry Razick

+

My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case.

+
+

In 02-teaching-philosophies.md:

+
+

Juho Lehtonen

+

I’m gradually realising the different ways to get a hint whether the workshop +participants are still following or perhaps bored. I assume it’s communicating +with the class, with exercises and simply by asking now and then. I also try +to remember to observe how people look like (puzzled, bored) while I teach, not +so obvious for me.

+

I believe that learners communicating with each other, in addition to with +instructors and helpers, really helps them to understand things faster. (At least +it helps me). So I try to make sure that no one sits or works alone at the workshops.

+
+

In 02-teaching-philosophies.md:

+
+

Richard Darst

+

Like many people, I’ve often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I’ve realized long ago that my most important lessons weren’t +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I’ve realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds.

+

My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I’m often start at the +very basics, because this is what I see missing most often.

+

When teaching, I like lots of audience questions and don’t mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don’t have to know everything perfectly, just show how +you’d approach a problem.

+
+

In 02-teaching-philosophies.md:

+
+

João M. da Silva

+

I started giving technical trainings twenty years ago, and hence my perspective +is perhaps more inclined towards the development of hands-on abilities and +capability to solve problems, independently or in a team.

+

But the development of hands-on practical skills, requires some essential +knowledge about the domain and some willingness to try different approaches +in case one gets stuck. Some call this the “KSA approach” +(“Knowledge-Skills-Attitude). Hence, I +try to impart the essential knowledge (and where to find out more) at my +trainings. And to encourage and challenge students in order to make them +overcome their self-perceived limits (e.g. “I’m a Humanist, I can’t use +Python virtualenv”).

+

I’ve been trying to study more about the Cognitive aspects of learning over the years, +and I should find out the time to return to that. There’s very interesting +research in Problem Solving, with Learning being a important component in that domain.

+

Storytelling: humans are neurologically made for paying attention to good +stories, and that’s something that I try to put into account: to give +a lesson like it would be a relevant narrative for the students, one that they +could relate to and help them in their work

+

I like to draw and be creative with that, but have to pay attention to +my handwriting during my trainings. I reckon that Architectural diagrams +help students to understand the big picture, so I should invest more on +those when development training material. I would also like to start looking into +Concept Maps and Semantic Trees in training.

+
+
+
+

Interactive teaching style

+

In 03-teaching-style.md:

+ +

In 03-teaching-style.md:

+
+

Give feedback on teaching (optional, 10 mn)

+

This exercise aims at learning to give feedback. It is optional as we have +similar exercises when practising teaching). +As a group, we will watch this video of teaching and +give feedback on two axes: positive vs. negative and content vs. presentation. Have each person in +the class add one point to a 2x2 grid on a whiteboard or in the shared notes (hackMD, etherpad, google doc) without duplicating any points. +For online instructor training event, use breakout room (4-5 persons per group) to facilitate discussion. Then each group reports to the shared notes. +You can use a rubric (used during The Carpentries teaching demos) to help you take notes. +What did other people see that you missed? What did they think that you strongly agree or disagree with?

+
+

In 03-teaching-style.md:

+
+

Exercise: How to identify learner profiles?

+
    +
  1. How to identify leaner profiles from surveys and during the class

  2. +
  3. Which types of learners should the leassons focus on

  4. +
+
+
+
+

Teaching practice and feedback

+

In teaching-practice.md:

+
+

Exercise

+
    +
  • We organize the breakout rooms to not only discuss one lesson/topic so that it is more interesting +to listen and also probably we will all get more useful feedback.

  • +
  • Give each other constructive verbal feedback on the teaching demos, for example +using this demo rubric.

  • +
  • Write down questions (in the collaborative document) that you would like to +discuss in the main room or interesting conclusions which you would like to +share with others.

  • +
+
+

In teaching-practice.md:

+
+

Exercise

+
    +
  • In the second round we distribute the rooms differently so that you can +present it to a new group of workshop participants and can receive new +feedback.

  • +
  • Ask for feedback and one/few point(s) you want to improve.

  • +
  • In your second trial check whether you feel the demonstration improved.

  • +
  • Share your lessons learned in the collaborative document.

  • +
  • Give us also feedback on this exercise format. Was it useful? What can we improve?

  • +
+
+

In teaching-practice.md:

+
+

Exercise

+

Teaching by live coding is a +performance art which requires practice. +This exercise highlights some typical pitfalls that most instructors +fall into sooner or later, and also shows how to avoid them. +Watch closely since we will be giving feedback!

+
    +
  • Watch these two videos: video 1 and +video 2

  • +
  • What was better in video 1 and what was better in video 2?

  • +
  • Please give feedback in the shared workshop document.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/future/index.html b/branch/ignore/future/index.html new file mode 100644 index 0000000..0ba644d --- /dev/null +++ b/branch/ignore/future/index.html @@ -0,0 +1,247 @@ + + + + + + + Possibilities for Carpentries — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Possibilities for Carpentries

+
+

Keypoints

+
    +
  • Carpentries is currently designed around small workshops, so many of these ideas can’t directly apply

  • +
  • Yet many of these tools and also team teaching can still be used

  • +
  • You can run your own breakout room for any of our workshops

  • +
  • Join as observer if you want to see our workshop organization and tools in action

  • +
+
+

CodeRefinery workshops can be a good progression step after taking a +Carpentries workshop.

+

Helping out at a CodeRefinery workshop as exercise lead can be a good +progression step for those who have helped out at a Carpentries workshop or who +have taken the Carpentries instructor training.

+
+
+

CodeRefinery’s plans

+
+

Keypoints

+
    +
  • We are continuing to focus on online-first with local breakout rooms

  • +
  • We welcome people joining us, either individually or as an organization

  • +
  • Still interested in collaboration with Carpentries

  • +
  • We need to become better at marketing and outreach

  • +
+
+
+

Biggest open problems

+
    +
  • How to give helpers and contributors more credit and visibility

  • +
  • How to promote/engage new members

  • +
  • What are we? Non-profit? Institution collaboration network? Selling services?

  • +
  • Funding and sustainability (but we have ideas: collaboration network)

  • +
+
+
+

How you can join

+

Individual level:

+
    +
  • Join CodeRefinery +chat

  • +
  • Lead a team, co-teach, or help organize a workshop

  • +
  • Generally provide marketing and outreach

  • +
+

Organization level:

+
    +
  • Have your organization join CodeRefinery

  • +
  • Officially co-advertise and co-teach workshops

  • +
  • Run local breakout rooms and join a workshop as a team

  • +
  • Send an observer to a workshop

  • +
+
+
+

Aside: Nordic-RSE (research software engineers)

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/genindex/index.html b/branch/ignore/genindex/index.html new file mode 100644 index 0000000..404a83e --- /dev/null +++ b/branch/ignore/genindex/index.html @@ -0,0 +1,181 @@ + + + + + + Index — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/branch/ignore/guide/index.html b/branch/ignore/guide/index.html new file mode 100644 index 0000000..35cd755 --- /dev/null +++ b/branch/ignore/guide/index.html @@ -0,0 +1,193 @@ + + + + + + + Instructor’s guide — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Instructor’s guide

+

In a lesson that was further developed, this would include an +instructor’s guide that mentioned:

+
    +
  • Background of why the course is how it is

  • +
  • Recommendations of teaching it

  • +
  • Known pitfalls of teaching it, so that other instructors can avoid +them

  • +
  • Possibly how to contribute, long-term plans, etc.

  • +
+

For example, see git-intro’s instructor guide.

+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/hackmd/index.html b/branch/ignore/hackmd/index.html new file mode 100644 index 0000000..8f9803c --- /dev/null +++ b/branch/ignore/hackmd/index.html @@ -0,0 +1,251 @@ + + + + + + + HackMD — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

HackMD

+

The name “HackMD” doesn’t do this concept justice, nor do the more +common descriptions of “shared notes” or “collaborative document”. It +is a full replacement for chat: perhaps it could be called random +access chat or parallel 2D chat ?

+

HackMD itself is a web service for collaborative documents in +Markdown. This isn’t special to HackMD, but we have used it for its +scalability, markdown support, and privacy in the “view” mode.

+
+

Primary articles

+ +
+
+

Advantages

+
    +
  • Synchronous questions, no disadvantage for quiet people.

  • +
  • Anonymous questions.

  • +
  • Parallel answers by a large number of helpers.

  • +
  • Easier to go back and review past questions during Q&A sessions +(compared to scrolling through chat), for example finding important +or unanswered questions.

  • +
  • The above can make a course feel much more interactive than it would +otherwise.

  • +
+
+
+

Disadvantages

+
    +
  • Overwhelming flood of information

    +
      +
    • But you wanted more interaction, right?

    • +
    • Co-teaching helps here, one person can focus on watching.

    • +
    • Students must be warned to be deliberate about where they focus +their attention (different learners have different interests).

    • +
    +
  • +
  • It is another tool to use

    +
      +
    • Not required for basic learners, learners can begin using when +they are comfortable.

    • +
    +
  • +
+
+
+

Exercise

+
+

Exercise

+
    +
  • Actively use HackMD during this course.

  • +
  • Observe how the instructors integrate it during the course +itself, and can immediately respond to the questions.

  • +
  • Observe how instructors occasionally mention and screenshare +HackMD to validate to the audience that it is being watched.

  • +
  • Keep HackMD open. Can you balance it and watching. Does it +increase or decrease engagement?

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/index.html b/branch/ignore/index.html new file mode 100644 index 0000000..d3cb4a2 --- /dev/null +++ b/branch/ignore/index.html @@ -0,0 +1,311 @@ + + + + + + + Community teaching training — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Community teaching training

+
+

Under development (mid 2022)

+

As of mid-2022, this material has been reworked for our summer workshop and +for the CarpentryCon 2022 workshop. The material will continue to be +improved before a longer training session in the autumn.

+

This material is the new version of our previous Instructor +training.

+
+
+

What this course covers

+

In 2020, we got farther from our offices but closer to each other. If +you could adapt to the circumstances, a huge number of possibilities +were opened - in particular with collaborative teaching. In this +training, you will learn how we use them. Teaching from 2019 is +almost obsolete - join us to learn more.

+
    +
  • Tools of teaching: how to make the most out of online (and +other) teaching.

  • +
  • Workshop organization, collaboratively: our vision of teaching +together outside of our silos.

  • +
  • Socio-technical factors: social and technical barriers to +learning, why you need to care, and what you can do about them.

  • +
  • Lesson development, collaboratively: how to design lessons and +teaching materials so that they can be open and shared.

  • +
+
+
+

Who is the course for?

+

Teaching is a profession, but also something that everyone needs to be +able to do to some degree, since everyone has their own personal +specialties they will either teach or mentor.

+

This course can be relevant for different learner personas:

+
    +
  • You run a practical teaching program at your institution (for example +as part of a research computing group) and would like to learn best +practices for collaborative teaching, so that you aren’t re-inventing +the same thing over and over again.

  • +
  • You are a technical specialist who is frustrated with the way you +currently try to teach others who need to use your software or +infrastructure. You can’t spend too much time to become a +professional, but you know you need something more than what you’ve +been doing. Thus, you would like to adopt some of the best practices of +designing and teaching interactive, hands-on workshops.

  • +
  • You’ve been teaching alone, but would like to join a collaboration +network for more co-teaching and to reduce the amount of duplication +of effort.

  • +
  • You are interested in teaching CodeRefinery lessons, and would like a +comprehensive kick-start to how CodeRefinery works, either to join us, +or teach its lessons with us or independently.

  • +
+
+

Preparation

+ +
+ + + + + +
+

Wrap-up, future, and getting involved

+ +
+ + +

test

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/instructor-tech-setup/index.html b/branch/ignore/instructor-tech-setup/index.html new file mode 100644 index 0000000..71579db --- /dev/null +++ b/branch/ignore/instructor-tech-setup/index.html @@ -0,0 +1,278 @@ + + + + + + + Instructor tech setup — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Instructor tech setup

+
+

Keypoints

+
    +
  • Screenshare: portrait layout instead of sharing entire screen

  • +
  • Prompt: adjust your prompt to make commands easy to read

  • +
  • Readability and beauty is important: adjust your setup for your audience

  • +
  • Share the history of your commands

  • +
  • Get set up a few days in advance and get an outside reviewer

  • +
+
+
+

Screenshare

+

Compare the following two screen-shares (you can find many more in +the coderefinery manuals:

+
+https://coderefinery.github.io/manuals/_images/screenshare-fullhd.png +
+

FullHD.

+
+
+
+https://coderefinery.github.io/manuals/_images/s10-kickstart-prompt-log.png +
+

Portrait, latest proposed best practices.

+
+
+

Share a portrait layout (left or right half of your screen) +instead of sharing entire screen.

+

Motivation:

+
    +
  • This makes it easier for you to look at some other notes or to coordinate +with other instructors at the same time +without distracting with too much information.

  • +
  • This makes it possible for participants to have something else open in the +other screen half: terminal or browser or notebook.

  • +
+
+
+

Adjust your prompt/configuration/colors

+

Adjust your prompt to make commands easy to read. What looks good for your own +work (many terminals, small font, extensions, shortcuts, color scheme) is +usually not the best for other people watching you. Adjust your setup for your +audience. Remove distractions.

+

You need to spend some time getting set up before you teach. 10 minutes +before the session starts is typically too late. Get set up a few days in +advance and get an outside reviewer.

+
+

Should instructors be forced to have a consistent screenshare?

+

There are pros and cons to all instructors using the same screenshare and prompt.

+
    +
  • What are the advantages?

  • +
  • What are the opportunities of instructors showing different setups?

  • +
  • How does it depend on the lesson and the experience of learners?

  • +
+
+
+
+

Share the history of your commands

+

Even if you type slowly it is almost impossible to follow every command. We +all get distracted or want to read up on something or while following a command +fails on the learner laptop while instructor gets no error.

+

Add pauses and share the commands that you have typed so that one can catch up.

+
+
+

More examples and how to set it up

+ +
+
+

Exercises

+
+

Evaluate screen captures

+

Evaluate screenshots within the instructor tech +setup lesson. +Use the collaborative document to make a list of the trade-offs of each one. +Which one do you prefer? Which are useful in each situation?

+
+
+

Set up your own environment

+

Set up your screen to teach something. Get some feedback from +another learner. We will discuss among the class.

+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/lesson.pdf b/branch/ignore/lesson.pdf new file mode 100644 index 0000000..6afd038 Binary files /dev/null and b/branch/ignore/lesson.pdf differ diff --git a/branch/ignore/lessons-with-version-control/index.html b/branch/ignore/lessons-with-version-control/index.html new file mode 100644 index 0000000..fcd66f5 --- /dev/null +++ b/branch/ignore/lessons-with-version-control/index.html @@ -0,0 +1,293 @@ + + + + + + + Lesson development with version control — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Lesson development with version control

+

So, we want to practically share. We have these minimum requirements:

+
    +
  • Someone can get the preferred form of modification, to improve +without limitation.

  • +
  • It is trivial to track differences and send the changes back to the +source, with little cost to the original maintainer.

  • +
+

Especially with the second of these, version control in an online +platform seems to be the only reasonable option.

+
+

Version control and static site generators

+

CodeRefinery and the Carpentries use git and Github to develop +lessons. The general procedure is this:

+
    +
  • Version control to store the raw files in text format

  • +
  • A static website compiler to convert them to HTML files

  • +
  • Serving to the public via Github Pages (but this could be replaced +with other systems)

  • +
+

This allows for true collaborative development and community +contributions.

+

Carpentries uses a custom website complierer based on R, CodeRefinery +uses the Sphinx documentation engine which is used in many different +projects for documentation. CodeRefinery’s use of a standard tool +allows us to build on a huge and growing ecosystem of extensions and +themes, and promotes local reuse.

+

The exact static website generator used isn’t so important, as long as +some form of version control is used.

+

A open-source license is the last bit to consider: without a license, +it can’t be reused and passed on, and there is little incentive for +someone to contribute.

+
+
+

CodeRefinery lesson tools

+

CodeRefinery uses the following tools to actually make its lessons +right now:

+
    +
  • Sphinx (a common documentation +generator, widely used in open source projects in general)

  • +
  • The sphinx-lesson, which is more of +a small collection of other extensions than new development itself.

  • +
  • Github for hosting lessons: https://github.com/coderefinery/

  • +
  • Github Actions and Github Pages for building and web serving our +lessons.

  • +
+
+
+

Exercises

+
+

Contribute to a sample lesson

+
    +
  • Open this very lesson in GitHub (it uses the same format as +typical CodeRefinery lessons): +https://github.com/coderefinery/community-teaching/

  • +
  • Browse the files and understand the general idea. Check out at +least these and use HackMD to record their functions:

    +
      +
    • .github/workflows/sphinx.yml

    • +
    • content/conf.py

    • +
    • content/index.rst

    • +
    • content/lessons-with-version-control.rst

    • +
    +
  • +
  • If you want, try to make a pull request to this lesson. It +doesn’t have to have any significant content, it can be a pure +test pull request.

  • +
+
+
+

(advanced) Create your own lesson

+

Use the +sphinx-lesson-template +to create a new lesson of your choice. Alternatively, use the current +Carpentries system, or some other system of your choice.

+
+
+
+

Recommendations and lessons learned

+
    +
  • Convert feedback about lessons and suggestions for improvements into issues +so that these don’t get lost.

  • +
  • Make your lesson citable: get a DOI.

  • +
  • Credit contributors (not only Git commits).

  • +
  • Instructor guide is essential for new instructors.

  • +
  • Lesson changes should be accompanied with instructor guide changes (it’s like +a documentation for the lesson material).

  • +
  • Apply and validate Backwards lesson design again and again.

  • +
  • Make it possible to try out new ideas (by making the lesson branch-able).

  • +
  • Before making larger changes, talk with somebody and discuss these changes.

  • +
  • For substantial changes we recommend to first open an issue and describe your +idea and collect feedback before you start with an extensive rewrite.

  • +
  • For things still under construction, open a draft pull request to collect +feedback and to signal to others what you are working on.

  • +
+
+
+

See also

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/livestreaming/index.html b/branch/ignore/livestreaming/index.html new file mode 100644 index 0000000..77e8599 --- /dev/null +++ b/branch/ignore/livestreaming/index.html @@ -0,0 +1,273 @@ + + + + + + + Livestreaming — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Livestreaming

+

In a large lecture, in effect, you don’t interact with most people - +not even close. Yet, trying to force this limited interaction greatly +limits our possible reach, and keeps us in an awkward state of +expecting live interaction yet usually receiving minimal. When we try +this online, it forces a closed

+

Teaching via livestreaming allows us to:

+
    +
  • Reach a near-unlimited number of people

  • +
  • Fully embrace online tools for interaction, instead of asking people +to speak up. This equalizes the participation for shy or passive +participants.

  • +
  • By being large, be more efficient and use the extra resources for +meaningful interactions in small groups.

  • +
+
+

Primary articles

+ +
+
+

Summary

+
    +
  • There are actually three levels here.

    +
      +
    • In-person

    • +
    • Online meeting

    • +
    • Online livestream

    • +
    +
  • +
+
+https://coderefinery.github.io/manuals/_images/mooc-diagram.png +
+

The general presence and information flow within the MOOC strategy.

+
+
+
    +
  • CodeRefinery livestreams via Twitch, but Twitch is not an essential +aspect.

  • +
  • We can invite anyone in the world, no risk of disruptions from +trolls.

  • +
  • This has enabled us to fully embrace strategies such as HackMD and +co-teaching.

    +
      +
    • While we tried these in-person, they didn’t work well since the +loud, extroverted people would dominate.

    • +
    +
  • +
+
+

Tech details

+
    +
  • We stream by using OBS to capture a Zoom meeting. We can switch +between a gallery view, screenshare, and mixed.

  • +
  • Dedicated instructor Zoom meeting - no learners. Thus, no chance of +privacy violations.

    +
      +
    • Learners can attend different ways: a) independently online b) +in-person breakout room c) Zoom breakout rooms.

    • +
    +
  • +
  • We don’t have time to get into details here… see the linked +documents and also join us for in-person experience while we improve +our materials more.

  • +
+
+
+
+

Exercises

+
+

(advanced) Set up and install OBS as a livestreaming tool.

+

This exercise is open-ended.

+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/objects.inv b/branch/ignore/objects.inv new file mode 100644 index 0000000..e6a41e7 Binary files /dev/null and b/branch/ignore/objects.inv differ diff --git a/branch/ignore/other-resources/index.html b/branch/ignore/other-resources/index.html new file mode 100644 index 0000000..598c821 --- /dev/null +++ b/branch/ignore/other-resources/index.html @@ -0,0 +1,206 @@ + + + + + + + Other resources — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Other resources

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/placeholder/index.html b/branch/ignore/placeholder/index.html new file mode 100644 index 0000000..a7b9aaa --- /dev/null +++ b/branch/ignore/placeholder/index.html @@ -0,0 +1,183 @@ + + + + + + + Placeholder — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/branch/ignore/preparation/index.html b/branch/ignore/preparation/index.html new file mode 100644 index 0000000..9275618 --- /dev/null +++ b/branch/ignore/preparation/index.html @@ -0,0 +1,228 @@ + + + + + + + Pre-workshop preparation — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Pre-workshop preparation

+

These things will help you get the most out of this workshop, by +giving you a broad overview at the beginning that you might only get +later on in the lesson.

+

Don’t worry if you don’t have time to do everything here. The most +important ones are listed first.

+
+

Read “How to help someone use a computer” (5 min)

+

How to help someone use a computer, by Phil +Agre. +Summary: Most of our teaching challenge is helping people to overcome bad user +interface design.

+
+
+

Browse a CodeRefinery lesson (5 min)

+

Please take 5 minutes and go through a CodeRefinery +lesson and understand the general +layout. Don’t go in-depth to any of the material (unless you want, +obviously). We would recommend +git-intro if you don’t +have a preference.

+
+
+

(optional) Watch “The future of teaching” (35 min content only, 45 min with Q&A, or 15 min reading)

+

The “The Future of Teaching” talk is a summary of many things in this +course. You could watch it as a preparation (or if you are reading on +your own, as a summary). This is low priority, since we will cover +most of these things in the course itself. +Watch it on YouTube +or read it if you prefer.

+
+
+

(optional) Read “The science of learning” (20 min)

+

Read this short paper The Science of +Learning +which provides a brief overview of some key evidence-based results in +teaching. This paper is also used by The +Carpentries for their Instructor Training +workshops.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/search/index.html b/branch/ignore/search/index.html new file mode 100644 index 0000000..752edd2 --- /dev/null +++ b/branch/ignore/search/index.html @@ -0,0 +1,195 @@ + + + + + + Search — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2020-, The contributors.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/branch/ignore/searchindex.js b/branch/ignore/searchindex.js new file mode 100644 index 0000000..33fd2cc --- /dev/null +++ b/branch/ignore/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["02-teaching-philosophies", "03-teaching-style", "about-coderefinery", "backward-lesson-design", "collaboration-models", "distributed", "diversity-and-inclusion", "exercises", "future", "guide", "hackmd", "index", "instructor-tech-setup", "lessons-with-version-control", "livestreaming", "other-resources", "placeholder", "preparation", "teaching-online", "teaching-practice", "teaching-strategies", "team-teaching", "teams", "video-editing", "video-recording", "welcome", "why-are-computers-hard", "why-teach-together", "workshop-roles", "workshops-online"], "filenames": ["02-teaching-philosophies.md", "03-teaching-style.md", "about-coderefinery.md", "backward-lesson-design.md", "collaboration-models.rst", "distributed.md", "diversity-and-inclusion.rst", "exercises.rst", "future.md", "guide.rst", "hackmd.rst", "index.rst", "instructor-tech-setup.md", "lessons-with-version-control.md", "livestreaming.rst", "other-resources.md", "placeholder.rst", "preparation.md", "teaching-online.md", "teaching-practice.md", "teaching-strategies.md", "team-teaching.rst", "teams.rst", "video-editing.rst", "video-recording.md", "welcome.md", "why-are-computers-hard.rst", "why-teach-together.rst", "workshop-roles.rst", "workshops-online.md"], "titles": ["CodeRefinery teaching philosophies", "Interactive teaching style", "About the CodeRefinery project and CodeRefinery workshops", "Backwards lesson design", "Collaboration models", "Distributed workshop organization", "Diversity and inclusion", "Exercise list", "Possibilities for Carpentries", "Instructor\u2019s guide", "HackMD", "Community teaching training", "Instructor tech setup", "Lesson development with version control", "Livestreaming", "Other resources", "Placeholder", "Pre-workshop preparation", "Teaching online", "Teaching practice and feedback", "How to teach online", "Team teaching", "Teams", "Video editing", "Video recording", "Welcome and introduction", "Why are computers hard?", "Why teach together?", "Workshop roles", "Running a workshop: online"], "terms": {"share": [0, 1, 2, 3, 5, 7, 10, 11, 13, 19, 23, 24, 25], "your": [0, 1, 3, 8, 11, 17, 19, 20, 22, 24, 27], "approach": [0, 2, 4, 7, 11], "pleas": [0, 7, 17, 19], "trick": [0, 4, 7, 29], "solut": 0, "live": [0, 1, 4, 5, 7, 14, 24, 25], "document": [0, 2, 3, 7, 10, 12, 13, 14, 15, 19, 24, 29], "other": [0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 12, 13, 18, 19, 20, 21, 22, 23, 25, 27], "addit": [0, 1, 3, 5, 7], "question": [0, 1, 2, 3, 7, 10, 18, 19, 21, 22, 28, 29], "what": [0, 2, 3, 4, 6, 8, 12, 13, 15, 19, 29], "i": [0, 1, 2, 3, 6, 7, 8, 9, 10, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 25, 26, 27, 29], "motiv": [0, 5, 6, 7, 12, 29], "take": [0, 1, 3, 6, 7, 8, 17, 19, 20, 21, 23, 24, 29], "thi": [0, 2, 3, 5, 6, 9, 10, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 24, 27, 29], "train": [0, 1, 2, 3, 4, 6, 7, 8, 15, 17, 21, 23, 28], "how": [0, 2, 3, 9, 10, 11, 15, 19, 25, 27, 29], "structur": [0, 7], "inform": [0, 1, 3, 7, 10, 12, 14, 20, 22, 23, 25, 28, 29], "ar": [0, 2, 3, 5, 6, 8, 10, 11, 12, 13, 14, 15, 17, 20, 21, 22, 23, 24, 25, 27, 28, 29], "own": [0, 1, 2, 3, 8, 11, 17, 22, 24, 27], "need": [0, 1, 2, 3, 5, 7, 8, 12, 20, 21, 22, 23, 24, 25, 27, 29], "differ": [0, 1, 2, 3, 5, 6, 7, 10, 11, 12, 13, 14, 19, 20, 21, 22, 24, 28, 29], "do": [0, 1, 2, 3, 5, 10, 11, 12, 17, 20, 21, 23, 24, 26, 29], "you": [0, 1, 3, 4, 7, 10, 11, 12, 13, 14, 15, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "notic": [0, 7, 19, 23, 25], "between": [0, 1, 3, 6, 7, 14, 20, 21, 29], "we": [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 13, 14, 17, 18, 19, 20, 23, 28, 29], "also": [0, 1, 2, 4, 5, 7, 8, 11, 14, 17, 19, 24, 25, 29], "carpentri": [0, 6, 7, 11, 13, 15, 17], "tradit": [0, 7], "academ": [0, 2, 7], "skill": [0, 1, 3, 7, 21, 22], "taught": [0, 1, 4, 7, 27, 29], "isn": [0, 7, 10, 13, 25], "t": [0, 1, 3, 7, 8, 10, 11, 13, 14, 17, 18, 20, 21, 22, 23, 24, 25, 27, 29], "right": [0, 7, 10, 12, 13, 18, 23, 27, 29], "set": [0, 1, 20, 22, 29], "here": [0, 1, 7, 10, 14, 17, 18, 23, 29], "instructor": [0, 2, 3, 4, 5, 6, 8, 10, 11, 13, 14, 15, 17, 20, 21, 24, 27, 28, 29], "show": [0, 2, 3, 7, 12, 19, 20], "all": [0, 1, 2, 3, 5, 7, 12, 18, 19, 22, 23, 24, 29], "have": [0, 1, 2, 3, 4, 5, 8, 10, 13, 14, 17, 19, 20, 21, 22, 23, 25, 28, 29], "style": [0, 2, 11], "benefici": 0, "workshop": [0, 1, 3, 4, 6, 8, 10, 18, 19, 20, 22, 23, 24], "It": [0, 1, 2, 3, 7, 10, 13, 19, 20, 23, 25, 27, 29], "import": [0, 3, 7, 10, 12, 13, 17, 20, 23, 25, 28, 29], "explain": [0, 1, 2, 3, 7, 20], "much": [0, 1, 3, 5, 7, 10, 11, 12, 18, 20, 21, 22, 23, 27, 29], "valu": [0, 27], "individu": [0, 1, 8], "one": [0, 1, 3, 7, 10, 12, 19, 20, 21, 22, 23, 24, 25, 29], "wai": [0, 3, 6, 7, 11, 14, 18, 20, 21, 23, 26, 29], "mani": [0, 1, 3, 5, 8, 12, 13, 17, 18, 20, 21, 24, 25, 26, 27, 29], "want": [0, 1, 2, 3, 4, 5, 7, 8, 10, 12, 13, 17, 19, 20, 22, 23, 24, 29], "help": [0, 1, 3, 4, 5, 6, 7, 8, 10, 15, 22, 23, 24, 25, 27, 29], "each": [0, 1, 3, 4, 5, 7, 11, 12, 18, 19, 20, 21, 22, 23, 25, 26, 28, 29], "find": [0, 7, 10, 12, 23, 27, 29], "best": [0, 1, 3, 7, 11, 12, 22, 25, 27], "u": [0, 1, 2, 5, 7, 8, 11, 13, 14, 19, 23, 24, 25, 27], "recent": [0, 3, 20], "some": [0, 1, 3, 4, 6, 7, 11, 12, 13, 15, 17, 18, 19, 20, 23, 24, 25, 28, 29], "below": [0, 1, 24, 29], "http": [0, 2, 4, 6, 7, 10, 12, 13, 14, 18, 21, 22, 23, 24, 26, 28, 29], "www": [0, 6, 7, 23, 26], "youtub": [0, 6, 7, 15, 17, 23], "com": [0, 6, 7, 13, 23, 29], "playlist": [0, 7, 23], "list": [0, 11, 12, 17, 23, 27, 28], "plplblyhczjaahf89p": 0, "gcjexwc8cf": 0, "7nhx": 0, "regularli": [0, 7], "so": [0, 1, 3, 5, 7, 8, 9, 11, 12, 13, 19, 20, 21, 22, 23, 25, 27, 29], "try": [0, 1, 3, 4, 5, 7, 11, 13, 14, 20, 22, 23, 29], "appli": [0, 1, 2, 3, 7, 8, 13, 20, 23, 25], "learnt": [0, 7, 25], "howev": [0, 1, 7, 21], "know": [0, 1, 2, 3, 7, 11, 20, 22, 24, 25], "our": [0, 1, 2, 5, 6, 7, 8, 11, 13, 14, 15, 17, 19, 21, 22, 23, 24, 25, 26, 27, 29], "target": [0, 1, 3, 7], "audienc": [0, 1, 3, 5, 7, 10, 12, 21, 23, 24, 26, 27, 29], "veri": [0, 1, 2, 3, 6, 7, 13, 20, 21, 23, 27, 29], "adapt": [0, 1, 7, 11, 26], "my": [0, 3, 7], "am": [0, 3, 7], "still": [0, 1, 3, 4, 7, 8, 13, 27, 29], "work": [0, 2, 3, 7, 11, 12, 13, 14, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29], "which": [0, 1, 3, 5, 7, 12, 13, 17, 18, 19, 20, 23, 25, 27, 29], "situat": [0, 1, 7, 12, 21], "why": [0, 1, 3, 9, 11, 25, 29], "like": [0, 1, 3, 4, 7, 11, 13, 19, 20, 23], "usual": [0, 1, 2, 3, 6, 7, 12, 14, 18, 21, 26, 27, 28, 29], "wider": [0, 7], "rang": [0, 7], "mix": [0, 7, 14, 21], "background": [0, 3, 6, 7, 9], "more": [0, 1, 2, 3, 5, 6, 8, 10, 11, 13, 14, 15, 18, 19, 20, 21, 22, 25, 26, 27, 29], "care": [0, 7, 11, 27], "pace": [0, 1, 7], "time": [0, 1, 3, 4, 5, 7, 11, 12, 14, 17, 20, 21, 23, 26], "given": [0, 1, 2, 5, 7], "exercis": [0, 2, 5, 8, 11, 20, 29], "consider": [0, 7], "spend": [0, 7, 11, 12], "quit": [0, 1, 6, 7, 22], "lot": [0, 7, 20, 22, 28], "read": [0, 1, 6, 7, 12, 15, 24], "materi": [0, 2, 3, 4, 7, 11, 13, 14, 17, 27], "practis": [0, 1, 7], "myself": [0, 7], "particularli": [0, 7], "note": [0, 1, 7, 10, 12, 20, 25], "just": [0, 3, 7, 20, 21, 23, 29], "befor": [0, 1, 4, 7, 11, 12, 13, 23, 28, 29], "thei": [0, 1, 2, 3, 5, 7, 10, 11, 14, 20, 22, 23, 24, 26, 29], "highlight": [0, 1, 7, 19, 22], "aspect": [0, 2, 3, 7, 14, 19], "both": [0, 1, 7, 19, 20, 27, 28], "prepar": [0, 1, 4, 7, 20, 21, 24, 27], "too": [0, 1, 2, 3, 7, 11, 12, 20, 22, 23, 24, 27, 29], "advanc": [0, 1, 12, 20], "think": [0, 1, 3, 7, 18, 20, 26, 27], "prevent": [0, 7, 25], "ask": [0, 1, 2, 3, 7, 14, 19, 20, 21, 25, 29], "If": [0, 4, 5, 7, 11, 13, 20, 23, 24, 25, 27], "less": [0, 1, 3, 7, 20, 21, 25, 27, 29], "compet": [0, 7], "practition": [0, 7], "classroom": [0, 1, 7, 21, 25], "can": [0, 1, 2, 3, 4, 5, 9, 10, 11, 12, 13, 14, 19, 20, 21, 22, 23, 24, 25, 27, 29], "easili": [0, 1, 5, 7], "copi": [0, 3, 7, 20, 23], "past": [0, 2, 7, 10, 23], "avoid": [0, 2, 3, 7, 9, 19, 27, 29], "slow": [0, 1, 7, 20, 23], "down": [0, 1, 7, 19, 20], "entir": [0, 1, 6, 7, 12], "ideal": [0, 7], "d": [0, 6, 7], "give": [0, 2, 3, 8, 17, 19, 20, 21, 29], "sever": [0, 2, 4, 6, 7, 20, 23], "anyon": [0, 1, 4, 7, 14, 23], "its": [0, 1, 2, 7, 10, 11, 13, 23], "everybodi": [0, 1, 7, 25], "get": [0, 2, 3, 12, 13, 14, 17, 19, 20, 22, 24, 27, 29], "someth": [0, 1, 3, 7, 11, 12, 20, 23, 25, 26], "from": [0, 1, 2, 3, 4, 6, 7, 11, 12, 14, 15, 20, 22, 23, 24, 25, 27, 29], "love": [0, 2, 7], "break": [0, 1, 7, 20, 23, 25, 29], "an": [0, 1, 2, 4, 5, 7, 8, 9, 12, 13, 14, 18, 21, 23, 24, 29], "opportun": [0, 2, 3, 7, 12, 18], "discuss": [0, 1, 3, 7, 12, 13, 18], "attende": [0, 7, 22], "research": [0, 1, 2, 3, 6, 7, 11], "topic": [0, 1, 4, 6, 15, 19, 20, 21, 23, 25], "especi": [0, 1, 3, 7, 13, 23, 24, 25], "interest": [0, 3, 4, 7, 8, 10, 11, 19, 20, 27], "understand": [0, 1, 2, 3, 7, 13, 17, 20, 26, 27], "softwar": [0, 1, 3, 7, 11, 14, 29], "write": [0, 2, 3, 7, 19], "plan": [0, 2, 3, 4, 7, 9, 11, 20, 21, 28, 29], "us": [0, 2, 3, 4, 8, 10, 11, 12, 13, 14, 15, 18, 19, 20, 22, 24, 25, 27, 28, 29], "learn": [0, 2, 3, 6, 7, 11, 15, 19, 20, 21, 22, 23, 25, 26, 28, 29], "dure": [0, 1, 3, 4, 5, 6, 7, 10, 19, 21, 22, 28, 29], "ha": [0, 1, 2, 3, 7, 11, 14, 20, 21, 29], "chang": [0, 1, 7, 13, 19, 27], "bit": [0, 1, 3, 7, 13, 22, 29], "sinc": [0, 7, 11, 14, 17, 19, 21, 23, 24, 25, 29], "start": [0, 1, 2, 3, 7, 11, 12, 13, 20, 23, 25, 29], "In": [0, 1, 2, 3, 5, 7, 9, 11, 14, 18, 19, 20, 21, 24, 29], "begin": [0, 7, 10, 17, 23], "had": [0, 2, 3, 7, 29], "blob": [0, 7], "binari": [0, 7], "larg": [0, 1, 4, 7, 10, 14, 20, 22, 24, 25, 27, 29], "object": [0, 7, 24], "knowledg": [0, 2, 3, 7, 25], "experi": [0, 1, 2, 3, 4, 5, 7, 12, 14, 20, 29], "convei": [0, 7], "particip": [0, 2, 4, 7, 12, 14, 19, 23, 24, 25, 29], "With": [0, 7, 20], "realiz": [0, 7], "serial": [0, 3, 7], "abl": [0, 1, 3, 7, 11, 13, 21, 23, 26, 29], "similar": [0, 1, 15, 20, 22, 23], "fashion": [0, 7], "would": [0, 1, 2, 3, 4, 7, 9, 10, 11, 14, 17, 19, 22, 24, 26, 27], "intend": [0, 1, 2, 7], "send": [0, 7, 8, 13, 29], "over": [0, 4, 7, 11, 20, 23, 29], "wire": [0, 7], "stop": [0, 7, 23], "signal": [0, 7, 13], "check": [0, 1, 3, 7, 13, 19, 23], "sum": [0, 7], "re": [0, 5, 7, 11, 22, 23], "transmiss": [0, 7], "when": [0, 1, 3, 6, 7, 10, 14, 20, 22, 23, 24, 26, 29], "lectur": [0, 7, 14, 20, 21, 29], "come": [0, 1, 3, 7, 20, 22, 23, 24, 29], "appreci": [0, 7], "natur": [0, 7, 22], "period": [0, 5, 7], "lesson": [0, 1, 2, 4, 9, 12, 19, 20, 21, 23, 28, 29], "offer": [0, 7], "rais": [0, 2, 7, 29], "error": [0, 1, 7, 12], "appear": [0, 7, 23, 24, 29], "type": [0, 1, 3, 7, 12, 20, 21], "along": [0, 1, 3, 7, 19, 20, 22, 23, 28], "co": [0, 5, 8, 10, 11, 14, 27, 28], "good": [0, 1, 2, 6, 7, 8, 12, 19, 21, 23, 24, 26, 29], "broaden": [0, 7], "specif": [0, 1, 2, 3, 7], "inclin": [0, 7], "wa": [0, 1, 2, 3, 4, 7, 9, 19, 23, 29], "todai": [0, 7], "guid": [0, 1, 7, 11, 13, 20, 21, 25, 28, 29], "includ": [0, 1, 7, 9, 19, 23, 29], "me": [0, 7], "well": [0, 1, 5, 7, 14, 25, 29], "That": [0, 1, 7], "mai": [0, 1, 3, 7, 22, 23, 25, 27], "sound": [0, 1, 7], "self": [0, 7, 22, 25], "centric": [0, 7], "fact": [0, 1, 3, 7, 22], "opposit": [0, 7], "sensit": [0, 7], "go": [0, 1, 3, 7, 10, 17, 20, 23, 25, 29], "room": [0, 1, 3, 4, 5, 7, 8, 14, 20, 22, 23, 24, 28], "The": [0, 2, 7, 10, 11, 13, 14, 15, 18, 19, 20, 21, 22, 23, 25, 26, 29], "consciou": [0, 7], "being": [0, 7, 10, 14, 22], "better": [0, 2, 3, 7, 8, 18, 19, 20, 21], "tool": [0, 1, 2, 3, 6, 8, 10, 18, 23, 26], "concept": [0, 1, 7, 10, 20, 21], "map": [0, 7], "learner": [0, 2, 3, 5, 10, 11, 12, 14, 20, 21, 22, 23, 24, 28, 29], "persona": [0, 3, 7, 11], "though": [0, 2, 3, 7], "develop": [0, 2, 3, 5, 9, 15, 27], "few": [0, 1, 3, 5, 7, 12, 19, 20, 23, 24], "them": [0, 1, 2, 3, 5, 7, 9, 11, 13, 19, 22, 29], "never": [0, 1, 3, 7, 23, 29], "leav": [0, 7, 23, 24], "ani": [0, 1, 2, 3, 4, 7, 8, 13, 17, 20, 21, 23, 25, 29], "behind": [0, 7], "realli": [0, 3, 7, 29], "don": [0, 1, 3, 7, 13, 14, 17, 20, 21, 22, 23, 24, 25, 27, 29], "see": [0, 1, 5, 7, 8, 9, 14, 24, 29], "confus": [0, 7, 25], "blank": [0, 7], "face": [0, 7], "At": [0, 7], "same": [0, 1, 3, 7, 11, 12, 13, 19, 20, 21, 22, 23, 27, 28, 29], "sometim": [0, 7, 28], "worri": [0, 7, 17, 20], "about": [0, 1, 3, 7, 10, 11, 13, 15, 20, 23, 24, 25, 27, 29], "bore": [0, 7], "progress": [0, 3, 5, 7, 8], "slowli": [0, 1, 7, 12], "alwai": [0, 3, 7, 20, 24, 28], "difficult": [0, 1, 7, 24], "compromis": [0, 7], "struggl": [0, 7], "focu": [0, 1, 7, 8, 10, 20, 21], "make": [0, 1, 2, 3, 5, 7, 10, 11, 12, 13, 19, 20, 21, 22, 24, 26, 27, 28, 29], "intuit": [0, 7], "sens": [0, 2, 7], "Of": [0, 7, 26], "cours": [0, 1, 2, 3, 4, 5, 7, 9, 10, 14, 17, 18, 20, 21, 22, 23, 24, 27, 29], "base": [0, 1, 2, 3, 7, 13, 15, 17, 20, 22, 23], "establish": [0, 1, 2, 7], "connect": [0, 1, 6, 7], "thing": [0, 3, 4, 7, 11, 13, 17, 20, 21, 23, 25, 26, 27, 29], "saw": [0, 7], "previou": [0, 7, 11], "where": [0, 1, 3, 7, 10, 20, 23, 25], "x": [0, 3, 7], "master": [0, 3, 7], "follow": [0, 1, 3, 7, 12, 13, 19, 20, 22, 23, 25, 26], "script": [0, 1, 2, 3, 7], "after": [0, 1, 2, 4, 7, 8, 10, 22, 23, 24], "becom": [0, 1, 2, 3, 7, 8, 11, 20, 23], "familiar": [0, 3, 7, 29], "improvis": [0, 7], "react": [0, 7, 21], "dynam": [0, 3, 7], "e": [0, 1, 2, 6, 7, 23], "g": [0, 7, 23], "detour": [0, 7], "clearli": [0, 1, 2, 7, 20, 23, 29], "often": [0, 1, 2, 3, 6, 7, 20, 21, 22, 25, 28], "code": [0, 1, 2, 3, 7, 23], "text": [0, 7, 13, 23, 26], "out": [0, 1, 2, 3, 7, 8, 11, 13, 17, 20, 22, 23, 27, 29], "describ": [0, 1, 3, 7, 13], "slower": [0, 1, 7, 29], "place": [0, 1, 4, 5, 7, 23, 29], "hopefulli": [0, 7], "compens": [0, 7, 18], "A": [0, 1, 2, 3, 4, 5, 7, 10, 13, 15, 20, 22], "convers": [0, 7], "trainer": [0, 7], "traine": [0, 7], "engag": [0, 3, 7, 8, 10, 27], "For": [0, 1, 3, 7, 9, 13, 18, 22, 23, 24, 25], "reason": [0, 1, 3, 7, 13, 26, 29], "most": [0, 1, 3, 6, 7, 11, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 26, 29], "finish": [0, 7], "part": [0, 1, 4, 7, 11, 20, 21, 23, 25], "step": [0, 1, 7, 8, 20, 23, 29], "back": [0, 1, 7, 10, 13, 23, 24, 29], "might": [0, 1, 7, 17, 23, 24, 27], "bring": [0, 1, 7, 20, 22], "anoth": [0, 3, 5, 7, 10, 12, 21], "point": [0, 1, 3, 7, 19, 20, 22, 23, 26], "throughout": [0, 7], "answer": [0, 2, 3, 7, 10, 20, 21, 25, 27, 29], "practic": [0, 1, 11, 12, 13, 21, 25, 29], "yourself": [0, 7, 20], "those": [0, 1, 7, 8, 21], "seem": [0, 1, 7, 13, 21], "open": [0, 2, 4, 7, 10, 11, 12, 13, 14, 27], "end": [0, 1, 3, 7, 14, 20, 23], "new": [0, 2, 3, 7, 8, 11, 13, 18, 19, 20, 21, 23, 27, 29], "exampl": [0, 1, 2, 7, 9, 10, 11, 20, 23, 25], "person": [0, 1, 4, 5, 7, 10, 11, 14, 18, 19, 20, 21, 25, 28], "last": [0, 7, 13, 27], "analogi": [0, 1, 7], "order": [0, 1, 3, 7, 19, 24], "simplifi": [0, 1, 7, 26], "convolut": [0, 7], "180": [0, 7, 29], "degre": [0, 7, 11], "slide": [0, 7], "45": [0, 7, 15, 23], "block": [0, 7, 23], "separ": [0, 7, 20, 23, 24], "session": [0, 1, 2, 5, 7, 10, 11, 12, 19, 20, 23, 25, 29], "embrac": [0, 2, 7, 14], "interact": [0, 4, 10, 11, 14, 18, 20, 21, 22, 23, 24, 25, 27, 29], "demo": [0, 1, 7, 20, 21, 23], "typo": [0, 7], "goal": [0, 3, 7, 19], "spark": [0, 7], "curios": [0, 7], "novic": [0, 7], "look": [0, 1, 7, 12, 20, 23, 24], "experienc": [0, 3, 4, 7], "aha": [0, 7], "did": [0, 1, 7, 29], "could": [0, 1, 4, 7, 10, 11, 13, 17, 22, 23, 24], "wonder": [0, 7], "whether": [0, 1, 7, 19, 23], "becaus": [0, 1, 2, 3, 7, 23, 29], "up": [0, 1, 2, 3, 4, 19, 20, 21, 22, 23, 24, 29], "browser": [0, 7, 12], "keep": [0, 1, 2, 3, 7, 10, 14, 20, 29], "expert": [0, 5, 7, 28, 29], "sign": [0, 1, 7, 22], "encourag": [0, 1, 7, 22], "But": [0, 1, 7, 10, 20, 22, 25, 27], "rabbit": [0, 7], "hole": [0, 7], "onli": [0, 1, 5, 7, 13, 15, 19, 20, 23, 24, 25, 29], "jargon": [0, 7], "war": [0, 7], "stori": [0, 7], "profession": [0, 7, 11], "perspect": [0, 7], "busi": [0, 7], "world": [0, 1, 4, 7, 14, 25], "relat": [0, 1, 7, 18, 26], "context": [0, 1, 3, 6, 7], "custom": [0, 7, 13, 29], "product": [0, 7], "agil": [0, 7], "hard": [0, 1, 6, 11, 23], "clear": [0, 3, 7, 20, 23, 29], "than": [0, 1, 3, 7, 10, 11, 13, 18, 20, 21, 23, 26, 27, 29], "unclear": [0, 7], "simpl": [0, 1, 3, 7, 23, 24, 29], "complic": [0, 7], "almost": [0, 3, 7, 11, 12, 20, 22, 26], "felt": [0, 7], "got": [0, 7, 11, 25], "feedback": [0, 2, 11, 12, 13, 20, 21, 29], "repeat": [0, 1, 7], "head": [0, 7], "word": [0, 1, 3, 7, 23], "simpli": [0, 1, 7], "easi": [0, 7, 12, 20, 24, 26, 29], "home": [0, 7], "two": [0, 1, 2, 3, 4, 7, 12, 20, 21, 22, 23, 27, 29], "": [0, 3, 7, 11, 13, 18, 19, 20, 21, 23, 25, 26, 27, 29], "success": [0, 3], "issu": [0, 3, 7, 13], "pull": [0, 7, 13, 23], "request": [0, 1, 7, 13, 22], "solv": [0, 1, 2, 3, 7, 24], "surpris": [0, 6, 7], "known": [0, 2, 7, 9, 29], "precis": [0, 7, 20], "next": [0, 2, 7, 20, 23, 29], "episod": [0, 1, 3, 7, 20, 23, 29], "allow": [0, 1, 3, 7, 13, 14, 20, 22, 23, 29], "skip": [0, 1, 7], "distil": [0, 7], "essenc": [0, 7], "bullet": [0, 7], "deviat": [0, 7], "explicit": [0, 7, 22], "great": [0, 4, 5, 7, 20, 21, 24, 25], "recommend": [0, 9, 17, 29], "watch": [0, 1, 4, 5, 6, 7, 10, 12, 15, 19, 20, 21, 22, 23, 24, 28, 29], "tutori": [0, 7, 25], "program": [0, 1, 2, 3, 7, 11, 15], "languag": [0, 2, 3, 7], "feel": [0, 1, 7, 10, 19], "overwhelm": [0, 7, 10, 29], "fast": [0, 1, 7, 23, 27, 29], "thrown": [0, 7], "somebodi": [0, 7, 13], "els": [0, 7, 12, 22, 23, 26, 29], "who": [0, 3, 4, 7, 8, 22, 23, 25, 29], "detect": [0, 7], "complement": [0, 7, 21], "interrupt": [0, 7, 20], "flow": [0, 7, 14, 20, 28], "mistak": [0, 7, 23, 24, 26], "mind": [0, 1, 7, 20, 21], "forc": [0, 7, 14], "fun": [0, 7, 29], "demystifi": [0, 7], "onc": [0, 3, 7, 26, 29], "mysteri": [0, 7], "anymor": [0, 7, 29], "mean": [0, 7, 21, 23, 28], "futur": [0, 1, 2, 7, 15, 23], "real": [0, 1, 7, 23], "life": [0, 7], "twist": [0, 7], "humour": [0, 7], "whenev": [0, 2, 7], "possibl": [0, 1, 2, 7, 11, 12, 13, 14, 20, 24, 29], "outcom": [0, 1, 3, 7], "certain": [0, 7, 29], "offens": [0, 7], "diagram": [0, 7], "spent": [0, 7], "week": [0, 7, 29], "creat": [0, 1, 3, 22, 24], "three": [0, 1, 3, 7, 14, 21, 29], "four": [0, 7, 23], "sentenc": [0, 7, 23], "effort": [0, 1, 4, 7, 11, 24, 27], "consid": [0, 7, 13, 22], "worthwhil": [0, 7], "intent": [0, 7], "achiev": [0, 1, 7], "nitti": [0, 7], "gritti": [0, 7], "confid": [0, 1, 2, 7], "case": [0, 1, 3, 7, 24], "gradual": [0, 7, 15], "realis": [0, 7], "hint": [0, 7, 14, 20, 23], "perhap": [0, 7, 10, 23, 24, 25], "assum": [0, 1, 2, 7, 20, 26], "commun": [0, 2, 3, 7, 13, 25, 27, 28, 29], "class": [0, 1, 7, 12, 20], "now": [0, 3, 4, 7, 13, 15, 18, 20, 22, 23], "rememb": [0, 1, 3, 7, 23], "observ": [0, 5, 7, 8, 10], "peopl": [0, 1, 2, 4, 5, 6, 8, 10, 12, 14, 15, 17, 18, 20, 22, 23, 24, 25, 26, 27, 29], "puzzl": [0, 7], "while": [0, 1, 5, 7, 12, 14, 20, 23, 29], "obviou": [0, 7, 20, 23, 29], "believ": [0, 1, 7, 18], "helper": [0, 5, 7, 8, 10, 15, 20, 22, 25, 27, 28], "faster": [0, 7, 20, 29], "least": [0, 1, 7, 13, 29], "sure": [0, 1, 7, 20, 23, 24, 29], "sit": [0, 7, 22], "alon": [0, 7, 11, 22, 25, 27], "ve": [0, 7, 11, 26, 29], "been": [0, 1, 3, 7, 11, 21, 23, 29], "rare": [0, 7], "teacher": [0, 1, 7, 21, 25, 26, 27, 28], "tend": [0, 7], "mentorship": [0, 6, 7], "long": [0, 1, 7, 9, 13, 20, 23, 24, 29], "ago": [0, 2, 3, 7], "weren": [0, 7], "combin": [0, 4, 7, 27, 29], "done": [0, 1, 7, 22, 23, 27], "friend": [0, 7], "independ": [0, 2, 3, 5, 7, 11, 14, 21, 25, 27], "studi": [0, 1, 6, 7], "correct": [0, 1, 7], "main": [0, 3, 7, 20, 22, 23, 29], "job": [0, 1, 3, 25], "support": [0, 2, 3, 7, 10, 28], "comput": [0, 1, 2, 3, 6, 11, 15, 23, 29], "infrastructur": [0, 2, 7, 11], "ground": [0, 7, 28], "problem": [0, 1, 2, 3, 7, 25, 29], "basic": [0, 3, 10, 20], "miss": [0, 1, 7, 20, 23, 24, 29], "off": [0, 7, 12, 18, 23, 24], "even": [0, 1, 3, 4, 7, 12, 14, 18, 21, 23], "should": [0, 1, 2, 3, 5, 6, 7, 13, 19, 20, 22, 23, 25, 29], "minim": [0, 7, 14, 20, 23, 27], "suffici": [0, 1, 2, 7], "everyth": [0, 1, 4, 7, 17, 20, 23, 25, 29], "perfectli": [0, 7, 21, 27], "technic": [0, 3, 6, 7], "twenti": [0, 7], "year": [0, 1, 2, 3, 4, 7], "henc": [0, 7], "toward": [0, 2, 7], "hand": [0, 2, 7, 11, 25, 29], "abil": [0, 6, 7, 26], "capabl": [0, 3, 7, 22], "team": [0, 3, 5, 8, 11, 20, 27, 28], "requir": [0, 3, 7, 10, 13, 19, 20, 27, 28, 29], "essenti": [0, 1, 7, 13, 14], "domain": [0, 1, 7], "willing": [0, 7], "stuck": [0, 7, 20], "call": [0, 1, 7, 10, 20], "ksa": [0, 7], "attitud": [0, 7], "impart": [0, 7], "And": [0, 7, 20, 23, 25], "challeng": [0, 1, 7, 15, 17, 21], "student": [0, 2, 3, 7, 10, 20, 21, 25, 27, 29], "overcom": [0, 7, 15, 17], "perceiv": [0, 7], "limit": [0, 3, 7, 13, 14, 20, 22, 29], "humanist": [0, 7], "python": [0, 7, 23, 29], "virtualenv": [0, 7], "cognit": [0, 7], "return": [0, 7], "There": [0, 1, 7, 12, 14, 20, 23], "compon": [0, 7], "storytel": [0, 7], "human": [0, 1, 7], "neurolog": [0, 7], "made": [0, 7, 22, 26, 28, 29], "pai": [0, 7], "attent": [0, 7, 10], "put": [0, 1, 4, 7, 29], "account": [0, 7, 19], "relev": [0, 1, 3, 5, 7, 11, 25, 27], "narr": [0, 7], "draw": [0, 7], "creativ": [0, 7], "handwrit": [0, 7], "reckon": [0, 7], "architectur": [0, 7], "big": [0, 7], "pictur": [0, 7, 20], "invest": [0, 7], "semant": [0, 7], "tree": [0, 7], "negoti": [1, 7], "minimum": [1, 3, 7, 13, 29], "minut": [1, 3, 12, 17, 19, 20, 29], "breakout": [1, 4, 5, 7, 8, 14, 19, 22, 23, 24, 28], "short": [1, 2, 5, 7, 17, 21, 23, 29], "expect": [1, 3, 7, 14, 20, 21, 23, 24, 26, 29], "intro": [1, 7, 9, 13, 14, 15, 17, 23, 29], "speed": [1, 2, 3, 7], "Not": [1, 7, 10], "accomplish": [1, 7, 20], "5": [1, 19, 20, 21, 22, 29], "stuff": [1, 2, 7], "wrong": [1, 7], "depend": [1, 7, 12, 23], "ok": [1, 7, 23], "cut": [1, 7, 23], "reserv": [1, 5, 7], "readi": [1, 3, 7, 23, 29], "run": [1, 3, 5, 8, 11, 20, 28], "environ": [1, 23, 25, 26], "match": [1, 7, 20, 21], "screen": [1, 3, 19, 23], "termin": [1, 7, 12], "histori": [1, 7, 20], "portion": [1, 7], "remot": [1, 3, 7, 23], "alreadi": [1, 2, 3, 4, 7], "prerequisit": [1, 7, 23], "Or": [1, 6, 7], "instal": [1, 3, 23], "configur": [1, 6, 7], "manag": [1, 7, 10, 22, 28, 29], "sad": [1, 7], "special": [1, 7, 10, 29], "deliv": [1, 5, 7], "onlin": [1, 2, 8, 11, 12, 13, 14, 21, 25], "organ": [1, 4, 7, 8, 18, 19, 21, 22, 28], "overview": [1, 2, 15, 17, 25, 28, 29], "complet": [1, 2, 25], "section": [1, 2, 3, 6, 7, 18, 19, 21, 23], "deriv": [1, 2], "further": [1, 9], "later": [1, 5, 7, 17, 19, 20, 23, 24, 29], "2": 1, "dai": [1, 7, 12, 22, 23, 27, 28, 29], "intructor": 1, "respect": 1, "inclus": [1, 11, 25], "reli": [1, 7, 21], "conduct": 1, "improv": [1, 2, 7, 11, 13, 14, 19, 29], "reinforc": 1, "daili": 1, "within": [1, 7, 12, 14, 21, 22, 23, 24], "15": [1, 7, 15, 23], "group": [1, 3, 6, 11, 14, 19, 20, 21, 22, 25], "method": [1, 3], "bi": [1, 8], "direct": [1, 2], "To": [1, 23, 29], "clarif": 1, "instanc": 1, "add": [1, 12, 24, 27], "through": [1, 2, 3, 7, 10, 17, 20, 22, 23], "contrast": [1, 29], "judg": 1, "reach": [1, 14], "accept": [1, 2, 29], "level": [1, 2, 3, 8, 14, 28], "either": [1, 3, 8, 11, 21, 22], "pass": [1, 13], "fail": [1, 12, 29], "One": [1, 2, 5, 20, 21, 22], "drive": 1, "exam": 1, "tell": 1, "rest": [1, 7, 18, 23], "societi": 1, "someon": [1, 3, 7, 13, 15, 20, 23, 25], "safe": 1, "road": 1, "univers": [1, 2, 5, 29], "assign": [1, 22, 29], "grade": 1, "fanci": 1, "term": [1, 9], "activ": [1, 2, 3, 7, 10, 21], "provid": [1, 2, 3, 5, 7, 8, 15, 17, 20, 23, 24, 25], "refocu": 1, "respond": [1, 7, 10], "continu": [1, 8, 11, 29], "mechan": [1, 10, 25, 29], "music": 1, "plai": 1, "scale": [1, 3, 4, 20, 21], "breath": 1, "correctli": 1, "happen": [1, 3, 4, 5, 22, 23, 24], "frequent": 1, "ll": 1, "talk": [1, 7, 13, 17, 23], "result": [1, 2, 4, 7, 15, 17, 23], "interpret": 1, "instrument": 1, "survei": [1, 2, 7], "pre": [1, 2, 11, 22, 29], "post": [1, 2], "poll": 1, "necessarili": 1, "multipl": [1, 20, 29], "choic": [1, 7, 13, 19, 23], "initi": [1, 4, 7, 23], "build": [1, 2, 13, 25], "exist": [1, 3, 5, 7], "uniqu": 1, "choos": [1, 3, 7, 21], "suitabl": [1, 27], "accommod": 1, "everyon": [1, 4, 7, 11, 22, 23], "posit": [1, 7], "v": [1, 7, 23, 24], "neg": [1, 7], "content": [1, 4, 7, 13, 15, 23, 29], "present": [1, 2, 4, 6, 7, 19, 20, 23, 27, 29], "rubric": [1, 7, 19], "aim": [1, 2, 7], "As": [1, 3, 7, 11, 18, 26, 28], "video": [1, 11, 19, 28, 29], "ax": [1, 7], "2x2": [1, 7], "grid": [1, 7], "whiteboard": [1, 7], "hackmd": [1, 4, 11, 13, 14, 18, 21, 23, 25, 27, 28], "etherpad": [1, 7], "googl": [1, 6, 7], "doc": [1, 6, 7], "without": [1, 7, 12, 13, 22], "duplic": [1, 7, 11, 27], "event": [1, 7, 22, 24, 27], "4": [1, 19], "per": [1, 4, 7, 22, 23, 29], "facilit": [1, 7], "Then": [1, 3, 7, 29], "report": [1, 7], "strongli": [1, 7, 22], "agre": [1, 7], "disagre": [1, 7], "first": [1, 3, 4, 7, 8, 13, 17, 23, 29], "task": [1, 3, 7, 19], "figur": [1, 3, 7, 29], "patricia": 1, "benner": 1, "dreyfu": 1, "acquisit": [1, 3], "her": [1, 3], "nurs": 1, "book": [1, 3, 15, 24], "indic": [1, 23], "formal": 1, "acquir": 1, "distinct": [1, 3], "stage": 1, "doesn": [1, 7, 10, 13, 20, 22, 29], "yet": [1, 2, 6, 7, 8, 14, 21, 22, 23, 26, 28], "idea": [1, 2, 3, 7, 8, 13, 20, 24], "aren": [1, 7, 11, 23, 27], "heard": 1, "bash": 1, "shell": [1, 3, 7, 19], "therefor": 1, "file": [1, 3, 13], "system": [1, 3, 6, 7, 13, 20, 22, 29], "execut": 1, "headless": 1, "mode": [1, 10, 23, 29], "queue": 1, "directli": [1, 7, 8, 18, 23, 24, 29], "login": [1, 3], "enough": [1, 3, 20, 22, 23, 25, 29], "everydai": 1, "purpos": [1, 20], "won": [1, 3, 7, 18, 23], "detail": 1, "accur": [1, 23], "normal": [1, 29], "under": [1, 13, 25, 28, 29], "circumst": [1, 11], "move": [1, 3, 21, 23], "around": [1, 4, 8, 29], "directori": [1, 7, 23], "fit": 1, "togeth": [1, 3, 4, 11, 15, 20, 22, 25, 29], "autom": 1, "he": [1, 3], "she": [1, 3], "benefit": [1, 5, 7, 20, 25, 27, 29], "doe": [1, 2, 7, 10, 12, 21, 29], "fulli": [1, 14], "project": [1, 3, 11, 13], "cluster": [1, 3], "submit": [1, 2, 3], "optim": 1, "amount": [1, 3, 4, 11, 28], "resourc": [1, 3, 11, 14, 25], "setup": [1, 11, 19, 20], "parallel": [1, 3, 10, 23, 27], "handl": [1, 29], "ordinari": 1, "immedi": [1, 7, 10, 23, 24, 29], "process": [1, 5, 7, 23], "goe": 1, "creation": 1, "found": 1, "collect": [1, 2, 7, 13, 20, 23, 25], "relationship": 1, "resid": 1, "unit": 1, "state": [1, 3, 14, 20], "locat": [1, 4, 22], "major": [1, 2, 6, 25], "citi": 1, "landmark": 1, "weather": 1, "pattern": 1, "region": 1, "economi": 1, "demograph": [1, 6], "among": [1, 6, 7, 12, 27, 28], "compar": [1, 4, 10, 12, 20, 29], "countri": [1, 2, 5, 29], "complex": [1, 3], "distinguish": 1, "built": [1, 26], "guesswork": 1, "borrow": 1, "piec": [1, 3, 24], "superfici": 1, "averag": [1, 4], "driver": 1, "car": 1, "probabl": [1, 2, 7, 19, 23], "engin": [1, 2, 13], "concern": 1, "mixtur": 1, "hardli": 1, "ever": 1, "scratch": [1, 24], "everi": [1, 12, 29], "opinion": 1, "true": [1, 13], "articul": [1, 2], "prior": [1, 2], "belief": 1, "incomplet": 1, "inaccur": 1, "misconcept": 1, "imped": 1, "incorpor": 1, "broadli": 1, "speak": [1, 14, 21, 23], "fall": [1, 7, 19], "categori": 1, "factual": 1, "vancouv": 1, "capit": 1, "british": 1, "columbia": 1, "These": [1, 2, 17, 23], "easiest": 1, "broken": 1, "motion": 1, "acceler": 1, "must": [1, 3, 7, 10, 20, 23], "address": [1, 2], "contradict": 1, "fundament": 1, "thousand": 1, "old": [1, 15, 20, 29], "beings": 1, "cannot": [1, 3], "affect": [1, 25], "planet": 1, "climat": [1, 3], "deepli": 1, "social": [1, 6], "ident": [1, 25], "hardest": 1, "current": [1, 3, 7, 8, 11, 13, 23, 27], "procedur": [1, 13], "inherit": 1, "lack": [1, 3], "depth": [1, 17], "leaner": [1, 7], "leasson": [1, 7], "wiggin": 1, "mctigh": 1, "firmli": 1, "determin": [1, 26], "decid": [1, 4], "constitut": 1, "evid": [1, 15, 17], "met": 1, "sort": 1, "increas": [1, 7, 10, 29], "capentri": 1, "framework": 1, "discret": [1, 2], "hierarch": 1, "gone": 1, "educ": [1, 3, 21], "remain": 1, "particular": [1, 3, 11, 21], "hierarchi": 1, "valid": [1, 7, 10, 13], "masteri": 1, "bottom": [1, 7, 21], "meet": [1, 4, 8, 14, 24, 29], "grow": [1, 13], "recogn": 1, "growth": 1, "ahead": 1, "imag": 1, "credit": [1, 8, 13], "vanderbilt": 1, "center": 1, "review": [1, 7, 10, 12, 23, 24], "carefulli": 1, "scan": [1, 7, 21], "promis": [1, 4], "verifi": [1, 29], "anticip": 1, "teach": [2, 3, 5, 6, 8, 9, 10, 12, 13, 14, 15, 23, 25], "intermedi": 2, "network": [2, 3, 8, 11, 25, 29], "publicli": 2, "fund": [2, 8], "3": [2, 10, 21, 29], "actual": [2, 7, 13, 14, 23, 29], "transit": [2, 22, 23], "nordic": [2, 4], "collabor": [2, 5, 8, 10, 11, 12, 13, 18, 19, 20, 25, 27], "neic": 2, "octob": 2, "2016": 2, "until": [2, 20], "februari": 2, "2025": 2, "2022": [2, 4, 8, 10], "design": [2, 8, 13, 15, 17, 19, 29], "beyond": 2, "form": [2, 3, 13, 22, 25], "contributor": [2, 8, 13], "grew": 2, "sese": 2, "kth": 2, "stockholm": 2, "2014": 2, "nu": 2, "scientif": [2, 7, 23, 29], "toolbox": 2, "propos": [2, 12], "2015": 2, "port": 2, "format": [2, 4, 7, 13, 19, 25, 28], "iter": [2, 27], "maintain": [2, 13, 27, 29], "disciplin": 2, "tri": [2, 3, 5, 14, 18], "repositori": [2, 29], "host": [2, 4, 13, 28, 29], "servic": [2, 8, 10], "free": 2, "institut": [2, 3, 8, 11, 29], "implement": [2, 22, 26], "sustain": [2, 8, 25], "measur": 2, "6": [2, 3, 29], "month": [2, 3], "attend": [2, 3, 7, 14, 23, 24, 25, 28, 29], "overal": [2, 3, 23], "qualiti": [2, 23], "reusabl": 2, "modular": 2, "reproduc": 2, "easier": [2, 10, 12, 20, 24, 27], "colleagu": [2, 3, 4, 7, 29], "usag": 2, "adopt": [2, 11], "suggest": [2, 3, 7, 13], "effect": [2, 14, 20, 21], "common": [2, 7, 10, 13, 21, 28], "theme": [2, 13], "wish": [2, 5], "grad": 2, "10": [2, 12, 23, 29], "quantifi": 2, "convinc": 2, "partner": [2, 5, 27], "theoret": 2, "gener": [2, 5, 8, 12, 14, 15, 17, 21, 25], "favor": 2, "awar": 2, "By": [2, 14, 23, 24], "qualifi": 2, "typic": [2, 3, 7, 12, 13, 19, 28, 29], "version": [2, 3, 4, 11], "control": [2, 11, 25], "git": [2, 9, 13, 17], "high": [2, 3, 4, 7, 23], "conceptu": 2, "jupyt": 2, "etc": [2, 3, 9, 12, 23, 28, 29], "difficulti": [2, 20, 22, 26, 27], "workflow": [2, 7, 13, 23], "defin": [2, 3, 5, 23, 29], "produc": [2, 7, 20, 23], "ship": 2, "far": [3, 27], "earlier": 3, "critic": [3, 6, 26], "widespread": 3, "number": [3, 10, 11, 14, 20, 21, 22, 25, 29], "cool": 3, "press": 3, "90": [3, 29], "instead": [3, 5, 7, 12, 14, 20, 23, 27, 29], "expos": 3, "technologi": [3, 6, 7, 26], "prefer": [3, 7, 12, 13, 15, 17, 19, 24], "divers": [3, 11, 25, 29], "reduc": [3, 11, 20, 27, 29], "bias": 3, "clarifi": 3, "concret": 3, "potenti": 3, "analyz": 3, "evalu": [3, 19], "sequenc": [3, 23], "test": [3, 11, 13], "increment": 3, "gap": 3, "tech": [3, 11, 15, 20], "brainstorm": [3, 7, 18], "rough": 3, "summ": 3, "assess": [3, 21], "coderefineri": [3, 10, 11, 12, 14, 15, 18, 20, 21, 22, 23, 24, 25, 28], "translat": [3, 7, 18, 23], "simpler": 3, "mayb": 3, "emphas": [3, 29], "let": [3, 20, 22, 23, 25, 27], "phd": 3, "postdoc": 3, "young": 3, "proper": 3, "definit": [3, 7, 23], "variou": [3, 20], "avail": [3, 4, 7, 20, 23, 25, 29], "paradigm": 3, "multi": [3, 29], "thread": [3, 20], "data": [3, 7, 23, 27], "box": 3, "multiprocess": 3, "gpu": 3, "dataset": 3, "larger": [3, 4, 13, 21], "memori": 3, "strategi": [3, 14, 18, 20, 27], "sonya": 3, "1st": 3, "oslo": 3, "join": [3, 11, 14, 29], "neurosci": 3, "nest": 3, "simul": [3, 7, 23], "spike": 3, "neural": 3, "model": [3, 5, 11, 21, 27], "thesi": 3, "small": [3, 4, 8, 12, 13, 14, 20, 27, 28], "excit": 3, "robert": 3, "field": [3, 22, 29], "ecologist": 3, "obtain": 3, "hi": 3, "scientist": 3, "consequ": 3, "global": 3, "command": [3, 7, 23], "line": [3, 7, 12, 23], "terrifi": 3, "extens": [3, 12, 13, 21, 27], "rather": 3, "jessica": 3, "investig": 3, "numer": 3, "aris": 3, "tip": [3, 20], "fluid": 3, "driven": 3, "ruptur": 3, "finit": 3, "element": 3, "compress": 3, "navier": 3, "stoke": 3, "equat": 3, "mesh": 3, "librari": 3, "mostli": [3, 29], "ran": 3, "local": [3, 4, 5, 7, 8, 13, 22, 27, 29], "desktop": 3, "due": 3, "keen": 3, "machin": 3, "notion": 3, "core": 3, "node": 3, "distribut": [3, 7, 11, 19], "schedul": [3, 4, 7, 23, 28], "appropri": 3, "optimis": 3, "o": [3, 6, 7, 23], "filesystem": 3, "access": [3, 6, 10, 11, 29], "oper": 3, "meant": 3, "cpu": 3, "laptop": [3, 12], "output": 3, "gromac": 3, "logic": [3, 7], "pick": [3, 7, 19], "regular": [3, 7], "express": [3, 7], "paper": [3, 7, 17], "latex": [3, 7], "favorit": [3, 7], "linux": [3, 7, 23], "non": [3, 4, 7, 8], "paint": [3, 7], "introduct": [3, 7, 20, 23, 29], "perform": [3, 7, 19], "therein": [3, 7], "unix": [3, 7], "covid": [4, 27], "19": [4, 27], "were": [4, 11, 23, 29], "physic": [4, 22, 29], "travel": 4, "maximum": 4, "size": [4, 22, 25, 29], "40": [4, 29], "workload": [4, 21], "attempt": 4, "livestream": [4, 5, 11, 22, 23, 24, 28], "staff": [4, 6, 22, 23, 25, 27], "regist": [4, 29], "instant": [4, 24, 29], "replai": [4, 24], "page": [4, 7, 13, 21, 23], "github": [4, 7, 10, 12, 13, 14, 18, 21, 22, 23, 24, 28, 29], "io": [4, 7, 10, 12, 14, 18, 21, 22, 23, 24, 28], "03": [4, 7, 10, 23], "22": [4, 10], "aalto": [4, 7, 23, 29], "asc": [4, 23], "came": [4, 19], "vision": [4, 11, 27], "announc": [4, 29], "invit": [4, 14], "went": [4, 29], "refin": 4, "date": 4, "registr": [4, 5, 22, 28, 29], "via": [4, 5, 13, 14, 25, 28, 29], "kept": 4, "track": [4, 13], "2021": 4, "scicomp": [4, 7, 23], "fi": [4, 7, 23], "scip": [4, 7, 23], "aaltoscicomp": [4, 7, 23], "techniqu": [4, 7, 18], "littl": [5, 13, 25, 29], "cost": [5, 13, 24], "risk": [5, 14, 23, 24], "mentor": [5, 6, 11], "intens": [5, 15], "possibli": [5, 6, 7, 9, 20, 27, 29], "invent": [5, 7, 11, 23], "reward": 5, "successfulli": 5, "stream": [5, 7, 14, 23, 24, 25], "coordin": [5, 12, 20, 22, 27, 28, 29], "duti": 5, "role": [5, 6, 10, 11, 14, 22, 23, 26], "fill": [6, 26], "un": 6, "involv": [6, 15, 22], "asoci": 6, "unfortun": 6, "imbal": 6, "demotiv": 6, "equiti": 6, "leader": [6, 22, 27, 28], "richard": 6, "darst": 6, "z1vs1wlen": 6, "2pacx": 6, "1vqkzomfi5sfnx69d4qrq_3n": 6, "mtcv7gubpzd4a6uypekzumgk0fl5w0rsse6alzxv1ne635yl1gpyckk": 6, "pub": 6, "summari": [6, 15, 17], "quickli": [6, 7, 21, 22, 23, 28, 29], "serv": [6, 13, 28, 29], "equal": [6, 7, 14, 23], "modern": [6, 25], "none": [6, 21, 26, 28], "mainli": [7, 20], "refer": 7, "automat": 7, "singl": 7, "cover": [7, 17], "subset": 7, "md": 7, "advantag": [7, 12, 18, 20, 29], "disadvantag": [7, 18, 20, 22, 29], "rst": [7, 13], "divid": [7, 21], "min": [7, 15, 21], "anywai": [7, 21, 27, 29], "integr": [7, 10], "itself": [7, 10, 13, 17, 26], "occasion": [7, 10], "mention": [7, 9, 10], "screenshar": [7, 10, 14], "balanc": [7, 10], "decreas": [7, 10], "screenshot": [7, 12], "trade": [7, 12, 18], "download": [7, 23], "user": [7, 15, 17, 23, 26], "darstr1": [7, 23], "kickstart": [7, 23], "2023": [7, 23], "mkv": [7, 23], "srt": [7, 23], "11": [7, 23], "35": [7, 15, 23], "12": [7, 23], "25": [7, 23], "descript": [7, 10, 14, 22, 23, 24], "abov": [7, 10, 23, 26, 29], "slice": [7, 23], "segment": [7, 19, 23], "left": [7, 12, 18, 22, 23], "reader": [7, 23], "devic": [7, 23], "cuda": [7, 23], "output_format": [7, 23], "initial_prompt": [7, 23], "welcom": [7, 8, 11, 23], "lang": [7, 23], "en": [7, 23], "condition_on_previous_text": [7, 23], "fals": [7, 23], "input": [7, 23], "prompt": [7, 23], "full": [7, 10, 23], "punctuat": [7, 23], "instruct": [7, 20, 21, 23, 24, 28, 29], "storag": [7, 23], "scienc": [7, 15, 23, 27], "said": [7, 23, 26], "record": [7, 11, 13, 23], "timestamp": [7, 23], "origin": [7, 13, 23], "day1": [7, 23], "part1": [7, 23], "titl": [7, 23], "00": [7, 23], "excerpt": [7, 23], "24": [7, 23], "37": [7, 23], "31": [7, 23], "extern": [7, 23], "lead": [7, 8, 23, 25, 27], "scicompintro": [7, 23], "43": [7, 23], "50": [7, 19, 23], "05": [7, 23], "pip": [7, 23], "virtual": [7, 21, 23], "path": [7, 23], "contain": [7, 23, 29], "quick": [7, 23, 29], "garbl": [7, 23], "second": [7, 13, 19, 23], "kei": [7, 15, 17, 23], "frame": [7, 23], "fix": [7, 23], "reencod": [7, 23], "encod": [7, 23], "info": [7, 18, 23], "txt": [7, 23], "chapter": [7, 23], "didn": [7, 14, 23, 29], "hpc": [7, 23], "summer": [7, 11, 23], "07": [7, 23], "lost": [7, 13, 23, 24], "plzlvms9rf3nmkr2jmglan4su3ojwtwmvw": [7, 23], "webpag": [7, 23, 29], "necessari": [7, 23], "editor": [7, 23, 28], "transcript": [7, 23], "align": [7, 23], "black": [7, 23], "adjust": [7, 22, 23], "outsid": [7, 11, 12, 23], "Be": [7, 23, 25, 29], "pyyaml": [7, 23], "modifi": [7, 23], "dead": [7, 23], "desir": [7, 23], "tabl": [7, 22, 23], "16": [7, 23], "demonstr": [7, 19, 23, 29], "04": [7, 23], "item": [7, 27], "histogram": [7, 28], "underli": [7, 26], "abstract": 7, "layer": 7, "imposs": [7, 12, 22, 26], "otherwis": [7, 10, 23, 26], "brows": [7, 13], "function": [7, 13], "sphinx": [7, 13], "yml": [7, 13], "conf": [7, 13], "py": [7, 13], "index": [7, 13], "signific": [7, 13, 21], "pure": [7, 13, 29], "templat": [7, 13, 29], "altern": [7, 13], "02": 7, "listen": [7, 19, 20], "construct": [7, 13, 19], "verbal": [7, 19], "conclus": [7, 19], "round": [7, 19], "receiv": [7, 14, 19, 27, 28], "trial": [7, 19, 20], "art": [7, 19], "pitfal": [7, 9, 19], "sooner": [7, 19], "close": [7, 14, 19, 20], "action": [8, 13], "taken": 8, "market": 8, "outreach": [8, 28], "visibl": 8, "promot": [8, 13, 25], "member": 8, "profit": 8, "sell": 8, "chat": [8, 10, 20, 21, 28, 29], "offici": 8, "advertis": [8, 28, 29], "unconfer": 8, "weekli": 8, "contribut": 9, "name": [10, 22, 23, 29], "justic": 10, "nor": 10, "replac": [10, 13, 15], "random": 10, "2d": 10, "web": [10, 13], "markdown": 10, "scalabl": 10, "privaci": [10, 14, 23, 29], "view": [10, 14, 29], "manual": [10, 12, 14, 15, 18, 20, 21, 22, 23, 24, 28], "publish": [10, 28], "six": 10, "hour": [10, 23, 24], "synchron": 10, "quiet": [10, 20, 29], "anonym": [10, 20, 29], "q": [10, 15], "scroll": [10, 23], "unansw": 10, "flood": 10, "warn": [10, 20], "deliber": 10, "comfort": 10, "rework": 11, "carpentrycon": 11, "longer": [11, 21], "autumn": 11, "2020": [11, 29], "farther": 11, "offic": 11, "closer": 11, "huge": [11, 13], "2019": 11, "obsolet": 11, "silo": 11, "socio": 11, "factor": [11, 23], "barrier": [11, 27], "profess": 11, "specialti": 11, "again": [11, 13], "specialist": 11, "frustrat": 11, "thu": [11, 14, 21, 22], "comprehens": 11, "kick": [11, 27], "edit": [11, 24, 28, 29], "usabl": 11, "placehold": 11, "backward": [11, 13], "philosophi": 11, "portrait": 12, "layout": [12, 17, 20], "readabl": 12, "beauti": 12, "fullhd": 12, "latest": 12, "half": [12, 20], "distract": [12, 20], "notebook": 12, "font": [12, 20, 25], "shortcut": 12, "scheme": 12, "remov": [12, 18, 23, 24], "late": [12, 23], "pro": 12, "con": 12, "paus": 12, "catch": [12, 20, 23, 24], "modif": 13, "trivial": 13, "sourc": 13, "platform": [13, 24], "option": [13, 20, 22, 23], "store": 13, "raw": [13, 24], "websit": 13, "compil": 13, "convert": 13, "html": 13, "public": [13, 27], "complier": 13, "r": 13, "standard": 13, "ecosystem": 13, "reus": 13, "exact": 13, "licens": 13, "incent": [13, 23, 24], "wide": [13, 21], "citabl": 13, "doi": 13, "commit": 13, "accompani": 13, "branch": 13, "substanti": 13, "rewrit": 13, "draft": 13, "greatli": [14, 29], "awkward": 14, "unlimit": 14, "shy": 14, "passiv": 14, "effici": 14, "extra": [14, 27, 29], "meaning": 14, "mooc": 14, "broadcast": [14, 28], "crash": 14, "presenc": 14, "twitch": [14, 29], "disrupt": 14, "troll": 14, "enabl": 14, "loud": 14, "extrovert": 14, "domin": 14, "captur": 14, "zoom": [14, 20, 22, 24, 25], "switch": 14, "galleri": [14, 29], "dedic": [14, 29], "chanc": 14, "violat": 14, "b": 14, "c": [14, 27], "link": [14, 25], "pathwai": 15, "focus": [15, 20, 29], "curriculum": 15, "handbook": 15, "organiz": 15, "phil": [15, 17], "agr": [15, 17], "bad": [15, 17, 19, 20, 26, 29], "interfac": [15, 17, 26], "brief": [15, 17, 23], "broad": 17, "ones": 17, "unless": 17, "obvious": 17, "low": [17, 24, 25], "prioriti": [17, 23], "wors": [18, 20], "suffer": [18, 25], "reveal": 18, "flaw": 18, "pedagogi": 18, "dump": 18, "elabor": 18, "somehow": [18, 22], "unnecessari": 20, "weird": 20, "save": 20, "harder": [20, 22, 29], "rewind": 20, "orient": 20, "whole": [20, 22, 23, 24, 29], "properti": [20, 22], "window": 20, "whatev": 20, "comment": [20, 25], "s1": 20, "s2": 20, "s3": 20, "s4": 20, "smaller": [20, 25], "anyth": [20, 23, 24], "constrict": 20, "vertic": 20, "displai": 20, "side": 20, "commentari": 20, "pressur": [20, 24], "forget": [20, 23], "introduc": [20, 28, 29], "unfamiliar": 20, "repli": [20, 29], "overload": [20, 27], "turn": 20, "tomorrow": 20, "manula": 20, "five": [20, 29], "prep": [20, 29], "improvemest": 21, "wikipedia": 21, "divis": 21, "labor": 21, "1": [21, 27], "strong": 21, "strength": 21, "strictli": 21, "voic": [21, 24, 29], "quicker": 21, "unexpect": 21, "act": 21, "onboard": [21, 28], "uncertainti": 21, "realiti": 21, "interview": 21, "primarili": 21, "space": 22, "nearbi": 22, "aka": 22, "stai": [22, 29], "uptak": 22, "higher": 22, "renam": 22, "n": [22, 29], "select": [22, 29], "indico": 22, "mail": 22, "messag": 22, "drop": 22, "partwai": 22, "natuar": 22, "arrang": 22, "manner": 22, "explicitli": 22, "ensur": 22, "crowd": 22, "deal": 22, "themselv": [22, 29], "deleg": 22, "releas": [23, 27], "hypothesi": 23, "perfect": 23, "principl": 23, "guarante": [23, 24, 29], "disclaim": [23, 24], "sai": [23, 24, 25, 27], "accid": [23, 24], "audio": [23, 24], "unprocess": [23, 24], "No": 23, "split": [23, 24, 28], "chunk": 23, "jump": 23, "spot": 23, "crowdsourc": 23, "20": [23, 29], "ob": 23, "cleanli": 23, "hover": 23, "mous": 23, "cursor": 23, "area": 23, "stick": 23, "advoc": 23, "flowchat": 23, "worth": 23, "thvmntbjg2y": 23, "_cobn": 23, "n2ak": 23, "afterward": 24, "cmp": 24, "ing": 24, "sth": 24, "soon": 24, "central": 24, "inspir": 25, "indirectli": 25, "luci": 25, "whallei": 25, "gave": [25, 27], "stack": 25, "overflow": 25, "bank": 25, "freeli": 25, "impress": 25, "signpost": 25, "impost": 25, "syndrom": 25, "disproportion": 25, "repres": 25, "manifest": 25, "kind": [25, 29], "silent": 25, "volum": 25, "librarian": 26, "net": 26, "stax": 26, "4965": 26, "terribl": 26, "fault": 26, "forgotten": 26, "despit": 27, "led": 27, "eventu": 27, "fair": 27, "heavili": 27, "emphazis": 27, "mass": 27, "previous": 27, "board": 27, "scari": 27, "tune": 27, "sync": 27, "revert": 27, "massiv": 28, "varieti": 28, "updat": [28, 29], "lower": 28, "top": 28, "sub": 28, "spare": [28, 29], "rotat": [28, 29], "director": 28, "ey": 28, "primari": 29, "condens": 29, "100": 29, "total": 29, "250": 29, "max": 29, "recruit": 29, "march": 29, "toler": 29, "ethic": 29, "featur": 29, "static": 29, "across": 29, "power": 29, "email": 29, "firstnam": 29, "lastnam": 29, "h": 29, "former": 29, "stress": 29, "overlap": 29, "shouldn": 29, "wen": 29, "written": 29, "lose": 29, "loss": 29, "tv": 29, "viewer": 29, "archiv": 29, "14": 29, "hundr": 29, "streamer": 29, "spotlight": 29, "dual": 29, "monitor": 29, "verif": 29, "haven": 29, "log": 29, "whelm": 29, "ourselv": 29, "techniquess": 29, "rapid": 29, "shortli": 29}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"coderefineri": [0, 1, 2, 4, 7, 8, 13, 17, 29], "teach": [0, 1, 4, 7, 11, 17, 18, 19, 20, 21, 26, 27, 28, 29], "philosophi": [0, 7], "ic": [0, 7], "breaker": [0, 7], "group": [0, 7], "20": [0, 7, 17], "minut": [0, 7], "video": [0, 7, 23, 24], "record": [0, 24, 29], "ann": [0, 7], "fouilloux": [0, 7], "bj\u00f8rn": [0, 7], "lindi": [0, 7], "thor": [0, 7], "wikfeldt": [0, 7], "stefan": [0, 7], "negru": [0, 7], "radovan": [0, 7], "bast": [0, 7], "sabri": [0, 7], "razick": [0, 7], "juho": [0, 7], "lehtonen": [0, 7], "richard": [0, 7], "darst": [0, 7], "jo\u00e3o": [0, 7], "m": [0, 7], "da": [0, 7], "silva": [0, 7], "interact": [1, 7], "style": [1, 7], "what": [1, 7, 11, 20, 22, 23, 25, 26, 27], "ar": [1, 7, 26], "top": 1, "issu": 1, "new": 1, "instructor": [1, 7, 9, 12, 19, 25], "face": 1, "solut": [1, 7, 23], "The": [1, 3, 17], "carpentri": [1, 2, 3, 8], "approach": [1, 3], "thi": [1, 7, 11, 23, 25], "materi": 1, "kei": 1, "principl": 1, "On": 1, "import": [1, 24], "feedback": [1, 7, 19], "get": [1, 7, 11, 23, 25], "give": [1, 7, 25], "learner": [1, 7], "progress": 1, "summ": 1, "assess": 1, "form": 1, "option": [1, 7, 17, 19], "10": [1, 7], "mn": [1, 7], "who": [1, 11], "novic": [1, 2], "compet": [1, 2], "practition": [1, 2], "expert": 1, "cognit": 1, "develop": [1, 7, 11, 13], "mental": 1, "model": [1, 4, 7], "how": [1, 6, 7, 8, 12, 17, 20, 23, 26, 28], "knowledg": 1, "wai": [1, 27], "exercis": [1, 3, 4, 6, 7, 10, 12, 13, 14, 18, 19, 21, 22, 23, 26, 27, 28], "identifi": [1, 7], "profil": [1, 7], "curriculum": 1, "revers": 1, "instruct": 1, "design": [1, 3, 7, 11], "recommend": [1, 4, 7, 13], "hpc": [1, 3, 29], "work": 1, "learn": [1, 5, 13, 17], "object": [1, 20], "us": [1, 7, 17, 23, 26], "bloom": 1, "": [1, 8, 9], "taxonomi": 1, "write": 1, "effect": 1, "revisit": 1, "about": 2, "project": 2, "workshop": [2, 5, 7, 11, 17, 25, 28, 29], "keypoint": [2, 5, 8, 12, 24], "histori": [2, 12], "main": [2, 19], "goal": [2, 25], "impact": 2, "target": 2, "audienc": 2, "best": 2, "softwar": [2, 8], "practic": [2, 7, 19, 20], "whom": 2, "backward": [3, 7], "lesson": [3, 5, 7, 11, 13, 17], "process": 3, "exampl": [3, 12, 19], "an": 3, "topic": [3, 7], "collabor": [4, 7, 29], "python": 4, "scientif": 4, "comput": [4, 7, 17, 26], "list": [4, 7], "success": [4, 7], "failur": [4, 7], "co": [4, 7, 21], "distribut": [5, 23], "organ": [5, 11], "It": 5, "i": [5, 11, 24], "easier": 5, "join": [5, 8], "follow": 5, "than": [5, 24], "start": 5, "lead": 5, "from": 5, "larger": 5, "divers": [6, 7], "inclus": [6, 7], "primari": [6, 10, 14, 21, 22, 23, 28], "articl": [6, 10, 14, 21, 22, 23, 28], "support": 6, "servic": 6, "v": [6, 29], "reflect": [6, 7], "your": [6, 7, 12, 13, 23, 28, 29], "job": [6, 7], "can": [6, 7, 8], "defin": [6, 7], "promot": [6, 7], "see": [6, 13, 18, 20, 21, 23, 26, 27, 28], "also": [6, 13, 18, 20, 21, 23, 26, 27, 28], "onlin": [7, 18, 20, 22, 29], "team": [7, 21, 22, 29], "hackmd": [7, 10, 20, 29], "livestream": [7, 14], "advanc": [7, 13, 14], "set": [7, 12, 14], "up": [7, 11, 12, 14], "instal": [7, 14, 29], "ob": [7, 14], "tool": [7, 11, 13, 14, 25], "tech": [7, 12, 14], "setup": [7, 12, 24], "evalu": [7, 12], "screen": [7, 12, 20], "captur": [7, 12], "own": [7, 12, 13, 29], "environ": [7, 12], "edit": [7, 23], "1": [7, 19, 23], "sampl": [7, 13, 23], "2": [7, 19, 23], "run": [7, 23, 29], "whisper": [7, 23], "gener": [7, 13, 23, 29], "raw": [7, 23], "subtitl": [7, 23], "test": [7, 23], "3": [7, 23], "creat": [7, 13, 23], "basic": [7, 22, 23, 29], "editlist": [7, 23], "yaml": [7, 23], "file": [7, 23], "4": [7, 23], "ffmpeg": [7, 23], "5": [7, 17, 23], "add": [7, 23], "more": [7, 12, 23, 24], "featur": [7, 23], "6": [7, 23], "7": [7, 23], "final": [7, 23], "output": [7, 23], "why": [7, 20, 26, 27], "togeth": [7, 27], "similar": [7, 27], "do": [7, 22, 25, 27], "we": [7, 11, 22, 24, 25, 26, 27], "have": [7, 12, 27], "role": [7, 24, 28, 29], "mani": [7, 28], "peopl": [7, 28], "hard": [7, 26], "version": [7, 13], "control": [7, 13], "contribut": [7, 13], "possibl": 8, "plan": 8, "biggest": 8, "open": 8, "problem": 8, "you": 8, "asid": 8, "nordic": 8, "rse": 8, "research": 8, "engin": 8, "guid": 9, "advantag": [10, 27], "disadvantag": [10, 27], "commun": 11, "train": [11, 25, 29], "under": 11, "mid": 11, "2022": 11, "cours": 11, "cover": 11, "prepar": [11, 17, 29], "introduct": [11, 25], "social": 11, "technic": 11, "consider": 11, "wrap": 11, "futur": [11, 17], "involv": 11, "refer": 11, "old": 11, "content": [11, 17], "need": 11, "move": 11, "merg": 11, "screenshar": 12, "adjust": 12, "prompt": 12, "configur": 12, "color": 12, "should": 12, "forc": 12, "consist": 12, "share": [12, 20], "command": 12, "static": 13, "site": 13, "summari": [14, 23, 28], "detail": 14, "other": [15, 24, 29], "resourc": 15, "placehold": 16, "pre": 17, "read": [17, 26], "help": [17, 26], "someon": [17, 26], "min": 17, "brows": 17, "watch": 17, "35": 17, "onli": 17, "45": 17, "q": 17, "A": [17, 23], "15": 17, "scienc": 17, "demo": 19, "part": 19, "discuss": [19, 20, 22, 23, 29], "room": [19, 29], "two": 19, "live": 19, "code": [19, 25], "mechan": 20, "matter": 20, "shell": 20, "goe": 20, "good": 20, "demonstr": 20, "prototyp": 20, "meta": 20, "talk": 20, "question": 20, "benefit": 21, "strategi": [21, 29], "concept": 22, "In": 22, "person": [22, 29], "actual": 22, "make": 23, "easi": 23, "b": 23, "try": 24, "releas": 24, "same": 24, "dai": 24, "privaci": 24, "ani": 24, "factor": 24, "broadcast": 24, "welcom": 25, "want": 25, "out": 25, "confid": 25, "conduct": 25, "initi": 26, "phil": 26, "agr": 26, "usabl": 26, "deep": 26, "abstract": 26, "layer": 26, "conclus": 26, "challeng": 27, "manual": 29, "case": 29, "studi": 29, "mega": 29, "finland": 29, "kickstart": 29, "arrang": 29, "link": 29, "scale": 29, "platform": 29, "zoom": 29, "breakout": 29, "bring": 29, "helper": 29, "staff": 29, "stream": 29, "time": 29, "note": 29}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 60}, "alltitles": {"CodeRefinery teaching philosophies": [[0, "coderefinery-teaching-philosophies"], [7, "coderefinery-teaching-philosophies"]], "Ice-breaker in groups (20 minutes)": [[0, "exercise-0"], [7, "exercise-0"]], "Video recordings": [[0, "prerequisites-0"]], "Anne Fouilloux": [[0, "exercise-1"], [7, "exercise-1"]], "Bj\u00f8rn Lindi": [[0, "exercise-2"], [7, "exercise-2"]], "Thor Wikfeldt": [[0, "exercise-3"], [7, "exercise-3"]], "Stefan Negru": [[0, "exercise-4"], [7, "exercise-4"]], "Radovan Bast": [[0, "exercise-5"], [7, "exercise-5"]], "Sabry Razick": [[0, "exercise-6"], [7, "exercise-6"]], "Juho Lehtonen": [[0, "exercise-7"], [7, "exercise-7"]], "Richard Darst": [[0, "exercise-8"], [7, "exercise-8"]], "Jo\u00e3o M. da Silva": [[0, "exercise-9"], [7, "exercise-9"]], "Interactive teaching style": [[1, "interactive-teaching-style"], [7, "interactive-teaching-style"]], "What are the top issues new instructors face?": [[1, "what-are-the-top-issues-new-instructors-face"]], "Solution": [[1, "solution-0"], [7, "solution-0"], [7, "solution-1"], [7, "solution-2"], [7, "solution-3"], [7, "solution-4"], [7, "solution-5"], [7, "solution-0"], [23, "solution-0"], [23, "solution-1"], [23, "solution-2"], [23, "solution-3"], [23, "solution-4"], [23, "solution-5"]], "The Carpentries and CodeRefinery approaches to teaching": [[1, "the-carpentries-and-coderefinery-approaches-to-teaching"]], "This material": [[1, "callout-0"]], "Key principles": [[1, "key-principles"]], "Carpentries teaching principles": [[1, "carpentries-teaching-principles"]], "On the importance of feedback": [[1, "on-the-importance-of-feedback"]], "Getting/giving feedback on learners\u2019 progress": [[1, "getting-giving-feedback-on-learners-progress"]], "Summative Assessment": [[1, "callout-1"]], "Formative assessment": [[1, "callout-2"]], "Getting/giving feedback on teaching": [[1, "getting-giving-feedback-on-teaching"]], "Give feedback on teaching (optional, 10 mn)": [[1, "exercise-0"], [7, "exercise-0"]], "Who are the learners": [[1, "who-are-the-learners"]], "Novices, competent practitioners and experts": [[1, "novices-competent-practitioners-and-experts"]], "Cognitive Development and Mental Models": [[1, "cognitive-development-and-mental-models"]], "How \u201cknowledge\u201d gets in the way": [[1, "how-knowledge-gets-in-the-way"]], "Exercise: How to identify learner profiles?": [[1, "exercise-1"], [7, "exercise-1"]], "CodeRefinery Curriculum and Reverse Instructional Design (with recommendations for HPC carpentries)": [[1, "coderefinery-curriculum-and-reverse-instructional-design-with-recommendations-for-hpc-carpentries"]], "Working with learning objectives": [[1, "working-with-learning-objectives"]], "Using Bloom\u2019s Taxonomy to write effective learning objectives": [[1, "using-bloom-s-taxonomy-to-write-effective-learning-objectives"]], "Revisiting Learning objectives": [[1, "revisiting-learning-objectives"]], "About the CodeRefinery project and CodeRefinery workshops": [[2, "about-the-coderefinery-project-and-coderefinery-workshops"]], "Keypoints": [[2, "keypoints-0"], [5, "keypoints-0"], [8, "keypoints-0"], [8, "keypoints-1"], [12, "keypoints-0"], [24, "keypoints-0"]], "History": [[2, "discussion-0"]], "Main goals": [[2, "main-goals"]], "Impact": [[2, "impact"]], "Target audience": [[2, "target-audience"]], "Carpentries audience": [[2, "carpentries-audience"]], "Novices": [[2, "callout-0"]], "CodeRefinery audience": [[2, "coderefinery-audience"]], "Competent practitioners": [[2, "callout-1"]], "Best software practices for whom?": [[2, "callout-2"]], "Backwards lesson design": [[3, "backwards-lesson-design"], [7, "backwards-lesson-design"]], "The approach": [[3, "the-approach"]], "The process": [[3, "the-process"]], "Example: designing an HPC Carpentry lesson": [[3, "discussion-0"]], "Exercises": [[3, "exercises"], [4, "exercises"], [6, "exercises"], [12, "exercises"], [13, "exercises"], [14, "exercises"], [21, "exercises"], [22, "exercises"], [23, "exercises"], [27, "exercises"], [28, "exercises"]], "Backwards-design a lesson/topic": [[3, "exercise-0"], [7, "exercise-0"]], "Collaboration models": [[4, "collaboration-models"], [7, "collaboration-models"]], "Model: CodeRefinery": [[4, "model-coderefinery"]], "Model: Python for Scientific Computing": [[4, "model-python-for-scientific-computing"]], "List successes and failures in collaborative teaching": [[4, "exercise-0"], [7, "exercise-0"]], "Recommendations for co-teaching": [[4, "exercise-1"], [7, "exercise-1"]], "Distributed workshop organization": [[5, "distributed-workshop-organization"]], "It is easier to join and follow than to start or lead": [[5, "it-is-easier-to-join-and-follow-than-to-start-or-lead"]], "Lessons learned from organizing larger workshops": [[5, "discussion-0"]], "Diversity and inclusion": [[6, "diversity-and-inclusion"], [7, "diversity-and-inclusion"]], "Primary articles": [[6, "primary-articles"], [10, "primary-articles"], [14, "primary-articles"], [22, "primary-articles"], [23, "primary-articles"], [28, "primary-articles"]], "Support services vs diversity": [[6, "support-services-vs-diversity"]], "Reflect on how your job can be defined to promote diversity.": [[6, "exercise-0"], [7, "exercise-0"]], "See also": [[6, "see-also"], [13, "see-also"], [18, "see-also"], [20, "see-also"], [21, "see-also"], [23, "see-also"], [26, "see-also"], [27, "see-also"], [28, "see-also"]], "Exercise list": [[7, "exercise-list"]], "Teaching online": [[7, "teaching-online"], [18, "teaching-online"]], "Exercise": [[7, "exercise-0"], [7, "exercise-0"], [7, "exercise-0"], [7, "exercise-0"], [7, "exercise-0"], [7, "exercise-1"], [7, "exercise-2"], [10, "exercise"], [10, "exercise-0"], [18, "exercise-0"], [19, "exercise-0"], [19, "exercise-1"], [19, "exercise-2"], [21, "exercise-0"], [26, "exercise-0"]], "Team teaching": [[7, "team-teaching"], [21, "team-teaching"]], "HackMD": [[7, "hackmd"], [10, "hackmd"], [29, "hackmd"]], "Teams": [[7, "teams"], [7, "exercise-0"], [22, "teams"], [22, "exercise-0"]], "Livestreaming": [[7, "livestreaming"], [14, "livestreaming"]], "(advanced) Set up and install OBS as a livestreaming tool.": [[7, "exercise-0"], [14, "exercise-0"]], "Instructor tech setup": [[7, "instructor-tech-setup"], [12, "instructor-tech-setup"]], "Evaluate screen captures": [[7, "exercise-0"], [12, "exercise-0"]], "Set up your own environment": [[7, "exercise-1"], [12, "exercise-1"]], "Video editing": [[7, "video-editing"], [23, "video-editing"]], "Editing-1: Get your sample video": [[7, "exercise-0"], [23, "exercise-0"]], "Editing-2: Run Whisper to generate raw subtitles and test video.": [[7, "exercise-1"], [23, "exercise-1"]], "Editing-3: Create the basic editlist.yaml file": [[7, "exercise-2"], [23, "exercise-2"]], "Editing-4: Run ffmpeg-editlist": [[7, "exercise-3"], [23, "exercise-3"]], "Editing-5: Add more features": [[7, "exercise-4"], [23, "exercise-4"]], "Editing-6: Subtitles": [[7, "exercise-5"], [7, "exercise-6"], [23, "exercise-5"], [23, "exercise-6"]], "Editing-7: Generate the final output file.": [[7, "exercise-7"], [23, "exercise-7"]], "Use ffmpeg-editlist to edit this sample video": [[7, "exercise-8"], [23, "exercise-8"]], "Why teach together?": [[7, "why-teach-together"], [27, "why-teach-together"]], "What similarities do we have?": [[7, "exercise-0"], [27, "exercise-0"]], "Workshop roles": [[7, "workshop-roles"], [28, "workshop-roles"]], "How many people teach in your workshops?": [[7, "exercise-0"], [28, "exercise-0"]], "Why are computers hard?": [[7, "why-are-computers-hard"], [26, "why-are-computers-hard"]], "Lesson development with version control": [[7, "lesson-development-with-version-control"], [13, "lesson-development-with-version-control"]], "Contribute to a sample lesson": [[7, "exercise-0"], [13, "exercise-0"]], "(advanced) Create your own lesson": [[7, "exercise-1"], [13, "exercise-1"]], "Teaching practice and feedback": [[7, "teaching-practice-and-feedback"], [19, "teaching-practice-and-feedback"]], "Possibilities for Carpentries": [[8, "possibilities-for-carpentries"]], "CodeRefinery\u2019s plans": [[8, "coderefinery-s-plans"]], "Biggest open problems": [[8, "biggest-open-problems"]], "How you can join": [[8, "how-you-can-join"]], "Aside: Nordic-RSE (research software engineers)": [[8, "aside-nordic-rse-research-software-engineers"]], "Instructor\u2019s guide": [[9, "instructor-s-guide"]], "Advantages": [[10, "advantages"], [27, "advantages"]], "Disadvantages": [[10, "disadvantages"]], "Community teaching training": [[11, "community-teaching-training"]], "Under development (mid 2022)": [[11, null]], "What this course covers": [[11, "what-this-course-covers"]], "Who is the course for?": [[11, "who-is-the-course-for"]], "Preparation": [[11, null]], "Introduction": [[11, null]], "Teaching tools": [[11, null]], "Workshop organization": [[11, null]], "Social-technical considerations": [[11, null]], "Lesson design and development": [[11, null]], "Wrap-up, future, and getting involved": [[11, null]], "Reference": [[11, null]], "Old contents - we need to move/merge": [[11, null]], "Screenshare": [[12, "screenshare"]], "Adjust your prompt/configuration/colors": [[12, "adjust-your-prompt-configuration-colors"]], "Should instructors be forced to have a consistent screenshare?": [[12, "discussion-0"]], "Share the history of your commands": [[12, "share-the-history-of-your-commands"]], "More examples and how to set it up": [[12, "more-examples-and-how-to-set-it-up"]], "Version control and static site generators": [[13, "version-control-and-static-site-generators"]], "CodeRefinery lesson tools": [[13, "coderefinery-lesson-tools"]], "Recommendations and lessons learned": [[13, "recommendations-and-lessons-learned"]], "Summary": [[14, "summary"], [23, "summary"], [28, "summary"]], "Tech details": [[14, "tech-details"]], "Other resources": [[15, "other-resources"]], "Placeholder": [[16, "placeholder"]], "Pre-workshop preparation": [[17, "pre-workshop-preparation"]], "Read \u201cHow to help someone use a computer\u201d (5 min)": [[17, "read-how-to-help-someone-use-a-computer-5-min"]], "Browse a CodeRefinery lesson (5 min)": [[17, "browse-a-coderefinery-lesson-5-min"]], "(optional) Watch \u201cThe future of teaching\u201d (35 min content only, 45 min with Q&A, or 15 min reading)": [[17, "optional-watch-the-future-of-teaching-35-min-content-only-45-min-with-q-a-or-15-min-reading"]], "(optional) Read \u201cThe science of learning\u201d (20 min)": [[17, "optional-read-the-science-of-learning-20-min"]], "Instructor demo": [[19, "instructor-demo"]], "Teaching demos part 1": [[19, "teaching-demos-part-1"]], "Teaching demos, part 2": [[19, "teaching-demos-part-2"]], "Discussion": [[19, "discussion"], [20, "discussion-1"], [20, "discussion-2"]], "Main room discussion": [[19, "discussion-0"]], "Optional: feedback for two live-coding examples": [[19, "optional-feedback-for-two-live-coding-examples"]], "How to teach online": [[20, "how-to-teach-online"]], "Objectives": [[20, "objectives-0"]], "Why teaching mechanics matter": [[20, "why-teaching-mechanics-matter"]], "Shell sharing": [[20, "shell-sharing"]], "Discussion: what goes into a good shell share or demonstration?": [[20, "discussion-0"]], "Screen sharing": [[20, "screen-sharing"]], "HackMD prototype": [[20, "output-0"]], "Meta-talk": [[20, "meta-talk"]], "Teach teaching": [[20, "teach-teaching"]], "Questions": [[20, "questions"]], "Teaching practice": [[20, "teaching-practice"]], "Co-teaching": [[21, null]], "Primary article": [[21, "primary-article"]], "Benefits": [[21, "benefits"]], "Strategies": [[21, "strategies"]], "Basic concepts": [[22, "basic-concepts"]], "Online": [[22, "online"]], "In-person": [[22, "in-person"]], "Discussion: what we actually do": [[22, "discussion-what-we-actually-do"]], "Exercise A": [[23, "exercise-a"]], "Discussion: what makes a video easy to edit?": [[23, null]], "Discussion: how to distribute this?": [[23, null]], "Exercise B": [[23, "exercise-b"]], "Video recording": [[24, "video-recording"]], "We try to release videos on the same day": [[24, "we-try-to-release-videos-on-the-same-day"]], "Privacy is more important than any other factor": [[24, "privacy-is-more-important-than-any-other-factor"]], "Broadcasting role and setup": [[24, "broadcasting-role-and-setup"]], "Welcome and introduction": [[25, "welcome-and-introduction"]], "What do we want to get out of this workshop": [[25, "discussion-0"]], "Goals for this workshop": [[25, "goals-for-this-workshop"]], "Goals for this instructor training": [[25, "discussion-1"]], "Giving confidence": [[25, "giving-confidence"]], "Tools for this workshop": [[25, "tools-for-this-workshop"]], "Code of Conduct": [[25, "code-of-conduct"]], "Initial reading": [[26, "initial-reading"]], "How to help someone use a computer, by Phil Agre": [[26, null]], "Usability": [[26, "usability"]], "Deep abstraction layers": [[26, "deep-abstraction-layers"]], "Conclusion: what are we teaching, then?": [[26, "conclusion-what-are-we-teaching-then"]], "Ways to teach together": [[27, "ways-to-teach-together"]], "Challenges and disadvantages": [[27, "challenges-and-disadvantages"]], "Workshop manuals": [[29, "callout-0"]], "Running a workshop: online": [[29, "running-a-workshop-online"]], "Online teaching discussion": [[29, "online-teaching-discussion"]], "Discussion: Online vs in-person": [[29, "discussion-0"]], "Case study: Mega-CodeRefinery and Finland HPC Kickstart": [[29, "case-study-mega-coderefinery-and-finland-hpc-kickstart"]], "General workshop arrangements": [[29, "general-workshop-arrangements"]], "Manuals link": [[29, "callout-1"]], "CodeRefinery online scaling strategy": [[29, "coderefinery-online-scaling-strategy"]], "Basic preparation": [[29, "basic-preparation"]], "Basic platform: Zoom": [[29, "basic-platform-zoom"]], "Breakout rooms, bring your own team": [[29, "breakout-rooms-bring-your-own-team"]], "Helper training": [[29, "helper-training"]], "Staff roles": [[29, "staff-roles"]], "Recording and streaming": [[29, "recording-and-streaming"]], "Installation time": [[29, "installation-time"]], "Other notes": [[29, "other-notes"]], "Workshop collaborations": [[29, "workshop-collaborations"]]}, "indexentries": {}}) \ No newline at end of file diff --git a/branch/ignore/singlehtml/_static/_sphinx_javascript_frameworks_compat.js b/branch/ignore/singlehtml/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 0000000..8141580 --- /dev/null +++ b/branch/ignore/singlehtml/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/branch/ignore/singlehtml/_static/basic.css b/branch/ignore/singlehtml/_static/basic.css new file mode 100644 index 0000000..30fee9d --- /dev/null +++ b/branch/ignore/singlehtml/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/branch/ignore/singlehtml/_static/check-solid.svg b/branch/ignore/singlehtml/_static/check-solid.svg new file mode 100644 index 0000000..92fad4b --- /dev/null +++ b/branch/ignore/singlehtml/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/branch/ignore/singlehtml/_static/clipboard.min.js b/branch/ignore/singlehtml/_static/clipboard.min.js new file mode 100644 index 0000000..54b3c46 --- /dev/null +++ b/branch/ignore/singlehtml/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/branch/ignore/singlehtml/_static/copybutton.css b/branch/ignore/singlehtml/_static/copybutton.css new file mode 100644 index 0000000..f1916ec --- /dev/null +++ b/branch/ignore/singlehtml/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/branch/ignore/singlehtml/_static/copybutton.js b/branch/ignore/singlehtml/_static/copybutton.js new file mode 100644 index 0000000..2ea7ff3 --- /dev/null +++ b/branch/ignore/singlehtml/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/branch/ignore/singlehtml/_static/copybutton_funcs.js b/branch/ignore/singlehtml/_static/copybutton_funcs.js new file mode 100644 index 0000000..dbe1aaa --- /dev/null +++ b/branch/ignore/singlehtml/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/branch/ignore/singlehtml/_static/css/badge_only.css b/branch/ignore/singlehtml/_static/css/badge_only.css new file mode 100644 index 0000000..c718cee --- /dev/null +++ b/branch/ignore/singlehtml/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/branch/ignore/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff b/branch/ignore/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/branch/ignore/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/branch/ignore/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff2 b/branch/ignore/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/branch/ignore/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/branch/ignore/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff b/branch/ignore/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/branch/ignore/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/branch/ignore/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff2 b/branch/ignore/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/branch/ignore/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/branch/ignore/singlehtml/_static/css/fonts/fontawesome-webfont.eot b/branch/ignore/singlehtml/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/branch/ignore/singlehtml/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/branch/ignore/singlehtml/_static/css/fonts/fontawesome-webfont.svg b/branch/ignore/singlehtml/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/branch/ignore/singlehtml/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/branch/ignore/singlehtml/_static/css/fonts/fontawesome-webfont.ttf b/branch/ignore/singlehtml/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/branch/ignore/singlehtml/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/branch/ignore/singlehtml/_static/css/fonts/fontawesome-webfont.woff b/branch/ignore/singlehtml/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/branch/ignore/singlehtml/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/branch/ignore/singlehtml/_static/css/fonts/fontawesome-webfont.woff2 b/branch/ignore/singlehtml/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/branch/ignore/singlehtml/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/branch/ignore/singlehtml/_static/css/fonts/lato-bold-italic.woff b/branch/ignore/singlehtml/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/branch/ignore/singlehtml/_static/css/fonts/lato-bold-italic.woff differ diff --git a/branch/ignore/singlehtml/_static/css/fonts/lato-bold-italic.woff2 b/branch/ignore/singlehtml/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/branch/ignore/singlehtml/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/branch/ignore/singlehtml/_static/css/fonts/lato-bold.woff b/branch/ignore/singlehtml/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/branch/ignore/singlehtml/_static/css/fonts/lato-bold.woff differ diff --git a/branch/ignore/singlehtml/_static/css/fonts/lato-bold.woff2 b/branch/ignore/singlehtml/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/branch/ignore/singlehtml/_static/css/fonts/lato-bold.woff2 differ diff --git a/branch/ignore/singlehtml/_static/css/fonts/lato-normal-italic.woff b/branch/ignore/singlehtml/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/branch/ignore/singlehtml/_static/css/fonts/lato-normal-italic.woff differ diff --git a/branch/ignore/singlehtml/_static/css/fonts/lato-normal-italic.woff2 b/branch/ignore/singlehtml/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/branch/ignore/singlehtml/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/branch/ignore/singlehtml/_static/css/fonts/lato-normal.woff b/branch/ignore/singlehtml/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/branch/ignore/singlehtml/_static/css/fonts/lato-normal.woff differ diff --git a/branch/ignore/singlehtml/_static/css/fonts/lato-normal.woff2 b/branch/ignore/singlehtml/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/branch/ignore/singlehtml/_static/css/fonts/lato-normal.woff2 differ diff --git a/branch/ignore/singlehtml/_static/css/theme.css b/branch/ignore/singlehtml/_static/css/theme.css new file mode 100644 index 0000000..19a446a --- /dev/null +++ b/branch/ignore/singlehtml/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/branch/ignore/singlehtml/_static/doctools.js b/branch/ignore/singlehtml/_static/doctools.js new file mode 100644 index 0000000..d06a71d --- /dev/null +++ b/branch/ignore/singlehtml/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/branch/ignore/singlehtml/_static/documentation_options.js b/branch/ignore/singlehtml/_static/documentation_options.js new file mode 100644 index 0000000..89003c6 --- /dev/null +++ b/branch/ignore/singlehtml/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'singlehtml', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/branch/ignore/singlehtml/_static/file.png b/branch/ignore/singlehtml/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/branch/ignore/singlehtml/_static/file.png differ diff --git a/branch/ignore/singlehtml/_static/jquery.js b/branch/ignore/singlehtml/_static/jquery.js new file mode 100644 index 0000000..c4c6022 --- /dev/null +++ b/branch/ignore/singlehtml/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!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(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=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,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).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 w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\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(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.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,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){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 H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.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--)b.attrHandle[n[r]]=t}function pe(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 de(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 d=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")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.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}},b.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[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.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},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),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(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.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},j=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)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(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==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(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?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{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 G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.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("(^|"+M+")"+e+"("+M+"|$)"))&&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:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.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 S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(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").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.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),m(t)&&(t=t.call(e,n,S.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)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.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"===S.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"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.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)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.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?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.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)}}),S.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){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/ignore/singlehtml/_static/js/html5shiv.min.js b/branch/ignore/singlehtml/_static/js/html5shiv.min.js new file mode 100644 index 0000000..cd1c674 --- /dev/null +++ b/branch/ignore/singlehtml/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/ignore/singlehtml/_static/js/theme.js b/branch/ignore/singlehtml/_static/js/theme.js new file mode 100644 index 0000000..1fddb6e --- /dev/null +++ b/branch/ignore/singlehtml/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/branch/ignore/singlehtml/_static/minipres.js b/branch/ignore/singlehtml/_static/minipres.js new file mode 100644 index 0000000..ad11c87 --- /dev/null +++ b/branch/ignore/singlehtml/_static/minipres.js @@ -0,0 +1,223 @@ +// Add goTo method to elements +// http://stackoverflow.com/questions/4801655/how-to-go-to-a-specific-element-on-page +(function($) { + $.fn.goTo = function() { + $('html, body').animate({ + scrollTop: $(this).offset().top //+ 'px' + }, 'fast'); + return this; // for chaining... + } +})(jQuery); + +// NO good way to do this!. Copy a hack from here +// https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript +// https://stackoverflow.com/a/2880929 +var urlParams; +(window.onpopstate = function () { + var match, + pl = /\+/g, // Regex for replacing addition symbol with a space + search = /([^&=]+)=?([^&]*)/g, + decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, + query = window.location.search.substring(1); + urlParams = {}; + while (match = search.exec(query)) + urlParams[decode(match[1])] = decode(match[2]); +})(); + +// Select heading levels +var maxHeading = urlParams['h'] +if (maxHeading === undefined) maxHeading = 2 +var headingLevels = []; +for (h=2 ; h (sections.length-1) ) { + // if we would scroll past bottom, or above top, do nothing + return; + } + + console.log('xxxxxx'); + var targetSection = sections[targetPos]; + console.log(targetSection, typeof(targetSection)); + + // Return targetSection top and height + var secProperties = section_top_and_height(targetSection); + var top = secProperties['top']; + var height = secProperties['height'] + var win_height = window.innerHeight; + //console.info(top, height, win_height) + + var scroll_to = 0; + if (height >= win_height || height == 0) { + scroll_to = top; + } else { + scroll_to = top - (win_height-height)/3.; + } + //console.info(top, height, win_height, scroll_to) + + $('html, body').animate({ + scrollTop: scroll_to //+ 'px' + }, 'fast'); + +} + + +function minipres() { + /* Enable the minipres mode: + - call the hide() function + - set up the scrolling listener + */ + document.addEventListener('keydown', function (event) { + switch(event.which) { + case 37: // left + switch_slide(-1); + event.preventDefault(); + return false; + break; + //case 38: // up + case 39: // right + switch_slide(+1); + event.preventDefault(); + return false; + break; + //case 40: // down + default: + return; // exit this handler for other keys + } + }, true) + + hide() + + // Increase space between sections + //$("div .section").css('margin-bottom', '50%'); + $(sectionSelector).css('margin-top', '50%'); + + // Reduce size/color of other sections + if (hiddenSectionSelector.length > 0) { + var hideNodes = $(hiddenSectionSelector); + console.log(typeof hideNodes, hideNodes); + for (node in hideNodes) { + console.log("a", typeof node, node); + node = hideNodes[node]; // what's right way to iterate values? + console.log("b", typeof node, node); + if (node.parentNode && node.parentNode.className == "section") { + node = node.parentNode; + console.log("c", typeof node, node); + //node.css['transform'] = 'scale(.5)'; + //node.css['transform-origin'] = 'top center'; + $(node).css('color', 'lightgrey'); + //$(node).css('font-size', '20%'); + //$(node).css('visibility', 'collapse'); + //ntahousnatouhasno; + } + } + } +} + +function hide() { + /* Hide all non-essential elements on the page + */ + + // This is for sphinx_rst_theme and readthedocs + $(".wy-nav-side").remove(); + $(".wy-nav-content-wrap").css('margin-left', 0); + $('.rst-versions').remove(); // readthedocs version selector + + // Add other formats here. +} + + +var slideshow = minipres; + +if (window.location.search.match(/[?&](minipres|slideshow|pres)([=&]|$)/) ) { + //minipres() + window.addEventListener("load", minipres); +} else if (window.location.search.match(/[?&](plain)([=&]|$)/) ) { + window.addEventListener("load", hide); +} diff --git a/branch/ignore/singlehtml/_static/minus.png b/branch/ignore/singlehtml/_static/minus.png new file mode 100644 index 0000000..d96755f Binary files /dev/null and b/branch/ignore/singlehtml/_static/minus.png differ diff --git a/branch/ignore/singlehtml/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css b/branch/ignore/singlehtml/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css new file mode 100644 index 0000000..3356631 --- /dev/null +++ b/branch/ignore/singlehtml/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css @@ -0,0 +1,2342 @@ +/* Variables */ +:root { + --mystnb-source-bg-color: #f7f7f7; + --mystnb-stdout-bg-color: #fcfcfc; + --mystnb-stderr-bg-color: #fdd; + --mystnb-traceback-bg-color: #fcfcfc; + --mystnb-source-border-color: #ccc; + --mystnb-source-margin-color: green; + --mystnb-stdout-border-color: #f7f7f7; + --mystnb-stderr-border-color: #f7f7f7; + --mystnb-traceback-border-color: #ffd6d6; + --mystnb-hide-prompt-opacity: 70%; + --mystnb-source-border-radius: .4em; + --mystnb-source-border-width: 1px; +} + +/* Whole cell */ +div.container.cell { + padding-left: 0; + margin-bottom: 1em; +} + +/* Removing all background formatting so we can control at the div level */ +.cell_input div.highlight, +.cell_output pre, +.cell_input pre, +.cell_output .output { + border: none; + box-shadow: none; +} + +.cell_output .output pre, +.cell_input pre { + margin: 0px; +} + +/* Input cells */ +div.cell div.cell_input, +div.cell details.above-input>summary { + padding-left: 0em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + background-color: var(--mystnb-source-bg-color); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; + border-radius: var(--mystnb-source-border-radius); +} + +div.cell_input>div, +div.cell_output div.output>div.highlight { + margin: 0em !important; + border: none !important; +} + +/* All cell outputs */ +.cell_output { + padding-left: 1em; + padding-right: 0em; + margin-top: 1em; +} + +/* Text outputs from cells */ +.cell_output .output.text_plain, +.cell_output .output.traceback, +.cell_output .output.stream, +.cell_output .output.stderr { + margin-top: 1em; + margin-bottom: 0em; + box-shadow: none; +} + +.cell_output .output.text_plain, +.cell_output .output.stream { + background: var(--mystnb-stdout-bg-color); + border: 1px solid var(--mystnb-stdout-border-color); +} + +.cell_output .output.stderr { + background: var(--mystnb-stderr-bg-color); + border: 1px solid var(--mystnb-stderr-border-color); +} + +.cell_output .output.traceback { + background: var(--mystnb-traceback-bg-color); + border: 1px solid var(--mystnb-traceback-border-color); +} + +/* Collapsible cell content */ +div.cell details.above-input div.cell_input { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-top: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; +} + +div.cell div.cell_input.above-output-prompt { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +div.cell details.above-input>summary { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; + padding-left: 1em; + margin-bottom: 0; +} + +div.cell details.above-output>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.below-input>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-top: none; + border-bottom-left-radius: var(--mystnb-source-border-radius); + border-bottom-right-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.hide>summary>span { + opacity: var(--mystnb-hide-prompt-opacity); +} + +div.cell details.hide[open]>summary>span.collapsed { + display: none; +} + +div.cell details.hide:not([open])>summary>span.expanded { + display: none; +} + +@keyframes collapsed-fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} +div.cell details.hide[open]>summary~* { + -moz-animation: collapsed-fade-in 0.3s ease-in-out; + -webkit-animation: collapsed-fade-in 0.3s ease-in-out; + animation: collapsed-fade-in 0.3s ease-in-out; +} + +/* Math align to the left */ +.cell_output .MathJax_Display { + text-align: left !important; +} + +/* Pandas tables. Pulled from the Jupyter / nbsphinx CSS */ +div.cell_output table { + border: none; + border-collapse: collapse; + border-spacing: 0; + color: black; + font-size: 1em; + table-layout: fixed; +} + +div.cell_output thead { + border-bottom: 1px solid black; + vertical-align: bottom; +} + +div.cell_output tr, +div.cell_output th, +div.cell_output td { + text-align: right; + vertical-align: middle; + padding: 0.5em 0.5em; + line-height: normal; + white-space: normal; + max-width: none; + border: none; +} + +div.cell_output th { + font-weight: bold; +} + +div.cell_output tbody tr:nth-child(odd) { + background: #f5f5f5; +} + +div.cell_output tbody tr:hover { + background: rgba(66, 165, 245, 0.2); +} + +/** source code line numbers **/ +span.linenos { + opacity: 0.5; +} + +/* Inline text from `paste` operation */ + +span.pasted-text { + font-weight: bold; +} + +span.pasted-inline img { + max-height: 2em; +} + +tbody span.pasted-inline img { + max-height: none; +} + +/* Font colors for translated ANSI escape sequences +Color values are copied from Jupyter Notebook +https://github.com/jupyter/notebook/blob/52581f8eda9b319eb0390ac77fe5903c38f81e3e/notebook/static/notebook/less/ansicolors.less#L14-L21 +Background colors from +https://nbsphinx.readthedocs.io/en/latest/code-cells.html#ANSI-Colors +*/ +div.highlight .-Color-Bold { + font-weight: bold; +} + +div.highlight .-Color[class*=-Black] { + color: #3E424D +} + +div.highlight .-Color[class*=-Red] { + color: #E75C58 +} + +div.highlight .-Color[class*=-Green] { + color: #00A250 +} + +div.highlight .-Color[class*=-Yellow] { + color: #DDB62B +} + +div.highlight .-Color[class*=-Blue] { + color: #208FFB +} + +div.highlight .-Color[class*=-Magenta] { + color: #D160C4 +} + +div.highlight .-Color[class*=-Cyan] { + color: #60C6C8 +} + +div.highlight .-Color[class*=-White] { + color: #C5C1B4 +} + +div.highlight .-Color[class*=-BGBlack] { + background-color: #3E424D +} + +div.highlight .-Color[class*=-BGRed] { + background-color: #E75C58 +} + +div.highlight .-Color[class*=-BGGreen] { + background-color: #00A250 +} + +div.highlight .-Color[class*=-BGYellow] { + background-color: #DDB62B +} + +div.highlight .-Color[class*=-BGBlue] { + background-color: #208FFB +} + +div.highlight .-Color[class*=-BGMagenta] { + background-color: #D160C4 +} + +div.highlight .-Color[class*=-BGCyan] { + background-color: #60C6C8 +} + +div.highlight .-Color[class*=-BGWhite] { + background-color: #C5C1B4 +} + +/* Font colors for 8-bit ANSI */ + +div.highlight .-Color[class*=-C0] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC0] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C1] { + color: #800000 +} + +div.highlight .-Color[class*=-BGC1] { + background-color: #800000 +} + +div.highlight .-Color[class*=-C2] { + color: #008000 +} + +div.highlight .-Color[class*=-BGC2] { + background-color: #008000 +} + +div.highlight .-Color[class*=-C3] { + color: #808000 +} + +div.highlight .-Color[class*=-BGC3] { + background-color: #808000 +} + +div.highlight .-Color[class*=-C4] { + color: #000080 +} + +div.highlight .-Color[class*=-BGC4] { + background-color: #000080 +} + +div.highlight .-Color[class*=-C5] { + color: #800080 +} + +div.highlight .-Color[class*=-BGC5] { + background-color: #800080 +} + +div.highlight .-Color[class*=-C6] { + color: #008080 +} + +div.highlight .-Color[class*=-BGC6] { + background-color: #008080 +} + +div.highlight .-Color[class*=-C7] { + color: #C0C0C0 +} + +div.highlight .-Color[class*=-BGC7] { + background-color: #C0C0C0 +} + +div.highlight .-Color[class*=-C8] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC8] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C9] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC9] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C10] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC10] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C11] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC11] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C12] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC12] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C13] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC13] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C14] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC14] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C15] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC15] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C16] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC16] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C17] { + color: #00005F +} + +div.highlight .-Color[class*=-BGC17] { + background-color: #00005F +} + +div.highlight .-Color[class*=-C18] { + color: #000087 +} + +div.highlight .-Color[class*=-BGC18] { + background-color: #000087 +} + +div.highlight .-Color[class*=-C19] { + color: #0000AF +} + +div.highlight .-Color[class*=-BGC19] { + background-color: #0000AF +} + +div.highlight .-Color[class*=-C20] { + color: #0000D7 +} + +div.highlight .-Color[class*=-BGC20] { + background-color: #0000D7 +} + +div.highlight .-Color[class*=-C21] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC21] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C22] { + color: #005F00 +} + +div.highlight .-Color[class*=-BGC22] { + background-color: #005F00 +} + +div.highlight .-Color[class*=-C23] { + color: #005F5F +} + +div.highlight .-Color[class*=-BGC23] { + background-color: #005F5F +} + +div.highlight .-Color[class*=-C24] { + color: #005F87 +} + +div.highlight .-Color[class*=-BGC24] { + background-color: #005F87 +} + +div.highlight .-Color[class*=-C25] { + color: #005FAF +} + +div.highlight .-Color[class*=-BGC25] { + background-color: #005FAF +} + +div.highlight .-Color[class*=-C26] { + color: #005FD7 +} + +div.highlight .-Color[class*=-BGC26] { + background-color: #005FD7 +} + +div.highlight .-Color[class*=-C27] { + color: #005FFF +} + +div.highlight .-Color[class*=-BGC27] { + background-color: #005FFF +} + +div.highlight .-Color[class*=-C28] { + color: #008700 +} + +div.highlight .-Color[class*=-BGC28] { + background-color: #008700 +} + +div.highlight .-Color[class*=-C29] { + color: #00875F +} + +div.highlight .-Color[class*=-BGC29] { + background-color: #00875F +} + +div.highlight .-Color[class*=-C30] { + color: #008787 +} + +div.highlight .-Color[class*=-BGC30] { + background-color: #008787 +} + +div.highlight .-Color[class*=-C31] { + color: #0087AF +} + +div.highlight .-Color[class*=-BGC31] { + background-color: #0087AF +} + +div.highlight .-Color[class*=-C32] { + color: #0087D7 +} + +div.highlight .-Color[class*=-BGC32] { + background-color: #0087D7 +} + +div.highlight .-Color[class*=-C33] { + color: #0087FF +} + +div.highlight .-Color[class*=-BGC33] { + background-color: #0087FF +} + +div.highlight .-Color[class*=-C34] { + color: #00AF00 +} + +div.highlight .-Color[class*=-BGC34] { + background-color: #00AF00 +} + +div.highlight .-Color[class*=-C35] { + color: #00AF5F +} + +div.highlight .-Color[class*=-BGC35] { + background-color: #00AF5F +} + +div.highlight .-Color[class*=-C36] { + color: #00AF87 +} + +div.highlight .-Color[class*=-BGC36] { + background-color: #00AF87 +} + +div.highlight .-Color[class*=-C37] { + color: #00AFAF +} + +div.highlight .-Color[class*=-BGC37] { + background-color: #00AFAF +} + +div.highlight .-Color[class*=-C38] { + color: #00AFD7 +} + +div.highlight .-Color[class*=-BGC38] { + background-color: #00AFD7 +} + +div.highlight .-Color[class*=-C39] { + color: #00AFFF +} + +div.highlight .-Color[class*=-BGC39] { + background-color: #00AFFF +} + +div.highlight .-Color[class*=-C40] { + color: #00D700 +} + +div.highlight .-Color[class*=-BGC40] { + background-color: #00D700 +} + +div.highlight .-Color[class*=-C41] { + color: #00D75F +} + +div.highlight .-Color[class*=-BGC41] { + background-color: #00D75F +} + +div.highlight .-Color[class*=-C42] { + color: #00D787 +} + +div.highlight .-Color[class*=-BGC42] { + background-color: #00D787 +} + +div.highlight .-Color[class*=-C43] { + color: #00D7AF +} + +div.highlight .-Color[class*=-BGC43] { + background-color: #00D7AF +} + +div.highlight .-Color[class*=-C44] { + color: #00D7D7 +} + +div.highlight .-Color[class*=-BGC44] { + background-color: #00D7D7 +} + +div.highlight .-Color[class*=-C45] { + color: #00D7FF +} + +div.highlight .-Color[class*=-BGC45] { + background-color: #00D7FF +} + +div.highlight .-Color[class*=-C46] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC46] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C47] { + color: #00FF5F +} + +div.highlight .-Color[class*=-BGC47] { + background-color: #00FF5F +} + +div.highlight .-Color[class*=-C48] { + color: #00FF87 +} + +div.highlight .-Color[class*=-BGC48] { + background-color: #00FF87 +} + +div.highlight .-Color[class*=-C49] { + color: #00FFAF +} + +div.highlight .-Color[class*=-BGC49] { + background-color: #00FFAF +} + +div.highlight .-Color[class*=-C50] { + color: #00FFD7 +} + +div.highlight .-Color[class*=-BGC50] { + background-color: #00FFD7 +} + +div.highlight .-Color[class*=-C51] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC51] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C52] { + color: #5F0000 +} + +div.highlight .-Color[class*=-BGC52] { + background-color: #5F0000 +} + +div.highlight .-Color[class*=-C53] { + color: #5F005F +} + +div.highlight .-Color[class*=-BGC53] { + background-color: #5F005F +} + +div.highlight .-Color[class*=-C54] { + color: #5F0087 +} + +div.highlight .-Color[class*=-BGC54] { + background-color: #5F0087 +} + +div.highlight .-Color[class*=-C55] { + color: #5F00AF +} + +div.highlight .-Color[class*=-BGC55] { + background-color: #5F00AF +} + +div.highlight .-Color[class*=-C56] { + color: #5F00D7 +} + +div.highlight .-Color[class*=-BGC56] { + background-color: #5F00D7 +} + +div.highlight .-Color[class*=-C57] { + color: #5F00FF +} + +div.highlight .-Color[class*=-BGC57] { + background-color: #5F00FF +} + +div.highlight .-Color[class*=-C58] { + color: #5F5F00 +} + +div.highlight .-Color[class*=-BGC58] { + background-color: #5F5F00 +} + +div.highlight .-Color[class*=-C59] { + color: #5F5F5F +} + +div.highlight .-Color[class*=-BGC59] { + background-color: #5F5F5F +} + +div.highlight .-Color[class*=-C60] { + color: #5F5F87 +} + +div.highlight .-Color[class*=-BGC60] { + background-color: #5F5F87 +} + +div.highlight .-Color[class*=-C61] { + color: #5F5FAF +} + +div.highlight .-Color[class*=-BGC61] { + background-color: #5F5FAF +} + +div.highlight .-Color[class*=-C62] { + color: #5F5FD7 +} + +div.highlight .-Color[class*=-BGC62] { + background-color: #5F5FD7 +} + +div.highlight .-Color[class*=-C63] { + color: #5F5FFF +} + +div.highlight .-Color[class*=-BGC63] { + background-color: #5F5FFF +} + +div.highlight .-Color[class*=-C64] { + color: #5F8700 +} + +div.highlight .-Color[class*=-BGC64] { + background-color: #5F8700 +} + +div.highlight .-Color[class*=-C65] { + color: #5F875F +} + +div.highlight .-Color[class*=-BGC65] { + background-color: #5F875F +} + +div.highlight .-Color[class*=-C66] { + color: #5F8787 +} + +div.highlight .-Color[class*=-BGC66] { + background-color: #5F8787 +} + +div.highlight .-Color[class*=-C67] { + color: #5F87AF +} + +div.highlight .-Color[class*=-BGC67] { + background-color: #5F87AF +} + +div.highlight .-Color[class*=-C68] { + color: #5F87D7 +} + +div.highlight .-Color[class*=-BGC68] { + background-color: #5F87D7 +} + +div.highlight .-Color[class*=-C69] { + color: #5F87FF +} + +div.highlight .-Color[class*=-BGC69] { + background-color: #5F87FF +} + +div.highlight .-Color[class*=-C70] { + color: #5FAF00 +} + +div.highlight .-Color[class*=-BGC70] { + background-color: #5FAF00 +} + +div.highlight .-Color[class*=-C71] { + color: #5FAF5F +} + +div.highlight .-Color[class*=-BGC71] { + background-color: #5FAF5F +} + +div.highlight .-Color[class*=-C72] { + color: #5FAF87 +} + +div.highlight .-Color[class*=-BGC72] { + background-color: #5FAF87 +} + +div.highlight .-Color[class*=-C73] { + color: #5FAFAF +} + +div.highlight .-Color[class*=-BGC73] { + background-color: #5FAFAF +} + +div.highlight .-Color[class*=-C74] { + color: #5FAFD7 +} + +div.highlight .-Color[class*=-BGC74] { + background-color: #5FAFD7 +} + +div.highlight .-Color[class*=-C75] { + color: #5FAFFF +} + +div.highlight .-Color[class*=-BGC75] { + background-color: #5FAFFF +} + +div.highlight .-Color[class*=-C76] { + color: #5FD700 +} + +div.highlight .-Color[class*=-BGC76] { + background-color: #5FD700 +} + +div.highlight .-Color[class*=-C77] { + color: #5FD75F +} + +div.highlight .-Color[class*=-BGC77] { + background-color: #5FD75F +} + +div.highlight .-Color[class*=-C78] { + color: #5FD787 +} + +div.highlight .-Color[class*=-BGC78] { + background-color: #5FD787 +} + +div.highlight .-Color[class*=-C79] { + color: #5FD7AF +} + +div.highlight .-Color[class*=-BGC79] { + background-color: #5FD7AF +} + +div.highlight .-Color[class*=-C80] { + color: #5FD7D7 +} + +div.highlight .-Color[class*=-BGC80] { + background-color: #5FD7D7 +} + +div.highlight .-Color[class*=-C81] { + color: #5FD7FF +} + +div.highlight .-Color[class*=-BGC81] { + background-color: #5FD7FF +} + +div.highlight .-Color[class*=-C82] { + color: #5FFF00 +} + +div.highlight .-Color[class*=-BGC82] { + background-color: #5FFF00 +} + +div.highlight .-Color[class*=-C83] { + color: #5FFF5F +} + +div.highlight .-Color[class*=-BGC83] { + background-color: #5FFF5F +} + +div.highlight .-Color[class*=-C84] { + color: #5FFF87 +} + +div.highlight .-Color[class*=-BGC84] { + background-color: #5FFF87 +} + +div.highlight .-Color[class*=-C85] { + color: #5FFFAF +} + +div.highlight .-Color[class*=-BGC85] { + background-color: #5FFFAF +} + +div.highlight .-Color[class*=-C86] { + color: #5FFFD7 +} + +div.highlight .-Color[class*=-BGC86] { + background-color: #5FFFD7 +} + +div.highlight .-Color[class*=-C87] { + color: #5FFFFF +} + +div.highlight .-Color[class*=-BGC87] { + background-color: #5FFFFF +} + +div.highlight .-Color[class*=-C88] { + color: #870000 +} + +div.highlight .-Color[class*=-BGC88] { + background-color: #870000 +} + +div.highlight .-Color[class*=-C89] { + color: #87005F +} + +div.highlight .-Color[class*=-BGC89] { + background-color: #87005F +} + +div.highlight .-Color[class*=-C90] { + color: #870087 +} + +div.highlight .-Color[class*=-BGC90] { + background-color: #870087 +} + +div.highlight .-Color[class*=-C91] { + color: #8700AF +} + +div.highlight .-Color[class*=-BGC91] { + background-color: #8700AF +} + +div.highlight .-Color[class*=-C92] { + color: #8700D7 +} + +div.highlight .-Color[class*=-BGC92] { + background-color: #8700D7 +} + +div.highlight .-Color[class*=-C93] { + color: #8700FF +} + +div.highlight .-Color[class*=-BGC93] { + background-color: #8700FF +} + +div.highlight .-Color[class*=-C94] { + color: #875F00 +} + +div.highlight .-Color[class*=-BGC94] { + background-color: #875F00 +} + +div.highlight .-Color[class*=-C95] { + color: #875F5F +} + +div.highlight .-Color[class*=-BGC95] { + background-color: #875F5F +} + +div.highlight .-Color[class*=-C96] { + color: #875F87 +} + +div.highlight .-Color[class*=-BGC96] { + background-color: #875F87 +} + +div.highlight .-Color[class*=-C97] { + color: #875FAF +} + +div.highlight .-Color[class*=-BGC97] { + background-color: #875FAF +} + +div.highlight .-Color[class*=-C98] { + color: #875FD7 +} + +div.highlight .-Color[class*=-BGC98] { + background-color: #875FD7 +} + +div.highlight .-Color[class*=-C99] { + color: #875FFF +} + +div.highlight .-Color[class*=-BGC99] { + background-color: #875FFF +} + +div.highlight .-Color[class*=-C100] { + color: #878700 +} + +div.highlight .-Color[class*=-BGC100] { + background-color: #878700 +} + +div.highlight .-Color[class*=-C101] { + color: #87875F +} + +div.highlight .-Color[class*=-BGC101] { + background-color: #87875F +} + +div.highlight .-Color[class*=-C102] { + color: #878787 +} + +div.highlight .-Color[class*=-BGC102] { + background-color: #878787 +} + +div.highlight .-Color[class*=-C103] { + color: #8787AF +} + +div.highlight .-Color[class*=-BGC103] { + background-color: #8787AF +} + +div.highlight .-Color[class*=-C104] { + color: #8787D7 +} + +div.highlight .-Color[class*=-BGC104] { + background-color: #8787D7 +} + +div.highlight .-Color[class*=-C105] { + color: #8787FF +} + +div.highlight .-Color[class*=-BGC105] { + background-color: #8787FF +} + +div.highlight .-Color[class*=-C106] { + color: #87AF00 +} + +div.highlight .-Color[class*=-BGC106] { + background-color: #87AF00 +} + +div.highlight .-Color[class*=-C107] { + color: #87AF5F +} + +div.highlight .-Color[class*=-BGC107] { + background-color: #87AF5F +} + +div.highlight .-Color[class*=-C108] { + color: #87AF87 +} + +div.highlight .-Color[class*=-BGC108] { + background-color: #87AF87 +} + +div.highlight .-Color[class*=-C109] { + color: #87AFAF +} + +div.highlight .-Color[class*=-BGC109] { + background-color: #87AFAF +} + +div.highlight .-Color[class*=-C110] { + color: #87AFD7 +} + +div.highlight .-Color[class*=-BGC110] { + background-color: #87AFD7 +} + +div.highlight .-Color[class*=-C111] { + color: #87AFFF +} + +div.highlight .-Color[class*=-BGC111] { + background-color: #87AFFF +} + +div.highlight .-Color[class*=-C112] { + color: #87D700 +} + +div.highlight .-Color[class*=-BGC112] { + background-color: #87D700 +} + +div.highlight .-Color[class*=-C113] { + color: #87D75F +} + +div.highlight .-Color[class*=-BGC113] { + background-color: #87D75F +} + +div.highlight .-Color[class*=-C114] { + color: #87D787 +} + +div.highlight .-Color[class*=-BGC114] { + background-color: #87D787 +} + +div.highlight .-Color[class*=-C115] { + color: #87D7AF +} + +div.highlight .-Color[class*=-BGC115] { + background-color: #87D7AF +} + +div.highlight .-Color[class*=-C116] { + color: #87D7D7 +} + +div.highlight .-Color[class*=-BGC116] { + background-color: #87D7D7 +} + +div.highlight .-Color[class*=-C117] { + color: #87D7FF +} + +div.highlight .-Color[class*=-BGC117] { + background-color: #87D7FF +} + +div.highlight .-Color[class*=-C118] { + color: #87FF00 +} + +div.highlight .-Color[class*=-BGC118] { + background-color: #87FF00 +} + +div.highlight .-Color[class*=-C119] { + color: #87FF5F +} + +div.highlight .-Color[class*=-BGC119] { + background-color: #87FF5F +} + +div.highlight .-Color[class*=-C120] { + color: #87FF87 +} + +div.highlight .-Color[class*=-BGC120] { + background-color: #87FF87 +} + +div.highlight .-Color[class*=-C121] { + color: #87FFAF +} + +div.highlight .-Color[class*=-BGC121] { + background-color: #87FFAF +} + +div.highlight .-Color[class*=-C122] { + color: #87FFD7 +} + +div.highlight .-Color[class*=-BGC122] { + background-color: #87FFD7 +} + +div.highlight .-Color[class*=-C123] { + color: #87FFFF +} + +div.highlight .-Color[class*=-BGC123] { + background-color: #87FFFF +} + +div.highlight .-Color[class*=-C124] { + color: #AF0000 +} + +div.highlight .-Color[class*=-BGC124] { + background-color: #AF0000 +} + +div.highlight .-Color[class*=-C125] { + color: #AF005F +} + +div.highlight .-Color[class*=-BGC125] { + background-color: #AF005F +} + +div.highlight .-Color[class*=-C126] { + color: #AF0087 +} + +div.highlight .-Color[class*=-BGC126] { + background-color: #AF0087 +} + +div.highlight .-Color[class*=-C127] { + color: #AF00AF +} + +div.highlight .-Color[class*=-BGC127] { + background-color: #AF00AF +} + +div.highlight .-Color[class*=-C128] { + color: #AF00D7 +} + +div.highlight .-Color[class*=-BGC128] { + background-color: #AF00D7 +} + +div.highlight .-Color[class*=-C129] { + color: #AF00FF +} + +div.highlight .-Color[class*=-BGC129] { + background-color: #AF00FF +} + +div.highlight .-Color[class*=-C130] { + color: #AF5F00 +} + +div.highlight .-Color[class*=-BGC130] { + background-color: #AF5F00 +} + +div.highlight .-Color[class*=-C131] { + color: #AF5F5F +} + +div.highlight .-Color[class*=-BGC131] { + background-color: #AF5F5F +} + +div.highlight .-Color[class*=-C132] { + color: #AF5F87 +} + +div.highlight .-Color[class*=-BGC132] { + background-color: #AF5F87 +} + +div.highlight .-Color[class*=-C133] { + color: #AF5FAF +} + +div.highlight .-Color[class*=-BGC133] { + background-color: #AF5FAF +} + +div.highlight .-Color[class*=-C134] { + color: #AF5FD7 +} + +div.highlight .-Color[class*=-BGC134] { + background-color: #AF5FD7 +} + +div.highlight .-Color[class*=-C135] { + color: #AF5FFF +} + +div.highlight .-Color[class*=-BGC135] { + background-color: #AF5FFF +} + +div.highlight .-Color[class*=-C136] { + color: #AF8700 +} + +div.highlight .-Color[class*=-BGC136] { + background-color: #AF8700 +} + +div.highlight .-Color[class*=-C137] { + color: #AF875F +} + +div.highlight .-Color[class*=-BGC137] { + background-color: #AF875F +} + +div.highlight .-Color[class*=-C138] { + color: #AF8787 +} + +div.highlight .-Color[class*=-BGC138] { + background-color: #AF8787 +} + +div.highlight .-Color[class*=-C139] { + color: #AF87AF +} + +div.highlight .-Color[class*=-BGC139] { + background-color: #AF87AF +} + +div.highlight .-Color[class*=-C140] { + color: #AF87D7 +} + +div.highlight .-Color[class*=-BGC140] { + background-color: #AF87D7 +} + +div.highlight .-Color[class*=-C141] { + color: #AF87FF +} + +div.highlight .-Color[class*=-BGC141] { + background-color: #AF87FF +} + +div.highlight .-Color[class*=-C142] { + color: #AFAF00 +} + +div.highlight .-Color[class*=-BGC142] { + background-color: #AFAF00 +} + +div.highlight .-Color[class*=-C143] { + color: #AFAF5F +} + +div.highlight .-Color[class*=-BGC143] { + background-color: #AFAF5F +} + +div.highlight .-Color[class*=-C144] { + color: #AFAF87 +} + +div.highlight .-Color[class*=-BGC144] { + background-color: #AFAF87 +} + +div.highlight .-Color[class*=-C145] { + color: #AFAFAF +} + +div.highlight .-Color[class*=-BGC145] { + background-color: #AFAFAF +} + +div.highlight .-Color[class*=-C146] { + color: #AFAFD7 +} + +div.highlight .-Color[class*=-BGC146] { + background-color: #AFAFD7 +} + +div.highlight .-Color[class*=-C147] { + color: #AFAFFF +} + +div.highlight .-Color[class*=-BGC147] { + background-color: #AFAFFF +} + +div.highlight .-Color[class*=-C148] { + color: #AFD700 +} + +div.highlight .-Color[class*=-BGC148] { + background-color: #AFD700 +} + +div.highlight .-Color[class*=-C149] { + color: #AFD75F +} + +div.highlight .-Color[class*=-BGC149] { + background-color: #AFD75F +} + +div.highlight .-Color[class*=-C150] { + color: #AFD787 +} + +div.highlight .-Color[class*=-BGC150] { + background-color: #AFD787 +} + +div.highlight .-Color[class*=-C151] { + color: #AFD7AF +} + +div.highlight .-Color[class*=-BGC151] { + background-color: #AFD7AF +} + +div.highlight .-Color[class*=-C152] { + color: #AFD7D7 +} + +div.highlight .-Color[class*=-BGC152] { + background-color: #AFD7D7 +} + +div.highlight .-Color[class*=-C153] { + color: #AFD7FF +} + +div.highlight .-Color[class*=-BGC153] { + background-color: #AFD7FF +} + +div.highlight .-Color[class*=-C154] { + color: #AFFF00 +} + +div.highlight .-Color[class*=-BGC154] { + background-color: #AFFF00 +} + +div.highlight .-Color[class*=-C155] { + color: #AFFF5F +} + +div.highlight .-Color[class*=-BGC155] { + background-color: #AFFF5F +} + +div.highlight .-Color[class*=-C156] { + color: #AFFF87 +} + +div.highlight .-Color[class*=-BGC156] { + background-color: #AFFF87 +} + +div.highlight .-Color[class*=-C157] { + color: #AFFFAF +} + +div.highlight .-Color[class*=-BGC157] { + background-color: #AFFFAF +} + +div.highlight .-Color[class*=-C158] { + color: #AFFFD7 +} + +div.highlight .-Color[class*=-BGC158] { + background-color: #AFFFD7 +} + +div.highlight .-Color[class*=-C159] { + color: #AFFFFF +} + +div.highlight .-Color[class*=-BGC159] { + background-color: #AFFFFF +} + +div.highlight .-Color[class*=-C160] { + color: #D70000 +} + +div.highlight .-Color[class*=-BGC160] { + background-color: #D70000 +} + +div.highlight .-Color[class*=-C161] { + color: #D7005F +} + +div.highlight .-Color[class*=-BGC161] { + background-color: #D7005F +} + +div.highlight .-Color[class*=-C162] { + color: #D70087 +} + +div.highlight .-Color[class*=-BGC162] { + background-color: #D70087 +} + +div.highlight .-Color[class*=-C163] { + color: #D700AF +} + +div.highlight .-Color[class*=-BGC163] { + background-color: #D700AF +} + +div.highlight .-Color[class*=-C164] { + color: #D700D7 +} + +div.highlight .-Color[class*=-BGC164] { + background-color: #D700D7 +} + +div.highlight .-Color[class*=-C165] { + color: #D700FF +} + +div.highlight .-Color[class*=-BGC165] { + background-color: #D700FF +} + +div.highlight .-Color[class*=-C166] { + color: #D75F00 +} + +div.highlight .-Color[class*=-BGC166] { + background-color: #D75F00 +} + +div.highlight .-Color[class*=-C167] { + color: #D75F5F +} + +div.highlight .-Color[class*=-BGC167] { + background-color: #D75F5F +} + +div.highlight .-Color[class*=-C168] { + color: #D75F87 +} + +div.highlight .-Color[class*=-BGC168] { + background-color: #D75F87 +} + +div.highlight .-Color[class*=-C169] { + color: #D75FAF +} + +div.highlight .-Color[class*=-BGC169] { + background-color: #D75FAF +} + +div.highlight .-Color[class*=-C170] { + color: #D75FD7 +} + +div.highlight .-Color[class*=-BGC170] { + background-color: #D75FD7 +} + +div.highlight .-Color[class*=-C171] { + color: #D75FFF +} + +div.highlight .-Color[class*=-BGC171] { + background-color: #D75FFF +} + +div.highlight .-Color[class*=-C172] { + color: #D78700 +} + +div.highlight .-Color[class*=-BGC172] { + background-color: #D78700 +} + +div.highlight .-Color[class*=-C173] { + color: #D7875F +} + +div.highlight .-Color[class*=-BGC173] { + background-color: #D7875F +} + +div.highlight .-Color[class*=-C174] { + color: #D78787 +} + +div.highlight .-Color[class*=-BGC174] { + background-color: #D78787 +} + +div.highlight .-Color[class*=-C175] { + color: #D787AF +} + +div.highlight .-Color[class*=-BGC175] { + background-color: #D787AF +} + +div.highlight .-Color[class*=-C176] { + color: #D787D7 +} + +div.highlight .-Color[class*=-BGC176] { + background-color: #D787D7 +} + +div.highlight .-Color[class*=-C177] { + color: #D787FF +} + +div.highlight .-Color[class*=-BGC177] { + background-color: #D787FF +} + +div.highlight .-Color[class*=-C178] { + color: #D7AF00 +} + +div.highlight .-Color[class*=-BGC178] { + background-color: #D7AF00 +} + +div.highlight .-Color[class*=-C179] { + color: #D7AF5F +} + +div.highlight .-Color[class*=-BGC179] { + background-color: #D7AF5F +} + +div.highlight .-Color[class*=-C180] { + color: #D7AF87 +} + +div.highlight .-Color[class*=-BGC180] { + background-color: #D7AF87 +} + +div.highlight .-Color[class*=-C181] { + color: #D7AFAF +} + +div.highlight .-Color[class*=-BGC181] { + background-color: #D7AFAF +} + +div.highlight .-Color[class*=-C182] { + color: #D7AFD7 +} + +div.highlight .-Color[class*=-BGC182] { + background-color: #D7AFD7 +} + +div.highlight .-Color[class*=-C183] { + color: #D7AFFF +} + +div.highlight .-Color[class*=-BGC183] { + background-color: #D7AFFF +} + +div.highlight .-Color[class*=-C184] { + color: #D7D700 +} + +div.highlight .-Color[class*=-BGC184] { + background-color: #D7D700 +} + +div.highlight .-Color[class*=-C185] { + color: #D7D75F +} + +div.highlight .-Color[class*=-BGC185] { + background-color: #D7D75F +} + +div.highlight .-Color[class*=-C186] { + color: #D7D787 +} + +div.highlight .-Color[class*=-BGC186] { + background-color: #D7D787 +} + +div.highlight .-Color[class*=-C187] { + color: #D7D7AF +} + +div.highlight .-Color[class*=-BGC187] { + background-color: #D7D7AF +} + +div.highlight .-Color[class*=-C188] { + color: #D7D7D7 +} + +div.highlight .-Color[class*=-BGC188] { + background-color: #D7D7D7 +} + +div.highlight .-Color[class*=-C189] { + color: #D7D7FF +} + +div.highlight .-Color[class*=-BGC189] { + background-color: #D7D7FF +} + +div.highlight .-Color[class*=-C190] { + color: #D7FF00 +} + +div.highlight .-Color[class*=-BGC190] { + background-color: #D7FF00 +} + +div.highlight .-Color[class*=-C191] { + color: #D7FF5F +} + +div.highlight .-Color[class*=-BGC191] { + background-color: #D7FF5F +} + +div.highlight .-Color[class*=-C192] { + color: #D7FF87 +} + +div.highlight .-Color[class*=-BGC192] { + background-color: #D7FF87 +} + +div.highlight .-Color[class*=-C193] { + color: #D7FFAF +} + +div.highlight .-Color[class*=-BGC193] { + background-color: #D7FFAF +} + +div.highlight .-Color[class*=-C194] { + color: #D7FFD7 +} + +div.highlight .-Color[class*=-BGC194] { + background-color: #D7FFD7 +} + +div.highlight .-Color[class*=-C195] { + color: #D7FFFF +} + +div.highlight .-Color[class*=-BGC195] { + background-color: #D7FFFF +} + +div.highlight .-Color[class*=-C196] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC196] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C197] { + color: #FF005F +} + +div.highlight .-Color[class*=-BGC197] { + background-color: #FF005F +} + +div.highlight .-Color[class*=-C198] { + color: #FF0087 +} + +div.highlight .-Color[class*=-BGC198] { + background-color: #FF0087 +} + +div.highlight .-Color[class*=-C199] { + color: #FF00AF +} + +div.highlight .-Color[class*=-BGC199] { + background-color: #FF00AF +} + +div.highlight .-Color[class*=-C200] { + color: #FF00D7 +} + +div.highlight .-Color[class*=-BGC200] { + background-color: #FF00D7 +} + +div.highlight .-Color[class*=-C201] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC201] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C202] { + color: #FF5F00 +} + +div.highlight .-Color[class*=-BGC202] { + background-color: #FF5F00 +} + +div.highlight .-Color[class*=-C203] { + color: #FF5F5F +} + +div.highlight .-Color[class*=-BGC203] { + background-color: #FF5F5F +} + +div.highlight .-Color[class*=-C204] { + color: #FF5F87 +} + +div.highlight .-Color[class*=-BGC204] { + background-color: #FF5F87 +} + +div.highlight .-Color[class*=-C205] { + color: #FF5FAF +} + +div.highlight .-Color[class*=-BGC205] { + background-color: #FF5FAF +} + +div.highlight .-Color[class*=-C206] { + color: #FF5FD7 +} + +div.highlight .-Color[class*=-BGC206] { + background-color: #FF5FD7 +} + +div.highlight .-Color[class*=-C207] { + color: #FF5FFF +} + +div.highlight .-Color[class*=-BGC207] { + background-color: #FF5FFF +} + +div.highlight .-Color[class*=-C208] { + color: #FF8700 +} + +div.highlight .-Color[class*=-BGC208] { + background-color: #FF8700 +} + +div.highlight .-Color[class*=-C209] { + color: #FF875F +} + +div.highlight .-Color[class*=-BGC209] { + background-color: #FF875F +} + +div.highlight .-Color[class*=-C210] { + color: #FF8787 +} + +div.highlight .-Color[class*=-BGC210] { + background-color: #FF8787 +} + +div.highlight .-Color[class*=-C211] { + color: #FF87AF +} + +div.highlight .-Color[class*=-BGC211] { + background-color: #FF87AF +} + +div.highlight .-Color[class*=-C212] { + color: #FF87D7 +} + +div.highlight .-Color[class*=-BGC212] { + background-color: #FF87D7 +} + +div.highlight .-Color[class*=-C213] { + color: #FF87FF +} + +div.highlight .-Color[class*=-BGC213] { + background-color: #FF87FF +} + +div.highlight .-Color[class*=-C214] { + color: #FFAF00 +} + +div.highlight .-Color[class*=-BGC214] { + background-color: #FFAF00 +} + +div.highlight .-Color[class*=-C215] { + color: #FFAF5F +} + +div.highlight .-Color[class*=-BGC215] { + background-color: #FFAF5F +} + +div.highlight .-Color[class*=-C216] { + color: #FFAF87 +} + +div.highlight .-Color[class*=-BGC216] { + background-color: #FFAF87 +} + +div.highlight .-Color[class*=-C217] { + color: #FFAFAF +} + +div.highlight .-Color[class*=-BGC217] { + background-color: #FFAFAF +} + +div.highlight .-Color[class*=-C218] { + color: #FFAFD7 +} + +div.highlight .-Color[class*=-BGC218] { + background-color: #FFAFD7 +} + +div.highlight .-Color[class*=-C219] { + color: #FFAFFF +} + +div.highlight .-Color[class*=-BGC219] { + background-color: #FFAFFF +} + +div.highlight .-Color[class*=-C220] { + color: #FFD700 +} + +div.highlight .-Color[class*=-BGC220] { + background-color: #FFD700 +} + +div.highlight .-Color[class*=-C221] { + color: #FFD75F +} + +div.highlight .-Color[class*=-BGC221] { + background-color: #FFD75F +} + +div.highlight .-Color[class*=-C222] { + color: #FFD787 +} + +div.highlight .-Color[class*=-BGC222] { + background-color: #FFD787 +} + +div.highlight .-Color[class*=-C223] { + color: #FFD7AF +} + +div.highlight .-Color[class*=-BGC223] { + background-color: #FFD7AF +} + +div.highlight .-Color[class*=-C224] { + color: #FFD7D7 +} + +div.highlight .-Color[class*=-BGC224] { + background-color: #FFD7D7 +} + +div.highlight .-Color[class*=-C225] { + color: #FFD7FF +} + +div.highlight .-Color[class*=-BGC225] { + background-color: #FFD7FF +} + +div.highlight .-Color[class*=-C226] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC226] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C227] { + color: #FFFF5F +} + +div.highlight .-Color[class*=-BGC227] { + background-color: #FFFF5F +} + +div.highlight .-Color[class*=-C228] { + color: #FFFF87 +} + +div.highlight .-Color[class*=-BGC228] { + background-color: #FFFF87 +} + +div.highlight .-Color[class*=-C229] { + color: #FFFFAF +} + +div.highlight .-Color[class*=-BGC229] { + background-color: #FFFFAF +} + +div.highlight .-Color[class*=-C230] { + color: #FFFFD7 +} + +div.highlight .-Color[class*=-BGC230] { + background-color: #FFFFD7 +} + +div.highlight .-Color[class*=-C231] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC231] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C232] { + color: #080808 +} + +div.highlight .-Color[class*=-BGC232] { + background-color: #080808 +} + +div.highlight .-Color[class*=-C233] { + color: #121212 +} + +div.highlight .-Color[class*=-BGC233] { + background-color: #121212 +} + +div.highlight .-Color[class*=-C234] { + color: #1C1C1C +} + +div.highlight .-Color[class*=-BGC234] { + background-color: #1C1C1C +} + +div.highlight .-Color[class*=-C235] { + color: #262626 +} + +div.highlight .-Color[class*=-BGC235] { + background-color: #262626 +} + +div.highlight .-Color[class*=-C236] { + color: #303030 +} + +div.highlight .-Color[class*=-BGC236] { + background-color: #303030 +} + +div.highlight .-Color[class*=-C237] { + color: #3A3A3A +} + +div.highlight .-Color[class*=-BGC237] { + background-color: #3A3A3A +} + +div.highlight .-Color[class*=-C238] { + color: #444444 +} + +div.highlight .-Color[class*=-BGC238] { + background-color: #444444 +} + +div.highlight .-Color[class*=-C239] { + color: #4E4E4E +} + +div.highlight .-Color[class*=-BGC239] { + background-color: #4E4E4E +} + +div.highlight .-Color[class*=-C240] { + color: #585858 +} + +div.highlight .-Color[class*=-BGC240] { + background-color: #585858 +} + +div.highlight .-Color[class*=-C241] { + color: #626262 +} + +div.highlight .-Color[class*=-BGC241] { + background-color: #626262 +} + +div.highlight .-Color[class*=-C242] { + color: #6C6C6C +} + +div.highlight .-Color[class*=-BGC242] { + background-color: #6C6C6C +} + +div.highlight .-Color[class*=-C243] { + color: #767676 +} + +div.highlight .-Color[class*=-BGC243] { + background-color: #767676 +} + +div.highlight .-Color[class*=-C244] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC244] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C245] { + color: #8A8A8A +} + +div.highlight .-Color[class*=-BGC245] { + background-color: #8A8A8A +} + +div.highlight .-Color[class*=-C246] { + color: #949494 +} + +div.highlight .-Color[class*=-BGC246] { + background-color: #949494 +} + +div.highlight .-Color[class*=-C247] { + color: #9E9E9E +} + +div.highlight .-Color[class*=-BGC247] { + background-color: #9E9E9E +} + +div.highlight .-Color[class*=-C248] { + color: #A8A8A8 +} + +div.highlight .-Color[class*=-BGC248] { + background-color: #A8A8A8 +} + +div.highlight .-Color[class*=-C249] { + color: #B2B2B2 +} + +div.highlight .-Color[class*=-BGC249] { + background-color: #B2B2B2 +} + +div.highlight .-Color[class*=-C250] { + color: #BCBCBC +} + +div.highlight .-Color[class*=-BGC250] { + background-color: #BCBCBC +} + +div.highlight .-Color[class*=-C251] { + color: #C6C6C6 +} + +div.highlight .-Color[class*=-BGC251] { + background-color: #C6C6C6 +} + +div.highlight .-Color[class*=-C252] { + color: #D0D0D0 +} + +div.highlight .-Color[class*=-BGC252] { + background-color: #D0D0D0 +} + +div.highlight .-Color[class*=-C253] { + color: #DADADA +} + +div.highlight .-Color[class*=-BGC253] { + background-color: #DADADA +} + +div.highlight .-Color[class*=-C254] { + color: #E4E4E4 +} + +div.highlight .-Color[class*=-BGC254] { + background-color: #E4E4E4 +} + +div.highlight .-Color[class*=-C255] { + color: #EEEEEE +} + +div.highlight .-Color[class*=-BGC255] { + background-color: #EEEEEE +} diff --git a/branch/ignore/singlehtml/_static/plus.png b/branch/ignore/singlehtml/_static/plus.png new file mode 100644 index 0000000..7107cec Binary files /dev/null and b/branch/ignore/singlehtml/_static/plus.png differ diff --git a/branch/ignore/singlehtml/_static/pygments.css b/branch/ignore/singlehtml/_static/pygments.css new file mode 100644 index 0000000..84ab303 --- /dev/null +++ b/branch/ignore/singlehtml/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/branch/ignore/singlehtml/_static/searchtools.js b/branch/ignore/singlehtml/_static/searchtools.js new file mode 100644 index 0000000..7918c3f --- /dev/null +++ b/branch/ignore/singlehtml/_static/searchtools.js @@ -0,0 +1,574 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + `Search finished, found ${resultCount} page(s) matching the search query.` + ); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent !== undefined) return docContent.textContent; + console.warn( + "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + /** + * execute search (requires search index to be loaded) + */ + query: (query) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + // array of [docname, title, anchor, descr, score, filename] + let results = []; + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + let score = Math.round(100 * queryLower.length / title.length) + results.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id] of foundEntries) { + let score = Math.round(100 * queryLower.length / entry.length) + results.push([ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // lookup as object + objectTerms.forEach((term) => + results.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item))); + + // now sort the results by score (in opposite order of appearance, since the + // display function below uses pop() to retrieve items) and then + // alphabetically + results.sort((a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; + }); + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + results = results.reverse(); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord) && !terms[word]) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord) && !titleTerms[word]) + arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); + }); + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1) + fileMap.get(file).push(word); + else fileMap.set(file, [word]); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords) => { + const text = Search.htmlToText(htmlText); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/branch/ignore/singlehtml/_static/sphinx_highlight.js b/branch/ignore/singlehtml/_static/sphinx_highlight.js new file mode 100644 index 0000000..8a96c69 --- /dev/null +++ b/branch/ignore/singlehtml/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/branch/ignore/singlehtml/_static/sphinx_lesson.css b/branch/ignore/singlehtml/_static/sphinx_lesson.css new file mode 100644 index 0000000..14b20c6 --- /dev/null +++ b/branch/ignore/singlehtml/_static/sphinx_lesson.css @@ -0,0 +1,51 @@ +/* sphinx_lesson.css */ + +body.wy-body-for-nav img.with-border { + border: 2px solid; +} + +.rst-content .admonition-no-content { + padding-bottom: 0px; +} + +.rst-content .demo > .admonition-title::before { + content: "\01F440"; /* Eyes */ } +.rst-content .type-along > .admonition-title::before { + content: "\02328\0FE0F"; /* Keyboard */ } +.rst-content .exercise > .admonition-title::before { + content: "\0270D\0FE0F"; /* Hand */ } +.rst-content .solution > .admonition-title::before { + content: "\02714\0FE0E"; /* Check mark */ } +.rst-content .homework > .admonition-title::before { + content: "\01F4DD"; /* Memo */ } +.rst-content .discussion > .admonition-title::before { + content: "\01F4AC"; /* Speech balloon */ } +.rst-content .questions > .admonition-title::before { + content: "\02753\0FE0E"; /* Question mark */ } +.rst-content .prerequisites > .admonition-title::before { + content: "\02699"; /* Gear */ } +.rst-content .seealso > .admonition-title::before { + content: "\027A1\0FE0E"; /* Question mark */ } + + +/* instructor-note */ +.rst-content .instructor-note { + background: #e7e7e7; +} +.rst-content .instructor-note > .admonition-title { + background: #6a6a6a; +} +.rst-content .instructor-note > .admonition-title::before { + content: ""; +} + + +/* sphinx_toggle_button, make the font white */ +.rst-content .toggle.admonition button.toggle-button { + color: white; +} + +/* sphinx-togglebutton, remove underflow when toggled to hidden mode */ +.rst-content .admonition.toggle-hidden { + padding-bottom: 0px; +} diff --git a/branch/ignore/singlehtml/_static/sphinx_rtd_theme_ext_color_contrast.css b/branch/ignore/singlehtml/_static/sphinx_rtd_theme_ext_color_contrast.css new file mode 100644 index 0000000..e68feb8 --- /dev/null +++ b/branch/ignore/singlehtml/_static/sphinx_rtd_theme_ext_color_contrast.css @@ -0,0 +1,47 @@ +/* The following are for web accessibility of sphinx_rtd_theme: they + * solve some of the most frequent contrast issues. Remove when this + * solved: + * https://github.com/readthedocs/sphinx_rtd_theme/issues/971 + */ +/* background: #fcfcfc, note boxes #E7F2FA */ +a { color: #2573A7; } /* original #2980B9, #1F5C84; */ +body { color: #242424; } /* original #404040, #383838 */ +.wy-side-nav-search>a, .wy-side-nav-search .wy-dropdown>a { + color: #ffffff; +} /* original #fcfcfc */ +footer { color: #737373; } /* original gray=#808080*/ +footer span.commit code, footer span.commit .rst-content tt, .rst-content footer span.commit tt { + color: #737373; +} /* original gray=#808080*/ +.rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal { + color: #AB2314; +} +/* Sidebar background */ +.wy-side-nav-search { background-color: #277CB4;} + +/* Same, but for pygments */ +.highlight .ch { color: #3E7A89; } /* #! line */ +.highlight .c1 { color: #3E7A89; } /* also comments */ +.highlight .nv { color: #AD3ECC; } /* variable */ +.highlight .gp { color: #B45608; } /* prompt character, $*/ +.highlight .si { color: #3975B1; } /* ${} variable text */ +.highlight .nc { color: #0C78A7; } + +/* Sphinx admonitions */ +/* warning */ +.wy-alert.wy-alert-warning .wy-alert-title, .rst-content .wy-alert-warning.note .wy-alert-title, .rst-content .attention .wy-alert-title, .rst-content .caution .wy-alert-title, .rst-content .wy-alert-warning.danger .wy-alert-title, .rst-content .wy-alert-warning.error .wy-alert-title, .rst-content .wy-alert-warning.hint .wy-alert-title, .rst-content .wy-alert-warning.important .wy-alert-title, .rst-content .wy-alert-warning.tip .wy-alert-title, .rst-content .warning .wy-alert-title, .rst-content .wy-alert-warning.seealso .wy-alert-title, .rst-content .admonition-todo .wy-alert-title, .rst-content .wy-alert-warning.admonition .wy-alert-title, .wy-alert.wy-alert-warning .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-warning .admonition-title, .rst-content .wy-alert-warning.note .admonition-title, .rst-content .attention .admonition-title, .rst-content .caution .admonition-title, .rst-content .wy-alert-warning.danger .admonition-title, .rst-content .wy-alert-warning.error .admonition-title, .rst-content .wy-alert-warning.hint .admonition-title, .rst-content .wy-alert-warning.important .admonition-title, .rst-content .wy-alert-warning.tip .admonition-title, .rst-content .warning .admonition-title, .rst-content .wy-alert-warning.seealso .admonition-title, .rst-content .admonition-todo .admonition-title, .rst-content .wy-alert-warning.admonition .admonition-title { + background: #B15E16; } +/* important */ +.wy-alert.wy-alert-success .wy-alert-title, .rst-content .wy-alert-success.note .wy-alert-title, .rst-content .wy-alert-success.attention .wy-alert-title, .rst-content .wy-alert-success.caution .wy-alert-title, .rst-content .wy-alert-success.danger .wy-alert-title, .rst-content .wy-alert-success.error .wy-alert-title, .rst-content .hint .wy-alert-title, .rst-content .important .wy-alert-title, .rst-content .tip .wy-alert-title, .rst-content .wy-alert-success.warning .wy-alert-title, .rst-content .wy-alert-success.seealso .wy-alert-title, .rst-content .wy-alert-success.admonition-todo .wy-alert-title, .rst-content .wy-alert-success.admonition .wy-alert-title, .wy-alert.wy-alert-success .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-success .admonition-title, .rst-content .wy-alert-success.note .admonition-title, .rst-content .wy-alert-success.attention .admonition-title, .rst-content .wy-alert-success.caution .admonition-title, .rst-content .wy-alert-success.danger .admonition-title, .rst-content .wy-alert-success.error .admonition-title, .rst-content .hint .admonition-title, .rst-content .important .admonition-title, .rst-content .tip .admonition-title, .rst-content .wy-alert-success.warning .admonition-title, .rst-content .wy-alert-success.seealso .admonition-title, .rst-content .wy-alert-success.admonition-todo .admonition-title, .rst-content .wy-alert-success.admonition .admonition-title { + background: #12826C; } +/* seealso, note, etc */ +.wy-alert.wy-alert-info .wy-alert-title, .rst-content .note .wy-alert-title, .rst-content .wy-alert-info.attention .wy-alert-title, .rst-content .wy-alert-info.caution .wy-alert-title, .rst-content .wy-alert-info.danger .wy-alert-title, .rst-content .wy-alert-info.error .wy-alert-title, .rst-content .wy-alert-info.hint .wy-alert-title, .rst-content .wy-alert-info.important .wy-alert-title, .rst-content .wy-alert-info.tip .wy-alert-title, .rst-content .wy-alert-info.warning .wy-alert-title, .rst-content .seealso .wy-alert-title, .rst-content .wy-alert-info.admonition-todo .wy-alert-title, .rst-content .wy-alert-info.admonition .wy-alert-title, .wy-alert.wy-alert-info .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-info .admonition-title, .rst-content .note .admonition-title, .rst-content .wy-alert-info.attention .admonition-title, .rst-content .wy-alert-info.caution .admonition-title, .rst-content .wy-alert-info.danger .admonition-title, .rst-content .wy-alert-info.error .admonition-title, .rst-content .wy-alert-info.hint .admonition-title, .rst-content .wy-alert-info.important .admonition-title, .rst-content .wy-alert-info.tip .admonition-title, .rst-content .wy-alert-info.warning .admonition-title, .rst-content .seealso .admonition-title, .rst-content .wy-alert-info.admonition-todo .admonition-title, .rst-content .wy-alert-info.admonition .admonition-title { + background: #277CB4; } +/* error, danger */ +.rst-content .danger .admonition-title, .rst-content .danger .wy-alert-title, .rst-content .error .admonition-title, .rst-content .error .wy-alert-title, .rst-content .wy-alert-danger.admonition-todo .admonition-title, .rst-content .wy-alert-danger.admonition-todo .wy-alert-title, .rst-content .wy-alert-danger.admonition .admonition-title, .rst-content .wy-alert-danger.admonition .wy-alert-title, .rst-content .wy-alert-danger.attention .admonition-title, .rst-content .wy-alert-danger.attention .wy-alert-title, .rst-content .wy-alert-danger.caution .admonition-title, .rst-content .wy-alert-danger.caution .wy-alert-title, .rst-content .wy-alert-danger.hint .admonition-title, .rst-content .wy-alert-danger.hint .wy-alert-title, .rst-content .wy-alert-danger.important .admonition-title, .rst-content .wy-alert-danger.important .wy-alert-title, .rst-content .wy-alert-danger.note .admonition-title, .rst-content .wy-alert-danger.note .wy-alert-title, .rst-content .wy-alert-danger.seealso .admonition-title, .rst-content .wy-alert-danger.seealso .wy-alert-title, .rst-content .wy-alert-danger.tip .admonition-title, .rst-content .wy-alert-danger.tip .wy-alert-title, .rst-content .wy-alert-danger.warning .admonition-title, .rst-content .wy-alert-danger.warning .wy-alert-title, .rst-content .wy-alert.wy-alert-danger .admonition-title, .wy-alert.wy-alert-danger .rst-content .admonition-title, .wy-alert.wy-alert-danger .wy-alert-title { + background: #e31704; +} + +/* Generic admonition titles */ +.wy-alert-title, .rst-content .admonition-title { + background: #277CB4; } diff --git a/branch/ignore/singlehtml/_static/tabs.css b/branch/ignore/singlehtml/_static/tabs.css new file mode 100644 index 0000000..957ba60 --- /dev/null +++ b/branch/ignore/singlehtml/_static/tabs.css @@ -0,0 +1,89 @@ +.sphinx-tabs { + margin-bottom: 1rem; +} + +[role="tablist"] { + border-bottom: 1px solid #a0b3bf; +} + +.sphinx-tabs-tab { + position: relative; + font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; + color: #1D5C87; + line-height: 24px; + margin: 0; + font-size: 16px; + font-weight: 400; + background-color: rgba(255, 255, 255, 0); + border-radius: 5px 5px 0 0; + border: 0; + padding: 1rem 1.5rem; + margin-bottom: 0; +} + +.sphinx-tabs-tab[aria-selected="true"] { + font-weight: 700; + border: 1px solid #a0b3bf; + border-bottom: 1px solid white; + margin: -1px; + background-color: white; +} + +.sphinx-tabs-tab:focus { + z-index: 1; + outline-offset: 1px; +} + +.sphinx-tabs-panel { + position: relative; + padding: 1rem; + border: 1px solid #a0b3bf; + margin: 0px -1px -1px -1px; + border-radius: 0 0 5px 5px; + border-top: 0; + background: white; +} + +.sphinx-tabs-panel.code-tab { + padding: 0.4rem; +} + +.sphinx-tab img { + margin-bottom: 24 px; +} + +/* Dark theme preference styling */ + +@media (prefers-color-scheme: dark) { + body[data-theme="auto"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); + } + + body[data-theme="auto"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); + } + + body[data-theme="auto"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 1px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); + } +} + +/* Explicit dark theme styling */ + +body[data-theme="dark"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); +} + +body[data-theme="dark"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); +} + +body[data-theme="dark"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 2px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); +} diff --git a/branch/ignore/singlehtml/_static/tabs.js b/branch/ignore/singlehtml/_static/tabs.js new file mode 100644 index 0000000..48dc303 --- /dev/null +++ b/branch/ignore/singlehtml/_static/tabs.js @@ -0,0 +1,145 @@ +try { + var session = window.sessionStorage || {}; +} catch (e) { + var session = {}; +} + +window.addEventListener("DOMContentLoaded", () => { + const allTabs = document.querySelectorAll('.sphinx-tabs-tab'); + const tabLists = document.querySelectorAll('[role="tablist"]'); + + allTabs.forEach(tab => { + tab.addEventListener("click", changeTabs); + }); + + tabLists.forEach(tabList => { + tabList.addEventListener("keydown", keyTabs); + }); + + // Restore group tab selection from session + const lastSelected = session.getItem('sphinx-tabs-last-selected'); + if (lastSelected != null) selectNamedTabs(lastSelected); +}); + +/** + * Key focus left and right between sibling elements using arrows + * @param {Node} e the element in focus when key was pressed + */ +function keyTabs(e) { + const tab = e.target; + let nextTab = null; + if (e.keyCode === 39 || e.keyCode === 37) { + tab.setAttribute("tabindex", -1); + // Move right + if (e.keyCode === 39) { + nextTab = tab.nextElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.firstElementChild; + } + // Move left + } else if (e.keyCode === 37) { + nextTab = tab.previousElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.lastElementChild; + } + } + } + + if (nextTab !== null) { + nextTab.setAttribute("tabindex", 0); + nextTab.focus(); + } +} + +/** + * Select or deselect clicked tab. If a group tab + * is selected, also select tab in other tabLists. + * @param {Node} e the element that was clicked + */ +function changeTabs(e) { + // Use this instead of the element that was clicked, in case it's a child + const notSelected = this.getAttribute("aria-selected") === "false"; + const positionBefore = this.parentNode.getBoundingClientRect().top; + const notClosable = !this.parentNode.classList.contains("closeable"); + + deselectTabList(this); + + if (notSelected || notClosable) { + selectTab(this); + const name = this.getAttribute("name"); + selectNamedTabs(name, this.id); + + if (this.classList.contains("group-tab")) { + // Persist during session + session.setItem('sphinx-tabs-last-selected', name); + } + } + + const positionAfter = this.parentNode.getBoundingClientRect().top; + const positionDelta = positionAfter - positionBefore; + // Scroll to offset content resizing + window.scrollTo(0, window.scrollY + positionDelta); +} + +/** + * Select tab and show associated panel. + * @param {Node} tab tab to select + */ +function selectTab(tab) { + tab.setAttribute("aria-selected", true); + + // Show the associated panel + document + .getElementById(tab.getAttribute("aria-controls")) + .removeAttribute("hidden"); +} + +/** + * Hide the panels associated with all tabs within the + * tablist containing this tab. + * @param {Node} tab a tab within the tablist to deselect + */ +function deselectTabList(tab) { + const parent = tab.parentNode; + const grandparent = parent.parentNode; + + Array.from(parent.children) + .forEach(t => t.setAttribute("aria-selected", false)); + + Array.from(grandparent.children) + .slice(1) // Skip tablist + .forEach(panel => panel.setAttribute("hidden", true)); +} + +/** + * Select grouped tabs with the same name, but no the tab + * with the given id. + * @param {Node} name name of grouped tab to be selected + * @param {Node} clickedId id of clicked tab + */ +function selectNamedTabs(name, clickedId=null) { + const groupedTabs = document.querySelectorAll(`.sphinx-tabs-tab[name="${name}"]`); + const tabLists = Array.from(groupedTabs).map(tab => tab.parentNode); + + tabLists + .forEach(tabList => { + // Don't want to change the tabList containing the clicked tab + const clickedTab = tabList.querySelector(`[id="${clickedId}"]`); + if (clickedTab === null ) { + // Select first tab with matching name + const tab = tabList.querySelector(`.sphinx-tabs-tab[name="${name}"]`); + deselectTabList(tab); + selectTab(tab); + } + }) +} + +if (typeof exports === 'undefined') { + exports = {}; +} + +exports.keyTabs = keyTabs; +exports.changeTabs = changeTabs; +exports.selectTab = selectTab; +exports.deselectTabList = deselectTabList; +exports.selectNamedTabs = selectNamedTabs; diff --git a/branch/ignore/singlehtml/_static/togglebutton.css b/branch/ignore/singlehtml/_static/togglebutton.css new file mode 100644 index 0000000..54a6787 --- /dev/null +++ b/branch/ignore/singlehtml/_static/togglebutton.css @@ -0,0 +1,160 @@ +/** + * Admonition-based toggles + */ + +/* Visibility of the target */ +.admonition.toggle .admonition-title ~ * { + transition: opacity .3s, height .3s; +} + +/* Toggle buttons inside admonitions so we see the title */ +.admonition.toggle { + position: relative; +} + +/* Titles should cut off earlier to avoid overlapping w/ button */ +.admonition.toggle .admonition-title { + padding-right: 25%; + cursor: pointer; +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:hover { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 1%); +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:active { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 3%); +} + +/* Remove extra whitespace below the admonition title when hidden */ +.admonition.toggle-hidden { + padding-bottom: 0; +} + +.admonition.toggle-hidden .admonition-title { + margin-bottom: 0; +} + +/* hides all the content of a page until de-toggled */ +.admonition.toggle-hidden .admonition-title ~ * { + height: 0; + margin: 0; + opacity: 0; + visibility: hidden; +} + +/* General button style and position*/ +button.toggle-button { + /** + * Background and shape. By default there's no background + * but users can style as they wish + */ + background: none; + border: none; + outline: none; + + /* Positioning just inside the admonition title */ + position: absolute; + right: 0.5em; + padding: 0px; + border: none; + outline: none; +} + +/* Display the toggle hint on wide screens */ +@media (min-width: 768px) { + button.toggle-button.toggle-button-hidden:before { + content: attr(data-toggle-hint); /* This will be filled in by JS */ + font-size: .8em; + align-self: center; + } +} + +/* Icon behavior */ +.tb-icon { + transition: transform .2s ease-out; + height: 1.5em; + width: 1.5em; + stroke: currentColor; /* So that we inherit the color of other text */ +} + +/* The icon should point right when closed, down when open. */ +/* Open */ +.admonition.toggle button .tb-icon { + transform: rotate(90deg); +} + +/* Closed */ +.admonition.toggle button.toggle-button-hidden .tb-icon { + transform: rotate(0deg); +} + +/* With details toggles, we don't rotate the icon so it points right */ +details.toggle-details .tb-icon { + height: 1.4em; + width: 1.4em; + margin-top: 0.1em; /* To center the button vertically */ +} + + +/** + * Details-based toggles. + * In this case, we wrap elements with `.toggle` in a details block. + */ + +/* Details blocks */ +details.toggle-details { + margin: 1em 0; +} + + +details.toggle-details summary { + display: flex; + align-items: center; + cursor: pointer; + list-style: none; + border-radius: .2em; + border-left: 3px solid #1976d2; + background-color: rgb(204 204 204 / 10%); + padding: 0.2em 0.7em 0.3em 0.5em; /* Less padding on left because the SVG has left margin */ + font-size: 0.9em; +} + +details.toggle-details summary:hover { + background-color: rgb(204 204 204 / 20%); +} + +details.toggle-details summary:active { + background: rgb(204 204 204 / 28%); +} + +.toggle-details__summary-text { + margin-left: 0.2em; +} + +details.toggle-details[open] summary { + margin-bottom: .5em; +} + +details.toggle-details[open] summary .tb-icon { + transform: rotate(90deg); +} + +details.toggle-details[open] summary ~ * { + animation: toggle-fade-in .3s ease-out; +} + +@keyframes toggle-fade-in { + from {opacity: 0%;} + to {opacity: 100%;} +} + +/* Print rules - we hide all toggle button elements at print */ +@media print { + /* Always hide the summary so the button doesn't show up */ + details.toggle-details summary { + display: none; + } +} \ No newline at end of file diff --git a/branch/ignore/singlehtml/_static/togglebutton.js b/branch/ignore/singlehtml/_static/togglebutton.js new file mode 100644 index 0000000..215a7ee --- /dev/null +++ b/branch/ignore/singlehtml/_static/togglebutton.js @@ -0,0 +1,187 @@ +/** + * Add Toggle Buttons to elements + */ + +let toggleChevron = ` + + + +`; + +var initToggleItems = () => { + var itemsToToggle = document.querySelectorAll(togglebuttonSelector); + console.log(`[togglebutton]: Adding toggle buttons to ${itemsToToggle.length} items`) + // Add the button to each admonition and hook up a callback to toggle visibility + itemsToToggle.forEach((item, index) => { + if (item.classList.contains("admonition")) { + // If it's an admonition block, then we'll add a button inside + // Generate unique IDs for this item + var toggleID = `toggle-${index}`; + var buttonID = `button-${toggleID}`; + + item.setAttribute('id', toggleID); + if (!item.classList.contains("toggle")){ + item.classList.add("toggle"); + } + // This is the button that will be added to each item to trigger the toggle + var collapseButton = ` + `; + + title = item.querySelector(".admonition-title") + title.insertAdjacentHTML("beforeend", collapseButton); + thisButton = document.getElementById(buttonID); + + // Add click handlers for the button + admonition title (if admonition) + admonitionTitle = document.querySelector(`#${toggleID} > .admonition-title`) + if (admonitionTitle) { + // If an admonition, then make the whole title block clickable + admonitionTitle.addEventListener('click', toggleClickHandler); + admonitionTitle.dataset.target = toggleID + admonitionTitle.dataset.button = buttonID + } else { + // If not an admonition then we'll listen for the button click + thisButton.addEventListener('click', toggleClickHandler); + } + + // Now hide the item for this toggle button unless explicitly noted to show + if (!item.classList.contains("toggle-shown")) { + toggleHidden(thisButton); + } + } else { + // If not an admonition, wrap the block in a
block + // Define the structure of the details block and insert it as a sibling + var detailsBlock = ` +
+ + ${toggleChevron} + ${toggleHintShow} + +
`; + item.insertAdjacentHTML("beforebegin", detailsBlock); + + // Now move the toggle-able content inside of the details block + details = item.previousElementSibling + details.appendChild(item) + item.classList.add("toggle-details__container") + + // Set up a click trigger to change the text as needed + details.addEventListener('click', (click) => { + let parent = click.target.parentElement; + if (parent.tagName.toLowerCase() == "details") { + summary = parent.querySelector("summary"); + details = parent; + } else { + summary = parent; + details = parent.parentElement; + } + // Update the inner text for the proper hint + if (details.open) { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintShow; + } else { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintHide; + } + + }); + + // If we have a toggle-shown class, open details block should be open + if (item.classList.contains("toggle-shown")) { + details.click(); + } + } + }) +}; + +// This should simply add / remove the collapsed class and change the button text +var toggleHidden = (button) => { + target = button.dataset['target'] + var itemToToggle = document.getElementById(target); + if (itemToToggle.classList.contains("toggle-hidden")) { + itemToToggle.classList.remove("toggle-hidden"); + button.classList.remove("toggle-button-hidden"); + } else { + itemToToggle.classList.add("toggle-hidden"); + button.classList.add("toggle-button-hidden"); + } +} + +var toggleClickHandler = (click) => { + // Be cause the admonition title is clickable and extends to the whole admonition + // We only look for a click event on this title to trigger the toggle. + + if (click.target.classList.contains("admonition-title")) { + button = click.target.querySelector(".toggle-button"); + } else if (click.target.classList.contains("tb-icon")) { + // We've clicked the icon and need to search up one parent for the button + button = click.target.parentElement; + } else if (click.target.tagName == "polyline") { + // We've clicked the SVG elements inside the button, need to up 2 layers + button = click.target.parentElement.parentElement; + } else if (click.target.classList.contains("toggle-button")) { + // We've clicked the button itself and so don't need to do anything + button = click.target; + } else { + console.log(`[togglebutton]: Couldn't find button for ${click.target}`) + } + target = document.getElementById(button.dataset['button']); + toggleHidden(target); +} + +// If we want to blanket-add toggle classes to certain cells +var addToggleToSelector = () => { + const selector = ""; + if (selector.length > 0) { + document.querySelectorAll(selector).forEach((item) => { + item.classList.add("toggle"); + }) + } +} + +// Helper function to run when the DOM is finished +const sphinxToggleRunWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} +sphinxToggleRunWhenDOMLoaded(addToggleToSelector) +sphinxToggleRunWhenDOMLoaded(initToggleItems) + +/** Toggle details blocks to be open when printing */ +if (toggleOpenOnPrint == "true") { + window.addEventListener("beforeprint", () => { + // Open the details + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.dataset["togglestatus"] = el.open; + el.open = true; + }); + + // Open the admonitions + document.querySelectorAll(".admonition.toggle.toggle-hidden").forEach((el) => { + console.log(el); + el.querySelector("button.toggle-button").click(); + el.dataset["toggle_after_print"] = "true"; + }); + }); + window.addEventListener("afterprint", () => { + // Re-close the details that were closed + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.open = el.dataset["togglestatus"] == "true"; + delete el.dataset["togglestatus"]; + }); + + // Re-close the admonition toggle buttons + document.querySelectorAll(".admonition.toggle").forEach((el) => { + if (el.dataset["toggle_after_print"] == "true") { + el.querySelector("button.toggle-button").click(); + delete el.dataset["toggle_after_print"]; + } + }); + }); +} diff --git a/branch/ignore/singlehtml/index.html b/branch/ignore/singlehtml/index.html new file mode 100644 index 0000000..61d243f --- /dev/null +++ b/branch/ignore/singlehtml/index.html @@ -0,0 +1,3179 @@ + + + + + + + Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Community teaching training

+
+

Under development (mid 2022)

+

As of mid-2022, this material has been reworked for our summer workshop and +for the CarpentryCon 2022 workshop. The material will continue to be +improved before a longer training session in the autumn.

+

This material is the new version of our previous Instructor +training.

+
+
+

What this course covers

+

In 2020, we got farther from our offices but closer to each other. If +you could adapt to the circumstances, a huge number of possibilities +were opened - in particular with collaborative teaching. In this +training, you will learn how we use them. Teaching from 2019 is +almost obsolete - join us to learn more.

+
    +
  • Tools of teaching: how to make the most out of online (and +other) teaching.

  • +
  • Workshop organization, collaboratively: our vision of teaching +together outside of our silos.

  • +
  • Socio-technical factors: social and technical barriers to +learning, why you need to care, and what you can do about them.

  • +
  • Lesson development, collaboratively: how to design lessons and +teaching materials so that they can be open and shared.

  • +
+
+
+

Who is the course for?

+

Teaching is a profession, but also something that everyone needs to be +able to do to some degree, since everyone has their own personal +specialties they will either teach or mentor.

+

This course can be relevant for different learner personas:

+
    +
  • You run a practical teaching program at your institution (for example +as part of a research computing group) and would like to learn best +practices for collaborative teaching, so that you aren’t re-inventing +the same thing over and over again.

  • +
  • You are a technical specialist who is frustrated with the way you +currently try to teach others who need to use your software or +infrastructure. You can’t spend too much time to become a +professional, but you know you need something more than what you’ve +been doing. Thus, you would like to adopt some of the best practices of +designing and teaching interactive, hands-on workshops.

  • +
  • You’ve been teaching alone, but would like to join a collaboration +network for more co-teaching and to reduce the amount of duplication +of effort.

  • +
  • You are interested in teaching CodeRefinery lessons, and would like a +comprehensive kick-start to how CodeRefinery works, either to join us, +or teach its lessons with us or independently.

  • +
+
+
+

Pre-workshop preparation

+

These things will help you get the most out of this workshop, by +giving you a broad overview at the beginning that you might only get +later on in the lesson.

+

Don’t worry if you don’t have time to do everything here. The most +important ones are listed first.

+
+

Read “How to help someone use a computer” (5 min)

+

How to help someone use a computer, by Phil +Agre. +Summary: Most of our teaching challenge is helping people to overcome bad user +interface design.

+
+
+

Browse a CodeRefinery lesson (5 min)

+

Please take 5 minutes and go through a CodeRefinery +lesson and understand the general +layout. Don’t go in-depth to any of the material (unless you want, +obviously). We would recommend +git-intro if you don’t +have a preference.

+
+
+

(optional) Watch “The future of teaching” (35 min content only, 45 min with Q&A, or 15 min reading)

+

The “The Future of Teaching” talk is a summary of many things in this +course. You could watch it as a preparation (or if you are reading on +your own, as a summary). This is low priority, since we will cover +most of these things in the course itself. +Watch it on YouTube +or read it if you prefer.

+
+
+

(optional) Read “The science of learning” (20 min)

+

Read this short paper The Science of +Learning +which provides a brief overview of some key evidence-based results in +teaching. This paper is also used by The +Carpentries for their Instructor Training +workshops.

+
+
+
+
+
+

Welcome and introduction

+
+

What do we want to get out of this workshop

+
    +
  • Introduction of instructors and helpers

  • +
  • Each instructor can say what we want to get out of the instructor training

  • +
  • But we want to know from everybody and collect these in the live notes

  • +
+
+
+
+

Goals for this workshop

+
+

Goals for this instructor training

+
    +
  • Inspire teachers and staff who have to teach indirectly as part of +their job: use best practices for the modern world, especially +for online teaching.

  • +
  • Promote collaboration in teaching: less going alone.

  • +
  • Promote CodeRefinery sustainability: form a network that can +work together to share the work and benefits.

  • +
+
+
+
Giving confidence
+
+

Goal number one should be that we give participants the confidence to +independently apply the tools or knowledge learnt. This is more important +that giving a “complete” overview. [Lucy Whalley gave this great comment at one of our workshops]

+
+
    +
  • You don’t have to know everything to use (or teach) something.

  • +
  • For the large majority of topics we teach, there are many resources online +which provide how-to guides or tutorials. And the Stack Overflow answer bank +isn’t getting any smaller. So we need to ask why do people attend in-person +sessions if there is information freely available? Our impression is that +it is for confidence building, identity formation, perhaps signposting to +resources.

  • +
  • This also links with building a welcoming/inclusive environment: for example, +imposter syndrome, which disproportionately affects under-represented groups +(link), +can manifest as low self-confidence –> building the confidence of +students in the classroom may lead to a more diverse community.

  • +
+
+
+
+
+

Tools for this workshop

+

We often start workshops with these:

+ +
+
+
+

Code of Conduct

+
    +
  • We follow The CodeRefinery Code of +Conduct.

  • +
  • This is a hands-on, interactive workshop.

    +
      +
    • Be kind to each other and help each other as best you can.

    • +
    • If you can’t help someone or there is some problem, let someone know.

    • +
    • If you notice something that prevents you from learning as well as you can, let us know and don’t suffer silently.

    • +
    +
  • +
  • It’s also about the little things:

    +
      +
    • volume

    • +
    • font size

    • +
    • generally confusing instructor

    • +
    • not enough breaks

    • +
    +
  • +
+
+
+
+

About the CodeRefinery project and CodeRefinery workshops

+
+

Keypoints

+
    +
  • Teaches intermediate-level software development tool lessons

  • +
  • Training network for other lessons, too

  • +
  • Publicly-funded discrete projects (3 projects actually) transitioning towards an open community project

  • +
  • We have online material, teaching, and exercise sessions

  • +
  • We want more people to work with us, and to work with more people

  • +
+
+

CodeRefinery is a +Nordic e-Infrastructure Collaboration (NeIC) +project that has started in October 2016 and is +funded until February 2025.

+

The funding from 2022-2025 is designed to keep this project active +beyond 2025 by forming a support network and building a community of +instructors and contributors.

+
+

History

+

The CodeRefinery project idea grew out of two SeSE courses given at KTH Stockholm in 2014 and 2016:

+ +

The project proposal was submitted to NeIC in 2015, accepted in 2015, and started in 2016.

+

We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form.

+
+
+

Main goals

+
    +
  • Develop and maintain training material on software best practices for researchers that already write code. Our material addresses all academic disciplines and tries to be as programming language-independent as possible.

  • +
  • Provide a code repository hosting service that is open and free for all researchers based in universities and research institutes from Nordic countries.

  • +
  • Provide training opportunities in the Nordics using Carpentries and CodeRefinery training materials.

  • +
  • Articulate and implement the CodeRefinery sustainability plan.

  • +
+
+
+

Impact

+

We collect feedback and survey results to measure our impact.

+

3-6 months after attending a workshop, past participants are asked to complete a short post-workshop survey. +The survey questions aim to establish what impact CodeRefinery workshops have on how past participants develop +research software.

+

Pre- and post-workshop survey results

+
    +
  • Overall quality of research software has improved: more reusable, modular, reproducible and documented.

  • +
  • Collaboration on research software development has become easier

  • +
  • Past participants share their new knowledge with colleagues

  • +
  • Usage of several tools is improved, and new tools are adopted

  • +
+

Free-form answers +also suggest that workshops are having the intended effects on how people develop code. A common theme is:

+
+

I wish I had known this stuff already as a grad student 10+ years ago…

+
+

We would love to get suggestions on how we can better quantify our impact. This +would make it easier for us to convince institutions to partner with us and +also open up funding opportunities.

+
+
+

Target audience

+
+
Carpentries audience
+

The Carpentries aims to teach computational competence to learners through an applied approach, avoiding the theoretical and general in favor of the practical and specific.

+

Learners do not need to have any prior experience in programming. One major goal of a Carpentry workshop is to raise awareness on the tools researchers can learn/use to speed up their research.

+

By showing learners how to solve specific problems with specific tools and providing hands-on practice, learners develops confidence for future learning.

+
+

Novices

+

We often qualify Carpentry learners as novices: they do not know what they need to learn yet. A typical example is the usage of version control: the Carpentry git lesson aims to give a very high level conceptual overview of Git but it does not explain how it can be used in research projects.

+
+
+
+
CodeRefinery audience
+

In that sense, CodeRefinery workshops differ from Carpentry workshops as we assume our audience already writes code and scripts and we aim at teaching them best software practices.

+

Our learners usually do not have a good overview of best software practices but are aware of the need to learn them. Very often, they know the tools (Git, Jupyter, etc.) we are teaching but have difficulties to make the best use of them in their software development workflow.

+

Whenever we can, we should direct learners that do not have sufficient coding experience to Carpentries workshops.

+
+

Competent practitioners

+

We often qualify CodeRefinery learners as competent practitioners because they already have an understanding of their needs. +Novices and competent practitioners will be more clearly defined in the next section.

+
+
+

Best software practices for whom?

+

It can be useful to ask the question: best software practices for whom? +CodeRefinery teaches best software practices derived from producing and +shipping software. These practices are also very good for sharing software, +though our audience will probably not need to embrace all aspects of +software engineering.

+
+
+
+
+
+
+
+

Teaching online

+

Is online teaching better or worse? As usual for that question, “it’s +all a trade-off”. We believe that many people tried to directly +translate in-person strategies to online, and teaching suffered. In +some ways, this even revealed the flaws of in-person pedagogy (remove +some interaction and not much is left other than an info-dump).

+
+

Exercise

+

Using HackMD, brainstorm advantages and disadvantages of online and +in-person teaching. For each disadvantage of each, think of ways to compensate.

+
+
    +
  • We won’t elaborate more here right now - most of the rest of the +course somehow relates to online teaching!

  • +
  • We will see many techniques which compensate for some of the +disadvantages in the section tools of teaching.

  • +
  • Workshop organization will discuss new collaborative +opportunities with online teaching.

  • +
+
+

See also

+
    +
  • The rest of this course

  • +
  • CodeRefinery manuals: https://coderefinery.github.io/manuals/

  • +
+
+
+
+

Team teaching

+

One of the most significant improvemest of our teaching has been the +concept of co-teaching.

+
+

Co-teaching

+

Wikipedia: Co-teaching or team teaching is the division of labor +between educators to plan, organize, instruct and make assessments +on the same group of students, generally in the a common +classroom,[1] and often with a strong focus on those teaching as a +team complementing one another’s particular skills or other +strengths.

+
+

This is not strictly an effect of moving online. However, the +larger number of instructors and larger audiences make this practical +on a wide scale.

+
+

Primary article

+

https://coderefinery.github.io/manuals/team-teaching/

+
+
+

Benefits

+
    +
  • The course seems very interactive, much more so than expecting +students to speak up. The co-teacher can take on the “voice of the +audience”.

  • +
  • Quicker preparation time since co-teachers can rely on each other in +unexpected situations.

  • +
  • One co-teacher can be effectively learning at the same time and thus +acting as the “voice of the audience” in another way.

  • +
  • Great way to onboard new instructors - extensive training and +preparation no longer needed.

  • +
  • More active minds means better able to watch and react to other +feedback, such as HackMD or chat.

  • +
  • Less workload - one person does not have to prepare perfectly, any +uncertainty can usually be quickly answered by the other.

  • +
+
+
+

Strategies

+

In reality, these strategies are mixed and matched even within a +lesson, and there are many things between these:

+
    +
  • One person gives lectures, one does the typing during demos.

  • +
  • “Interview”: One primarily doing the “teaching”, one guiding by +asking questions - either as an interviewer or as a virtual learner.

  • +
+

Things that don’t work (are not team teaching):

+
    +
  • Dividing up a lesson into parts, each person gives different parts +independently.

  • +
+
+
+

Exercises

+
+

Exercise

+

Divide into groups of two or three. Choose one of the two models +in the team-teaching page, and quickly (5 min) prepare a short +topic (3-5 min) to team teach. You can quickly scan the +“preparation” section at the bottom.

+

The challenge is not just to give the lesson, but to prepare the +lesson quickly and rely on each other to give a good lesson anyway.

+
+
+
+

See also

+

(none yet)

+
+
+
+

HackMD

+

The name “HackMD” doesn’t do this concept justice, nor do the more +common descriptions of “shared notes” or “collaborative document”. It +is a full replacement for chat: perhaps it could be called random +access chat or parallel 2D chat ?

+

HackMD itself is a web service for collaborative documents in +Markdown. This isn’t special to HackMD, but we have used it for its +scalability, markdown support, and privacy in the “view” mode.

+
+

Primary articles

+ +
+
+

Advantages

+
    +
  • Synchronous questions, no disadvantage for quiet people.

  • +
  • Anonymous questions.

  • +
  • Parallel answers by a large number of helpers.

  • +
  • Easier to go back and review past questions during Q&A sessions +(compared to scrolling through chat), for example finding important +or unanswered questions.

  • +
  • The above can make a course feel much more interactive than it would +otherwise.

  • +
+
+
+

Disadvantages

+
    +
  • Overwhelming flood of information

    +
      +
    • But you wanted more interaction, right?

    • +
    • Co-teaching helps here, one person can focus on watching.

    • +
    • Students must be warned to be deliberate about where they focus +their attention (different learners have different interests).

    • +
    +
  • +
  • It is another tool to use

    +
      +
    • Not required for basic learners, learners can begin using when +they are comfortable.

    • +
    +
  • +
+
+
+

Exercise

+
+

Exercise

+
    +
  • Actively use HackMD during this course.

  • +
  • Observe how the instructors integrate it during the course +itself, and can immediately respond to the questions.

  • +
  • Observe how instructors occasionally mention and screenshare +HackMD to validate to the audience that it is being watched.

  • +
  • Keep HackMD open. Can you balance it and watching. Does it +increase or decrease engagement?

  • +
+
+
+
+
+

Teams

+

Everyone wants interaction in courses, yet when a group size gets too +large, it doesn’t have much interaction. A event in a physical space +naturally makes teams based on who is nearby. When done online, this +needs to be more explicit.

+
+

Primary articles

+ +
+
+

Basic concepts

+
    +
  • Teams are pre-assigned

  • +
  • Exercise leaders (aka helpers) assigned per team

  • +
  • Teams stay together during the whole workshop.

  • +
  • Learners can sign up either alone…

  • +
  • … or they can sign up with a pre-made team: people who know +each. “bring your own breakout room”:

    +
      +
    • When two people in a work group learn a skill, uptake within the +group is often much higher. Thus, we strongly encourage pre-made +teams that know each other.

    • +
    • Teams that all come from the same group or field, with a helper +from that field, can transition to help

    • +
    +
  • +
+
+
+

Online

+

In the best online implementations, our teams have these properties:

+
    +
  • Coordination of breakout rooms is a lot of work.

  • +
  • In zoom, we could request learners to rename to (N) Learner +Name, and then quickly assign people. Now, you can have learners +self-select their rooms. But will they actually do this, or stay in +main room?

  • +
  • One helper is assigned per team.

    +
      +
    • In fact, we would limit the number of registrations to 5× the +number of helpers so that all teams have a helper

    • +
    +
  • +
  • Our registration system (indico) is capable of mailing personalized +messages per person with their team information. This is quite a +bit of work to manage.

  • +
+

But they have these disadvantages:

+
    +
  • Much, much harder registration coordination, almost to the point of +being impossible.

  • +
  • Number of attendees.

  • +
  • Difficulties when attendees drop out partway through a course.

  • +
+
+
+

In-person

+

Teams may natuarally form based on setting location, but

+
    +
  • Teams may happen naturally by sitting at the same table

  • +
  • Do teams stay the same day after day?

  • +
  • Do teams get arranged in a manner useful for learning?

  • +
  • Do you have one helper per team?

  • +
  • Do you encourage people to interact explicitly enough?

  • +
  • Do you ensure that no one gets left out in the crowd? Are the teams +explicit enough?

  • +
+
+
+

Discussion: what we actually do

+
    +
  • For large enough CodeRefinery workshops, assign teams with one +helper each. Deal with re-adjustment

  • +
  • The livestream option allows everyone else to follow along.

  • +
  • In other workshops, create breakout rooms but somehow try let people +self-assign. Most don’t.

  • +
  • For large workshops without enough staff help, livestream and +encourage people to form their own teams and watch themselves - we +don’t actually need to be involved.

  • +
  • Teams can be delegated to a local organizer.

  • +
+
+
+

Exercises

+
+

Teams

+

Consider these questions:

+
    +
  • Should teams have similar or different people in them?

  • +
+
+
+
+
+

Livestreaming

+

In a large lecture, in effect, you don’t interact with most people - +not even close. Yet, trying to force this limited interaction greatly +limits our possible reach, and keeps us in an awkward state of +expecting live interaction yet usually receiving minimal. When we try +this online, it forces a closed

+

Teaching via livestreaming allows us to:

+
    +
  • Reach a near-unlimited number of people

  • +
  • Fully embrace online tools for interaction, instead of asking people +to speak up. This equalizes the participation for shy or passive +participants.

  • +
  • By being large, be more efficient and use the extra resources for +meaningful interactions in small groups.

  • +
+
+

Primary articles

+ +
+
+

Summary

+
    +
  • There are actually three levels here.

    +
      +
    • In-person

    • +
    • Online meeting

    • +
    • Online livestream

    • +
    +
  • +
+
+https://coderefinery.github.io/manuals/_images/mooc-diagram.png +
+

The general presence and information flow within the MOOC strategy.

+
+
+
    +
  • CodeRefinery livestreams via Twitch, but Twitch is not an essential +aspect.

  • +
  • We can invite anyone in the world, no risk of disruptions from +trolls.

  • +
  • This has enabled us to fully embrace strategies such as HackMD and +co-teaching.

    +
      +
    • While we tried these in-person, they didn’t work well since the +loud, extroverted people would dominate.

    • +
    +
  • +
+
+
Tech details
+
    +
  • We stream by using OBS to capture a Zoom meeting. We can switch +between a gallery view, screenshare, and mixed.

  • +
  • Dedicated instructor Zoom meeting - no learners. Thus, no chance of +privacy violations.

    +
      +
    • Learners can attend different ways: a) independently online b) +in-person breakout room c) Zoom breakout rooms.

    • +
    +
  • +
  • We don’t have time to get into details here… see the linked +documents and also join us for in-person experience while we improve +our materials more.

  • +
+
+
+
+

Exercises

+
+

(advanced) Set up and install OBS as a livestreaming tool.

+

This exercise is open-ended.

+
+
+
+
+

Instructor tech setup

+
+

Keypoints

+
    +
  • Screenshare: portrait layout instead of sharing entire screen

  • +
  • Prompt: adjust your prompt to make commands easy to read

  • +
  • Readability and beauty is important: adjust your setup for your audience

  • +
  • Share the history of your commands

  • +
  • Get set up a few days in advance and get an outside reviewer

  • +
+
+
+

Screenshare

+

Compare the following two screen-shares (you can find many more in +the coderefinery manuals:

+
+https://coderefinery.github.io/manuals/_images/screenshare-fullhd.png +
+

FullHD.

+
+
+
+https://coderefinery.github.io/manuals/_images/s10-kickstart-prompt-log.png +
+

Portrait, latest proposed best practices.

+
+
+

Share a portrait layout (left or right half of your screen) +instead of sharing entire screen.

+

Motivation:

+
    +
  • This makes it easier for you to look at some other notes or to coordinate +with other instructors at the same time +without distracting with too much information.

  • +
  • This makes it possible for participants to have something else open in the +other screen half: terminal or browser or notebook.

  • +
+
+
+

Adjust your prompt/configuration/colors

+

Adjust your prompt to make commands easy to read. What looks good for your own +work (many terminals, small font, extensions, shortcuts, color scheme) is +usually not the best for other people watching you. Adjust your setup for your +audience. Remove distractions.

+

You need to spend some time getting set up before you teach. 10 minutes +before the session starts is typically too late. Get set up a few days in +advance and get an outside reviewer.

+
+

Should instructors be forced to have a consistent screenshare?

+

There are pros and cons to all instructors using the same screenshare and prompt.

+
    +
  • What are the advantages?

  • +
  • What are the opportunities of instructors showing different setups?

  • +
  • How does it depend on the lesson and the experience of learners?

  • +
+
+
+
+

Share the history of your commands

+

Even if you type slowly it is almost impossible to follow every command. We +all get distracted or want to read up on something or while following a command +fails on the learner laptop while instructor gets no error.

+

Add pauses and share the commands that you have typed so that one can catch up.

+
+
+

More examples and how to set it up

+ +
+
+

Exercises

+
+

Evaluate screen captures

+

Evaluate screenshots within the instructor tech +setup lesson. +Use the collaborative document to make a list of the trade-offs of each one. +Which one do you prefer? Which are useful in each situation?

+
+
+

Set up your own environment

+

Set up your screen to teach something. Get some feedback from +another learner. We will discuss among the class.

+
+
+
+
+

Video recording

+
+

Keypoints

+
    +
  • We don’t expect many people to watch the recording from scratch later (but +some do) (some might look afterwards a few pieces, cmp. reading a book vs +look ing sth up from a book)

  • +
  • Learners getting an “instant replay” to review, or to make up for a lost day, is great.

  • +
  • Privacy is more important than any other factor

  • +
  • Recording only works if privacy is guaranteed and effort is low. +This is only possible with the instructor-audience split setup of livestreaming.

  • +
+
+
+

We try to release videos on the same day

+

Video recordings could be useful for people attending a course later, but also +are (perhaps more) useful for immediate review and catching up after missing +a day in a workshop.

+

For this, they need to be released immediately, within a few hours of the +workshop (see Video editing). CodeRefinery can do this.

+

For the videos to be released soon we need to make sure we guarantee privacy of +learners (see below). Our livestream setup makes the privacy guarantee easy at +the cost of separating instructors and learners into different video rooms.

+

Good preparation and documentation helps to make video recording and video +editing easier.

+
+
+

Privacy is more important than any other factor

+

If we can’t guarantee privacy, we can’t release videos at all.

+

Some events add a disclaimers such as “if you don’t want to appear +in a recording, leave your video off and don’t say anything”. We +would prefer not to do this, since:

+
    +
  • we know accidents happen (especially when coming back from breakout rooms)

  • +
  • it creates an incentive to not interact by voice/video

  • +
  • it could pressure participants to not object in order “to not be difficult”

  • +
+

Livestreaming solves this for us:

+
    +
  • By separating the instruction from +the audience audio/video, there is no privacy risk in the raw +recording. They could be released or shared unprocessed.

  • +
  • Recording with Zoom in a large meeting with all the instructors and +learners is simple, but not good for privacy: there are always +mistakes, reviewing takes too long.

  • +
  • Livestream platforms also provide instant recordings of the whole +stream, and some make instant replays possible. This could remove +the need for making our own videos, since one of the most important +cases is this instant replay idea.

  • +
+
+
+

Broadcasting role and setup

+

In the live-streaming setup, the Broadcasting role is central to video +recording.

+

Broadcaster description (most is not directly about recording): +https://coderefinery.github.io/manuals/broadcaster/

+
+
+
+

Video editing

+

Video recordings could be useful for people attending a course later, +but also are (perhaps more) useful for immediate review and catching +up after missing a day in a workshop. For this, they need to be +released immediately, within a few hours of the workshop. +CodeRefinery can do this.

+

Hypothesis: videos must be processed the same evening as they were +recorded, otherwise (it may never happen) or (it’s too late to be +useful). To do that, we have to make processing good enough (not +perfect) and fast and distributeable

+
+

Primary articles

+ +
+
+

Summary

+
    +
  • Basic principle: privacy is more important than any other factor. +If we can’t guarantee privacy, we can’t release videos at all.

    +
      +
    • Disclaimers such as “if you don’t want to appear in a recording, +leave your video off and don’t say anything”, since a) accidents +happen especially when coming back from breakout rooms. b) it +creates an incentive to not interact or participate in the course.

    • +
    +
  • +
  • Livestreaming is important here: by separating the instruction from +the audience audio/video, there is no privacy risk in the raw +recording. They could be released or shared unprocessed.

  • +
  • Our overall priorities

    +
      +
    1. No learner (or anyone not staff) video, audio, names, etc. are +present in the recordings.

    2. +
    3. Good descriptions.

    4. +
    5. Removing breaks and other dead time.

    6. +
    7. Splitting videos into useful chunks (e.g. per-episode), perhaps +equal with the next one:

    8. +
    9. Good Table of Contents information so learners can jump to the +right spots (this also helps with “good description”.)

    10. +
    +
  • +
  • ffmpeg-editlist allows us to +define an edit in a text file (crowdsourceable on Github), and then +generate videos very quickly.

  • +
+
+
+

Exercises

+
+
Exercise A
+

These exercises will take you through the whole sequence.

+
+

Editing-1: Get your sample video

+

Download a sample video:

+
+
+
+
+

Editing-2: Run Whisper to generate raw subtitles and test video.

+

First off, install Whisper and generate the base subtitles, based +on the. Since this is probably too much to expect for a short +lesson, they are provided for you (above), but if you want you can +try using Whisper, or generating the subtitles some other way.

+

You can start generating subtitles now, while you do the next +steps, so that they are ready by the time you are ready to apply +the editlist. ffmpeg-editlist can also slice up the subtitles from +the main video to make subtitles for each segment you cut out.

+

Whisper is left as an exercise to the reader.

+ +
+
+

Editing-3: Create the basic editlist.yaml file

+

Install ffmpeg-editlist and try to +follow its instructions, to create an edit with these features:

+
    +
  • The input definition.

  • +
  • Two output sections: the “Intro to the course”, and “From data +storage to your science” talks (Remember it said the recording +started at 11:35… look at the schedule for hints on when it +might start!). This should have a start/end timestamp from the +original video.

  • +
+

A basic example:

+
- input: day1-raw.mkv
+
+# This is the output from one section.  Your result should have two of these sections.
+- output: part1.mkv
+  title: something
+  description: >-
+    some long
+    description of the
+    segment
+  editlist:
+    - start: 10:00    # start timestamp of the section, in *original* video
+    - end: 20:00      # end timestamp of the section, in the *original* video
+
+
+ +
+
+

Discussion: what makes a video easy to edit?

+
    +
  • Clear speaking and have high audio quality.

  • +
  • For subtitle generation: Separate sentences cleanly, otherwise it +gets in a “stream of words” instead of “punctuated sentences” +mode.

  • +
  • Clearly screen-sharing the place you are at, including section +name.

  • +
  • Clear transitions, “OK, now let’s move on to the next lesson, +LESSON-NAME. Going back to the main page, we see it here.”

  • +
  • Clearly indicate where the transitions are

  • +
  • Hover mouse cursor over the area you are currently talking about.

  • +
  • Scroll screen when you move on to a new topic.

  • +
  • Accurate course webpage and sticking to the schedule

  • +
+

All of these are also good for learners. By editing videos, you +become an advocate for good teaching overall.

+
+
+

Editing-4: Run ffmpeg-editlist

+

Install ffmpeg-editlist: pip install ffmpeg-editlist[srt] (you +may want to use a virtual environment, but these are very minimal +dependencies).

+

The ffmpeg command line tool must be available in your +PATH.

+ +
+
+

Editing-5: Add more features

+
    +
  • Several chapter definitions.(re-run and you should see a +.info.txt file also generated). Video chapter definitions +are timestamps of the original video, that get translated to +timestamps of the output video.

    +
    - output: part1.mkv
    +  editlist:
    +  - start: 10:00
    +  - -: Introduction    #  <-- New, `-` means "at start time"
    +  - 10:45: Part 1      #  <-- New
    +  - 15:00: Part 2      #  <-- New
    +  - end: 20:00
    +
    +
    +

    Look at the .info.txt files that come out now. What is new in it?

    +
  • +
  • Add in “workshop title”, “workshop description”, and see the +.info.txt files that come out now. This is ready for +copy-pasting into a YouTube description (first line is the title, +rest is the description).

    +

    Look at the new .info.txt files. What is new?

    +
  • +
+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+
+
+

Editing-7: Generate the final output file.

+
    +
  • Run ffmpeg-editlist with the --reencode option: this +re-encodes the video and makes sure that there is no black point +at the start.

  • +
  • If you re-run with --check, it won’t output a new video file, +but it will re-output the .info.txt and .srt files. +This is useful when you adjust descriptions or chapters.

  • +
+
+
+

Discussion: how to distribute this?

+

Create a flowchat of all the parts that need to be done, and which +parts can be done in parallel. Don’t forget things that you might +need to do before the workshop starts.

+

How hard was this editing? Was it worth it?

+
+
+
+
Exercise B
+

This is similar to the above but more brief and not on a real example +video.

+
+

Use ffmpeg-editlist to edit this sample video

+

Prerequisites: ffmpeg must be installed on your computer +outside of Python. Be able to install ffmpeg-editlist. This is +simple in a Python virtual environment, but if not the only +dependency is PyYAML.

+ +
+ +
+
+
+

See also

+ +
+
+
+

Distributed workshop organization

+
+

Keypoints

+
    +
  • If another university/organization wants to run the course, they can easily join our existing course at little cost/risk to them and to us.

  • +
  • Each organization that joins provides a great benefit to us (helpers, instructors).

  • +
  • They can reserve an in-person breakout room and provide mentors while watching the livestream: A great experience for their audience.

  • +
+
+
+

It is easier to join and follow than to start or lead

+

Organizing a course is time intensive and so is developing a course. Many +courses given in country A are also relevant in other countries and instead of +developing and possibly re-inventing courses independently in different places, +it is so much more rewarding to collaborate and share.

+

In our courses we wish and try to make it easier for teams and organizations +and universities to join, at little risk and cost to them, possibly for a short +period of time, possibly only as observer. Later observers can progress to +exercise leads, expert helpers, instructors, and co-organizers.

+

One model that we have successfully tried is that the course is delivered via +live-stream to all partners and all the partner needs to do is to reserve a +room and motivate few people to help local learners as exercise leads during +exercise sessions which can happen in-person.

+
+

Lessons learned from organizing larger workshops

+
    +
  • One person is needed to coordinate the registration process and this person should +not have teaching duties in addition to this role.

  • +
  • Generally it helps to have well-defined roles (see Workshop roles).

  • +
+
+
+
+
+
+
+

Why teach together?

+

We usually say so much about the value of collaboration. Despite us +saying this, our teaching is still far too alone. Covid-19 gave us a +kick that reduced our barriers and led to lasting changes in how we +taught (eventually leading to this very course).

+

Open Science / FAIR data is heavily emphazised these days. But let’s +add a “C” to FAIR: “collaborative”. Instead of people doing their own +thing and releasing, develop, iterate, and maintain collaboratively.

+
+

Ways to teach together

+
    +
  • Develop materials together - avoid duplication.

  • +
  • Team teaching

  • +
  • Extensive use of helpers and team leaders.

  • +
  • HackMD for parallel and mass answers.

  • +
+
+
+

Advantages

+
    +
  • You need to teach anyway, less effort if you combine.

  • +
  • If done right, minimal extra effort for others to receive benefit (+ +you get publicity).

  • +
  • Many of the previously presented teaching strategies work best in +large courses - this makes the course more engaging than a small +event with minimal interaction.

  • +
  • More engaging for the audience.

  • +
  • Easier on-boarding of new instructors (less “scary” to teach a new course +with other instructors).

  • +
+
+
+

Challenges and disadvantages

+
    +
  • Coordination

    +
      +
    • Finding suitable partners with the same vision

    • +
    • Coordination efforts (if others don’t understand the vision).

    • +
    +
  • +
  • Materials

    +
      +
    • May not be perfectly tuned to your own audience

    • +
    • May not iterate as fast as you need

    • +
    +
  • +
  • Co-teaching

    +
      +
    • Difficulty in finding co-teachers

    • +
    • Required effort of syncing among staff

    • +
    • It might revert to independent teaching if you aren’t careful.

    • +
    +
  • +
  • HackMD

    +
      +
    • Can possibly overload both student and teacher.

    • +
    +
  • +
+
+
+

Exercises

+
+

What similarities do we have?

+

Using HackMD, make two lists:

+
    +
  • What courses do you think your local community would benefit +from, which you don’t currently have? +1 other people’s items +which are also relevant to you.

  • +
  • Which courses are you thinking of preparing for your local +community? +1 other people’s items which you would be +interested in helping out with.

  • +
+
+
+
+

See also

+ +
+
+
+

Collaboration models

+
+

Model: CodeRefinery

+
    +
  • Before Covid-19, workshops were physically around the Nordics, +instructors would travel (or already be there).

    +
      +
    • Maximum size: ~40 people

    • +
    • High workload per person

    • +
    +
  • +
  • After several small scaling attempts, now we have:

    +
      +
    • Two large workshops per year - livestream format

    • +
    • Combined organization efforts

    • +
    • Instructors from each location - on average two lessons taught.

    • +
    • Locations with staff can have local breakout rooms: physical +place to help during exercises.

    • +
    +
  • +
  • Others in the world can register and interact using HackMD, but no +promises of help.

  • +
  • Content still available to anyone in the world: live + instant +replay.

  • +
  • Course page and material: +https://coderefinery.github.io/2022-03-22-workshop/

  • +
+
+
+

Model: Python for Scientific Computing

+
    +
  • Aalto Scientific Computing wanted to host a course, Python for +Scientific Computing

  • +
  • ASC came up with initial vision and announced it

  • +
  • ASC hosted an open initial meeting, inviting any interested +organizers or instructors

  • +
  • We went over the plan and refined the topics and schedule. We also +decided things such as the date, organizers, and instructors for +each lesson.

  • +
  • Registration was open to everyone in the world, non-Nordic +participants could watch via livestream.

  • +
  • People prepared their parts and came together and presented. +Organizers kept everything on track.

  • +
  • Compared to the amount of effort each person put in, the results +were great.

  • +
  • A 2021 version also happened and was even larger.

  • +
  • Course page: https://scicomp.aalto.fi/training/scip/python-for-scicomp/

  • +
  • Material: https://aaltoscicomp.github.io/python-for-scicomp/

  • +
+
+
+

Exercises

+
+

List successes and failures in collaborative teaching

+

Using HackMD, list some successes and failures in collaborative +teaching that you have experienced.

+
+
+

Recommendations for co-teaching

+

If you have experience with co-teaching, what approach/technique/trick +can you recommend a colleague who would like to try co-teaching for the +first time?

+
+
+
+
+

Workshop roles

+

Running massive workshops requires a lot of people. We have a variety +of roles with different levels of support.

+

As usual, roles are a plan, and a plans are made to be updated.

+
+

Primary articles

+ +
+
+

Summary

+

Lower levels mean “top level sometimes split into some of these +sub-roles”.

+
    +
  • Instructor coordinator: coordinates schedule and instructors

    +
      +
    • Instructor: Teaches along with a co-teacher.

    • +
    • Expert helper: Spare person, usually watching HackMD but also +rotates among breakout rooms. Often instructs some lessons.

    • +
    • Director: Manages the flow of the schedule during the +workshop, introduces each lesson, etc. (often the instructor +coordinator)

      +
        +
      • Broadcaster: Manages the livestreaming

        +
          +
        • Video editor: Edits and publishes videos the day of the +workshop.

        • +
        +
      • +
      +
    • +
    +
  • +
  • Registration coordinator: coordinates registration, helpers, and +breakout rooms.

    +
      +
    • Exercise leader coordinator: Onboards exercise leaders

    • +
    • Host: Manages the learner breakout rooms, learner questions, +etc. (often the registration coordinator)

    • +
    • Advertisement coordinator: Advertises and outreaches

    • +
    +
  • +
  • Under both registration coordinator and instructor coordinator

    +
      +
    • HackMD manager: always watches and formats HackMD and +publishes it same-day. “Eyes on the ground” via HackMD and chat +and quickly communicates important information to instructor and +registration coordinators.

    • +
    +
  • +
  • Learner: attends and learns

  • +
  • Exercise leader: serves as a guide to the team, receives small +amount of training before the workshop.

  • +
+
+
+

Exercises

+
+

How many people teach in your workshops?

+
    +
  • Using HackMD, make a histogram of how many (instructors + +organizers) you typically have in your workshops.

  • +
  • List some of the common roles you have used.

  • +
+
+
+
+

See also

+

(none yet)

+
+
+
+
+
+

Why are computers hard?

+

Most of the time, when teaching, our difficulty is not what you expect.

+
+

Initial reading

+

Read the following:

+ +

Of each of the points made, how many are related to:

+
    +
  • The computing itself

  • +
  • The user interface

  • +
  • The ability of the user to work in the computing environment

  • +
  • Something else

  • +
+
+
+

Usability

+

As said in the text above:

+
+

Most user interfaces are terrible. When people make mistakes it’s +usually the fault of the interface. You’ve forgotten how many ways +you’ve learned to adapt to bad interfaces. You’ve forgotten how +many things you once assumed that the interface would be able to +do for you.

+
+
+
+

Deep abstraction layers

+

Most technology is built on abstraction layers, for good reason. They +help simplify implementation and understanding.

+
+

Exercise

+

Think of a tool or technology that is easy to understand and use if +you understand the underlying abstraction layers, but is almost +impossible otherwise.

+
+
+
+

Conclusion: what are we teaching, then?

+

As teachers of computing, we fill a critical role that is more +determined by our audience, than the technology we are teaching.

+
+
+

See also

+

(none yet)

+
+
+
+

Diversity and inclusion

+

When we are teaching, we fill a critical role in between people and +technology. We are not un-involved technical staff teaching asocial +topics, but we are very connected to the social context of the tools. +Unfortunately, there are major demographic imbalances in most +computing.

+
+

Primary articles

+ +
+
+

Support services vs diversity

+

Study this presentation by Richard Darst:

+ +

Summary:

+
    +
  • Computing is hard and quite often our ability to learn quickly is +connected to our social group.

  • +
  • Good technical services serve the role of mentors

  • +
  • This mentorship helps to equalize

  • +
  • Our entire system of research should be configured for more +equality. Modernization usually takes it the other way.

  • +
+
+
+

Exercises

+
+

Reflect on how your job can be defined to promote diversity.

+

What are some (possibly surprising) ways that your job promote +diversity and equality among people of different backgrounds?

+
+
+
+

See also

+

(none yet)

+
+
+
+

Placeholder

+
+
+
+
+

Lesson development with version control

+

So, we want to practically share. We have these minimum requirements:

+
    +
  • Someone can get the preferred form of modification, to improve +without limitation.

  • +
  • It is trivial to track differences and send the changes back to the +source, with little cost to the original maintainer.

  • +
+

Especially with the second of these, version control in an online +platform seems to be the only reasonable option.

+
+

Version control and static site generators

+

CodeRefinery and the Carpentries use git and Github to develop +lessons. The general procedure is this:

+
    +
  • Version control to store the raw files in text format

  • +
  • A static website compiler to convert them to HTML files

  • +
  • Serving to the public via Github Pages (but this could be replaced +with other systems)

  • +
+

This allows for true collaborative development and community +contributions.

+

Carpentries uses a custom website complierer based on R, CodeRefinery +uses the Sphinx documentation engine which is used in many different +projects for documentation. CodeRefinery’s use of a standard tool +allows us to build on a huge and growing ecosystem of extensions and +themes, and promotes local reuse.

+

The exact static website generator used isn’t so important, as long as +some form of version control is used.

+

A open-source license is the last bit to consider: without a license, +it can’t be reused and passed on, and there is little incentive for +someone to contribute.

+
+
+

CodeRefinery lesson tools

+

CodeRefinery uses the following tools to actually make its lessons +right now:

+
    +
  • Sphinx (a common documentation +generator, widely used in open source projects in general)

  • +
  • The sphinx-lesson, which is more of +a small collection of other extensions than new development itself.

  • +
  • Github for hosting lessons: https://github.com/coderefinery/

  • +
  • Github Actions and Github Pages for building and web serving our +lessons.

  • +
+
+
+

Exercises

+
+

Contribute to a sample lesson

+
    +
  • Open this very lesson in GitHub (it uses the same format as +typical CodeRefinery lessons): +https://github.com/coderefinery/community-teaching/

  • +
  • Browse the files and understand the general idea. Check out at +least these and use HackMD to record their functions:

    +
      +
    • .github/workflows/sphinx.yml

    • +
    • content/conf.py

    • +
    • content/index.rst

    • +
    • content/lessons-with-version-control.rst

    • +
    +
  • +
  • If you want, try to make a pull request to this lesson. It +doesn’t have to have any significant content, it can be a pure +test pull request.

  • +
+
+
+

(advanced) Create your own lesson

+

Use the +sphinx-lesson-template +to create a new lesson of your choice. Alternatively, use the current +Carpentries system, or some other system of your choice.

+
+
+
+

Recommendations and lessons learned

+
    +
  • Convert feedback about lessons and suggestions for improvements into issues +so that these don’t get lost.

  • +
  • Make your lesson citable: get a DOI.

  • +
  • Credit contributors (not only Git commits).

  • +
  • Instructor guide is essential for new instructors.

  • +
  • Lesson changes should be accompanied with instructor guide changes (it’s like +a documentation for the lesson material).

  • +
  • Apply and validate Backwards lesson design again and again.

  • +
  • Make it possible to try out new ideas (by making the lesson branch-able).

  • +
  • Before making larger changes, talk with somebody and discuss these changes.

  • +
  • For substantial changes we recommend to first open an issue and describe your +idea and collect feedback before you start with an extensive rewrite.

  • +
  • For things still under construction, open a draft pull request to collect +feedback and to signal to others what you are working on.

  • +
+
+
+

See also

+ +
+
+
+

Backwards lesson design

+

It happens far too often: someone creates a lesson, but they think +about what is interesting to them, not what is important for the +learners. In fact, an earlier version of this instructor training had +this very issue.

+

It is critical to backwards design almost any piece of communication, +especially something as widespread as teaching.

+
+

The approach

+
    +
  • You don’t think about how to do something and try to explain it.

  • +
  • Avoid the typical approach “I want to show a number of things which I think are cool about +tool X - how do I press these into 90 minutes?”

  • +
  • Instead, you start defining your target audience by answering to questions +such What is the expected educational level of my audience?, Have they +been already exposed to the technologies I am planning to teach?, What +tools do they already use?, What are the main issues they are currently +experiencing?. It is important to discuss these points with a group of +colleagues, preferably from diverse backgrounds and institutions to reduce +biases. Once you clarified your target audience, it is useful to create +learner personas; that will help you during the development process by +providing concrete examples of potential learners showing up at your +workshops. For each learner personas, try to think of what is useful to +them: “What do they need to +remember/understand/apply/analyze/evaluate/create?”. +Asking and answering to these questions will allow you to define the +background knowledge (starting points) and goals (end points) of your +learners. Then, you create a sequence of exercises which test incrementally +progressing tasks and acquisition of the new skills (from starting to end +points).

  • +
  • Then, you write the minimum amount +of material to teach the gap between exercises.

  • +
+
+
+

The process

+

As described in “A lesson design process” in the book Teaching Tech +Together:

+
    +
  1. Understand your learners

  2. +
  3. Brainstorm rough ideas

  4. +
  5. Create an summative assessment to know your overall goal

    +
      +
    • CodeRefinery translation: think of the things your learners will +be able to do at the end of the lesson. Think simple! The +simpler the better. Think of three main points they will +remember, of which maybe one or two are a concrete skill.

    • +
    +
  6. +
  7. Create formative assessments to go from the starting point to this.

    +
      +
    • CodeRefinery translation: think of some engaging and active +exercises.

    • +
    +
  8. +
  9. Order the formative assessments (exercises) into a reasonable order.

  10. +
  11. Write just enough material to get from one assessment (exercise) to +another.

  12. +
  13. Describe the course so the learners know if it is relevant to them.

  14. +
+

We can’t emphasize enough how important it is to know your end +state and keep it simple.

+
+

Example: designing an HPC Carpentry lesson

+

Let’s take as an example the HPC Carpentry lesson

+

Target audience

+
    +
  • What is the expected educational level of my audience?

    +
      +
    • A PhD student, postdoc or young researcher.

    • +
    +
  • +
  • Have they been already exposed to the technologies I am planning to teach?

    +
      +
    • The word HPC is not new to them and they may have already used an HPC but are still not capable of giving a proper definition of HPC. In addition, we do not expect them to know much about parallelism and they cannot make any distinction between various available parallelism paradigms.

    • +
    +
  • +
  • What tools do they already use?

    +
      +
    • serial codes, multi-threaded codes, data parallelism; usually out-of-the-box tools.

    • +
    • they may have tried to “scale” their code (multiprocessing, threading, GPUs) with more or less success.

    • +
    +
  • +
  • What are the main issues they are currently experiencing?

    +
      +
    • they cannot solve their problems either because they would like to run the same code but with many different datasets or because their problem is larger (more computations/memory).

    • +
    • most of the time they know their codes can run on HPC (from the documentation) but never really had the opportunity to try it out.

    • +
    • Very few will have their own codes where they may have tried different things to speed it up (threading, task parallelism) but have no clear strategy.

    • +
    +
  • +
+

Learner persona

+
    +
  • Sonya is a 1st year PhD student: she recently moved to Oslo and joined the +Computational and Systems Neuroscience group. She will be using the +NEST, a simulator for spiking +neural network model. She used NEST during her master thesis but on her +small cluster: she never used an HPC resource and is really excited about it.

  • +
  • Robert is a field ecologist who obtained his PhD 6 months ago. He is now +working on a new project with Climate scientists and as a consequence will +need to run global climate models. He is not very familiar with command +line even though he attended a Software Carpentry workshop and the idea to +use HPC is a bit terrifying. He knows that he will get support from his +team who has extensive experience with HPC but would like to become more +independent and be able to run his own simulations (rather than copying +existing cases).

  • +
  • Jessica is a postdoc working on a project that investigates numerically the +complex dynamics arising at the tip of a fluid-driven rupture. Fluid +dynamics will be computed by a finite element method solving the +compressible Navier-Stokes equations on a moving mesh. She uses a code she +has developed during her PhD and that is based on existing libraries. She +has mostly ran it on a local desktop; her work during her PhD was very +limited due to the lack of computing resources and she is now very keen is +moving to HPC; she knows that it will requires some work, in particular to +parallelize her code. This HPC training will be her first experience with +HPC.

  • +
+

Learning outcomes

+
    +
  • Understand the difference between HPCs and other local/remote machines

  • +
  • Understand the notion of core, nodes, cluster, shared/distributed memory, etc.

  • +
  • Understand the notion of login nodes.

  • +
  • Understand the need for a scheduler and how to use it appropriately

  • +
  • Understand why optimising I/O is important on HPC and how to best use HPC filesystems

  • +
  • Understand the need to parallelize (or use existing parallel) codes and in which cases HPCs is a must (when communications is required)

  • +
  • Understand how to get your code ready to use on HPC (access to libraries, installation of your own libraries/software, etc.)

  • +
  • Understand that an HPC is an operational machine and is not meant for developing codes.

  • +
+

Exercises

+
    +
  • Get basic information such the number of CPUs, memory from your laptop and try to do the same on a HPC. Discuss outcomes.

  • +
  • Try to create files on the different filesystems on your HPC resource and access them.

  • +
  • Create different types of job scripts, submit and check outputs.

  • +
  • Make a concrete example to run a specific software on your HPC (something like GROMACS).

  • +
+
+
+
+

Exercises

+
+

Backwards-design a lesson/topic

+

Choose a simple lesson topic and apply backwards lesson design. You +won’t get all the way through, but come up with a logical +progression of exercises.

+

The section you pick should require screen sharing and be of some follow-along +task (preferably using a shell).

+

Some suggestions:

+
    +
  • Regular expressions

  • +
  • Making papers in LaTeX

  • +
  • Making figures in your favorite programming language

  • +
  • Linux shell basics

  • +
  • Something non-technical, such as painting a room

  • +
  • An instructor training for CodeRefinery

  • +
  • Some aspect from an already existing lesson

  • +
  • Introduction to high-performance computing (or an episode therein)

  • +
  • Unix shell in a HPC context (or an episode therein)

  • +
  • A lesson you always wanted to teach

  • +
+
+
+
+
+
+
+

Possibilities for Carpentries

+
+

Keypoints

+
    +
  • Carpentries is currently designed around small workshops, so many of these ideas can’t directly apply

  • +
  • Yet many of these tools and also team teaching can still be used

  • +
  • You can run your own breakout room for any of our workshops

  • +
  • Join as observer if you want to see our workshop organization and tools in action

  • +
+
+

CodeRefinery workshops can be a good progression step after taking a +Carpentries workshop.

+

Helping out at a CodeRefinery workshop as exercise lead can be a good +progression step for those who have helped out at a Carpentries workshop or who +have taken the Carpentries instructor training.

+
+
+

CodeRefinery’s plans

+
+

Keypoints

+
    +
  • We are continuing to focus on online-first with local breakout rooms

  • +
  • We welcome people joining us, either individually or as an organization

  • +
  • Still interested in collaboration with Carpentries

  • +
  • We need to become better at marketing and outreach

  • +
+
+
+

Biggest open problems

+
    +
  • How to give helpers and contributors more credit and visibility

  • +
  • How to promote/engage new members

  • +
  • What are we? Non-profit? Institution collaboration network? Selling services?

  • +
  • Funding and sustainability (but we have ideas: collaboration network)

  • +
+
+
+

How you can join

+

Individual level:

+
    +
  • Join CodeRefinery +chat

  • +
  • Lead a team, co-teach, or help organize a workshop

  • +
  • Generally provide marketing and outreach

  • +
+

Organization level:

+
    +
  • Have your organization join CodeRefinery

  • +
  • Officially co-advertise and co-teach workshops

  • +
  • Run local breakout rooms and join a workshop as a team

  • +
  • Send an observer to a workshop

  • +
+
+
+

Aside: Nordic-RSE (research software engineers)

+ +
+
+
+
+
+

Other resources

+ +
+
+

Instructor’s guide

+

In a lesson that was further developed, this would include an +instructor’s guide that mentioned:

+
    +
  • Background of why the course is how it is

  • +
  • Recommendations of teaching it

  • +
  • Known pitfalls of teaching it, so that other instructors can avoid +them

  • +
  • Possibly how to contribute, long-term plans, etc.

  • +
+

For example, see git-intro’s instructor guide.

+
+
+

Exercise list

+

This is a list of all exercises and solutions in this lesson, mainly +as a reference for helpers and instructors. This list is +automatically generated from all of the other pages in the lesson. +Any single teaching event will probably cover only a subset of these, +depending on their interests.

+
+
+
+
+

CodeRefinery teaching philosophies

+
+

Ice-breaker in groups (20 minutes)

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also +Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+

Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops.

+

It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us.

+
+

Video recordings

+

Recently we have recorded some of the below as videos: +https://www.youtube.com/playlist?list=PLpLblYHCzJAAHF89P-GCjEXWC8CF-7nhX

+
+
+

Anne Fouilloux

+

I regularly teach Carpentries workshops so I try to apply what I have learnt to CodeRefinery workshops. However, I know our target audience is very much different and that I need to adapt my teaching style. I am still trying to find what works best in which situations and this is why I like so much CodeRefinery workshops. We usually have a wider range of skills and very mixed backgrounds so we usually have to be more careful with the pace and time given for exercises.

+

Some considerations:

+
    +
  • I spend quite a lot of time reading the CodeRefinery material and practising myself exercises. I particularly like to read the instructor notes just before teaching: they usually highlight important aspects both for preparing and teaching.

  • +
  • I usually do not show too much in advance the material as I think it prevents asking questions. If you have less competent practitioners in the classroom, they can easily copy-paste to avoid slowing down the entire classroom.

  • +
  • Ideally, I’d like to give several exercises so anyone can work at its own pace. I find it is important that everybody gets something different from the workshop.

  • +
  • I love breaks as it gives us an opportunity to discuss with attendees on their research topics. I am especially interested to understand what software they write and how they plan to use what they learn during our workshops.

  • +
+
+
+

Bjørn Lindi

+

My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this “BLOB” (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the “BLOB”, to be able to share it with others.

+

In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic.

+

When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson.

+

Tools that I find useful in preparing a lesson is concept maps and Learner Personas, though I have develop to few them.

+ +
+
+

Thor Wikfeldt

+

I never want to leave any learner behind and I really don’t like seeing confused, blank faces in the classroom. +At the same time I sometimes worry about some participants getting bored if a lesson is progressing slowly. +This is always a difficult compromise and something I struggle with!

+

I try to focus on making concepts intuitive, to “make sense” to the learners. Of course this is usually +based on how I learned the topic myself and how it makes sense to me.

+

I try to establish connections between topics: “this thing here is similar to what we saw in the previous +lesson where we learned about X…”.

+

Before mastering a lesson by teaching in many times I try to “follow the script”. After becoming very +familiar with a lesson I start to improvise more and react more dynamically to questions, e.g. by taking a +detour to explain a confusing topic more clearly.

+

What I think I do too often: copy-paste code/text from lesson material. This can leave learners behind - +typing out the code and describing it is slower, but more learning takes place. More advanced learners +will hopefully “be compensated” by interesting advanced exercises which follow.

+
+
+

Stefan Negru

+

A lesson is a conversation, it is useful if both the trainer and the trainee are engaged. +For that reason I try to have, most of the time, a conversation with the classroom and +after we finish parts of a lesson, step back and see how we might use what we learned.

+

That brings me to another point I follow throughout the lessons, answering questions like:

+
    +
  • How can we apply in practice what we just learned?

  • +
  • Do you see yourself (the trainee) using that in practice, why or why not?

  • +
+

Most of the times those seem like open-ended questions to the trainees that just learned +something new, so I try to find examples, most of the times from personal experience.

+

Last thing is that analogies are important when I teach, I try to find analogies in order +to simplify a convoluted part of a lesson.

+
+
+

Radovan Bast

+

My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos.

+

My goal for a lesson is to spark curiosity to try things after the lesson, +both for the novices (“This looks like a useful tool, I want to try using it +after the workshop.”) and the more experienced participants (“Aha - I did not +know you could do this. I wonder whether I can make it work with X.”). I like +to start lessons with a question because this makes participants look up from +their browsers.

+

Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise.

+

For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate +the answer.

+

I try to avoid jargon and “war stories” from the professional developers’ +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid “customer”, +“production”, also a lot of Agile jargon is hard to relate to.

+

Less and clear is better than more and unclear. Simple examples are better +than complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +“simply”, “just”, “easy”. If participants take home one or two points from +a lesson, that’s for me success.

+

I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don’t want to +be surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or +slide. This allows me to skip and distill the essence and not read bullet +point by bullet point.

+

I try to never deviate from the script and if I do, be very explicit about +it.

+

A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel.

+

I find it very helpful if there is somebody else in the room who helps me +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson but when doing that to +others, I am often worried of interrupting their flow and timing too much.

+

A mistake I often do is to type too fast and in my mind I force myself +to slow down.

+
+
+

Sabry Razick

+

My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case.

+
+
+

Juho Lehtonen

+

I’m gradually realising the different ways to get a hint whether the workshop +participants are still following or perhaps bored. I assume it’s communicating +with the class, with exercises and simply by asking now and then. I also try +to remember to observe how people look like (puzzled, bored) while I teach, not +so obvious for me.

+

I believe that learners communicating with each other, in addition to with +instructors and helpers, really helps them to understand things faster. (At least +it helps me). So I try to make sure that no one sits or works alone at the workshops.

+
+
+

Richard Darst

+

Like many people, I’ve often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I’ve realized long ago that my most important lessons weren’t +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I’ve realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds.

+

My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I’m often start at the +very basics, because this is what I see missing most often.

+

When teaching, I like lots of audience questions and don’t mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don’t have to know everything perfectly, just show how +you’d approach a problem.

+
+
+

João M. da Silva

+

I started giving technical trainings twenty years ago, and hence my perspective +is perhaps more inclined towards the development of hands-on abilities and +capability to solve problems, independently or in a team.

+

But the development of hands-on practical skills, requires some essential +knowledge about the domain and some willingness to try different approaches +in case one gets stuck. Some call this the “KSA approach” +(“Knowledge-Skills-Attitude). Hence, I +try to impart the essential knowledge (and where to find out more) at my +trainings. And to encourage and challenge students in order to make them +overcome their self-perceived limits (e.g. “I’m a Humanist, I can’t use +Python virtualenv”).

+

I’ve been trying to study more about the Cognitive aspects of learning over the years, +and I should find out the time to return to that. There’s very interesting +research in Problem Solving, with Learning being a important component in that domain.

+

Storytelling: humans are neurologically made for paying attention to good +stories, and that’s something that I try to put into account: to give +a lesson like it would be a relevant narrative for the students, one that they +could relate to and help them in their work

+

I like to draw and be creative with that, but have to pay attention to +my handwriting during my trainings. I reckon that Architectural diagrams +help students to understand the big picture, so I should invest more on +those when development training material. I would also like to start looking into +Concept Maps and Semantic Trees in training.

+
+
+
+

Interactive teaching style

+
+

What are the top issues new instructors face?

+ +
+
+
+

The Carpentries and CodeRefinery approaches to teaching

+

Here we will give you a very short overview of the Carpentries approach to teaching and highlight +parts that are most important for teaching CodeRefinery style lessons.

+

Most CodeRefinery instructors have completed the +Carpentry instructor training workshop, which +anyone can apply for

+
+

This material

+

This section is derived from the +Carpentries instructor training material. +We encourage you to further study this material later, and to sign up for a 2-day Carpentry +intructor training workshop.

+
+
+
+

Key principles

+

The “Carpentries” approach to teaching is based on:

+
    +
  • Applying research-based teaching principles, especially as they apply to the +Carpentries audience.

  • +
  • Understanding the importance of a respectful and inclusive classroom environment.

  • +
+
+
Carpentries teaching principles
+
    +
  • Learners need to practice what they are learning in real time and get feedback on what they +are doing. That is why the teaching approach relies on live coding.

  • +
  • Learners best learn in a respectful classroom environment, so the Carpentries use a +Code of Conduct.

  • +
  • Learners are encouraged to help each other during workshops as this improves their confidence +and reinforces concepts taught.

  • +
  • Carpentry instructors try to have learners do something that they think is useful in their +daily work within 15 minutes of starting each lesson.

  • +
+

What to Teach

+

In CodeRefinery, we follow The Carpentries teaching principles but in addition to live coding +we often use group discussions to put in context the concepts we are teaching.

+

Applying these teaching principles are not sufficient and in addition we need to be able to check +the effectiveness of our methods.

+
+
+
+
+

On the importance of feedback

+

Feedback is an essential part of effective learning. Feedback is bi-directional:

+
    +
  • To be effective, instructors need feedback on their learners’ progress. Learners can also check their progress and ask relevant questions to get clarification.

  • +
  • Instructors also need feedback on their teaching. For instance, this can help them to adapt the pace, add/skip optional exercises and improve their teaching.

  • +
+
+
Getting/giving feedback on learners’ progress
+

This feedback comes through what is called formative assessments (in contrast +to summative assessment).

+
+

Summative Assessment

+

Summative assessment is used +to judge whether a learner has reached an acceptable level of competence. +Usually at the end of a course +Learners either “pass” or “fail” a summative assessment. +One example is a driving exam, +which tells the rest of society whether someone can safely be allowed on the road. Most assessment done in university +courses is summative, and is used to assign course grades.

+
+
+

Formative assessment

+

Formative assessment takes place during teaching and learning. It sounds like +a fancy term, but it can be used to describe any interaction or activity +that provides feedback to both instructors and learners about learners’ level of understanding of the +material. For learners, this feedback can help focus their study efforts. For instructors, it allows them to refocus +their instruction to respond to challenges that learners are facing. +Used continuously

+
+

Learners don’t “pass” or “fail” formative assessments; they are simply a feedback mechanism. +For example, a music teacher might ask a learner to play a scale very slowly +in order to see whether they are breathing correctly, +and if not, what they should change.

+

Formative assessment is most useful when it happens frequently (we’ll talk about how frequently later) +and when the results are easily interpretable by the learner and instructor.

+

CodeRefinery uses different instruments to get feedback from learners:

+
    +
  • Surveys: we will discuss about CodeRefinery pre/post-surveys in the episode +Running a workshop: online.

  • +
  • Exercises: we have many exercises during CodeRefinery workshops and use polls too but not necessarily many multiple-choice questions. +This is something that we may change in the future but the initial reason was that we build on existing knowledge +(see below section on our target audience) and give recommendations for best software practices: +there is no unique solution and you would like our learners to choose the approach that is most suitable for them. +For the same reasons, we have many optional exercises to accommodate the different levels. +We would like everyone to get something useful out of the CodeRefinery workshops.

  • +
+
+
+
Getting/giving feedback on teaching
+

Teaching is a skill. One of the objective of the CodeRefinery Instructor training is to give you +the confidence in teaching CodeRefinery lessons. Later we will have group work where we will +practice teaching some lessons.

+

Before doing so, we will learn here to give feedback on teaching using the same +positive-vs-negative and content-vs-presentation rubric.

+
+

Give feedback on teaching (optional, 10 mn)

+

This exercise aims at learning to give feedback. It is optional as we have +similar exercises when practising teaching). +As a group, we will watch this video of teaching and +give feedback on two axes: positive vs. negative and content vs. presentation. Have each person in +the class add one point to a 2x2 grid on a whiteboard or in the shared notes (hackMD, etherpad, google doc) without duplicating any points. +For online instructor training event, use breakout room (4-5 persons per group) to facilitate discussion. Then each group reports to the shared notes. +You can use a rubric (used during The Carpentries teaching demos) to help you take notes. +What did other people see that you missed? What did they think that you strongly agree or disagree with?

+
+
+
+
+
+

Who are the learners

+

The first task in teaching is to figure out who your learners are. The Carpentries approach is +based on the work of researchers like Patricia Benner, +who applied the +Dreyfus model of skill acquisition +in her studies of +how nurses progress from novice to expert +(see also books by Benner). +This work indicates that through practice and formal instruction, learners acquire skills and advance +through distinct stages. In simplified form, the three stages of this model are:

+
+
Novices, competent practitioners and experts
+

Novice, Competent Practitioner, Expert

+
    +
  • Novice: someone who doesn’t know what they don’t know, i.e., +they don’t yet know what the key ideas in the domain are or how they relate. +One sign that someone is a novice is that their questions “aren’t even wrong”.

    +
      +
    • Example: A novice learner in a Carpentries workshop might never have heard of the bash +shell, and therefore may have no understanding of how it relates to their file system or +other programs on their computer.

    • +
    • Example HPC: A learner who has never executed a program on remote computer in headless mode

    • +
    • Example HPC: A learner who has no understanding about using a queue system and having a +hard time why a program can not be run directly after login in.

    • +
    +
  • +
  • Competent practitioner: someone who has enough understanding for everyday purposes. +They won’t know all the details of how something works and their understanding may not +be entirely accurate, but it is sufficient for completing normal tasks with normal +effort under normal circumstances.

    +
      +
    • Example: A competent practitioner in a Carpentries workshop might have used the shell +before and understand how to move around directories and use individual programs, but +they might not understand how they can fit these programs together to build scripts +and automate large tasks.

    • +
    • Example: A competent practitioner in a CodeRefinery workshop is someone that understands +the concepts of best software practices and its importance. He/she clearly sees the +benefits of applying best software practices but he/she does not fully know yet how and +what to use for their own projects.

    • +
    • Example HPC: Knows how to establish a connection to a cluster and have submitted jobs. +But may not know how to request optimal amount of resources in a job and how to setup +parallel jobs

    • +
    +
  • +
  • Expert: someone who can easily handle situations that are out of the ordinary.

    +
      +
    • Example: An expert in a Carpentries workshop may have experience writing and running shell +scripts and, when presented with a problem, immediately sees how these skills can be used +to solve the problem.

    • +
    • Example HPC: A learner who has a good understanding of the queue system, parallel processing +and understand how to interpret error reports when something goes wrong and knows how to +get help.

    • +
    +
  • +
+
+
+
Cognitive Development and Mental Models
+

Effective learning is facilitated by the creation of a well-founded mental model. A mental model +is a collection of concepts and facts, along with the relationships between those concepts, which +a person has about a topic. For example, a long-time resident of the United States may have an +advanced understanding of the location of US states, major cities and landmarks, weather patterns, +regional economies and demographic patterns, as well as the relationships among these, compared +with their understanding of these relationships for other countries. In other words, their mental +model of the United States is more complex compared with their mental model of other countries.

+

We can distinguish between a novice and a competent practitioner for a given domain based +on the complexity of their mental models.

+
    +
  • A novice is someone who has not yet built a mental model of the domain. +They therefore reason by analogy and guesswork, borrowing bits and pieces +of their mental models of other domains which seem superficially similar.

  • +
  • A competent practitioner is someone who has a mental model that’s good enough +for everyday purposes. This model does not have to be completely accurate in order +to be useful: for example, the average driver’s mental model of how a car works +probably doesn’t include most of the complexities that a mechanical engineer +would be concerned with.

  • +
+

We could expect a mixture of learners from novice and competent practitioner groups +in HPC training events.

+

Mental Models

+
+
+
+
How “knowledge” gets in the way
+

Mental models are hardly ever built from scratch. Every learner comes to a topic with +some amount of information, ideas and opinions about the topic. This is true even in +the case where a learner can’t articulate their prior knowledge and beliefs.

+

In many cases, this prior knowledge is incomplete or inaccurate. Inaccurate beliefs +can be termed “misconceptions” and can impede learning by making it more difficult for +learners to incorporate new, correct information into their mental models. +Correcting learners’ misconceptions is at least as important as presenting them with +correct information. Broadly speaking, misconceptions fall into three categories:

+
    +
  • Simple factual errors, such as believing that Vancouver is the capital of +British Columbia. These are the easiest to correct.

  • +
  • Broken models, such as believing that motion and acceleration must be in the +same direction. We can address these by having learners reason through examples to +see contradictions.

  • +
  • Fundamental beliefs, such as “the world is only a few thousand years old” or +“human beings cannot affect the planet’s climate”. These beliefs are deeply connected +to the learner’s social identity and are the hardest to change.

  • +
+

The current HPC carpentry workshop material are aimed at Novice of HPC

+

Among Novice learners there might be learners who are experts in their domain and very +competent in the program they are executing, but may not have used a HPC system before. +Then among the competent practitioners There might be learners who repeat some procedures +they have inherited but lack a in-depth understanding of what’s going on. That is why it is +important to get accurate feedback, before and during the workshops to understand the learner profiles.

+
+

Exercise: How to identify learner profiles?

+
    +
  1. How to identify leaner profiles from surveys and during the class

  2. +
  3. Which types of learners should the leassons focus on

  4. +
+
+
+
+
+
+

CodeRefinery Curriculum and Reverse Instructional Design (with recommendations for HPC carpentries)

+

When writing a CodeRefinery lesson, we take a “reverse” approach to instruction, +as described in Wiggins and McTighe’s +Understanding by Design, +that keeps the focus firmly on learning outcomes. The order of preparation in this case becomes

+
    +
  • Determine your learning objectives

  • +
  • Decide what constitutes evidence that objectives have been met, and design assessments +to target that evidence

  • +
  • Design instruction: Sort assessments in order of increasing complexity, +and write content that connects everything together

  • +
+
+
Working with learning objectives
+

Each CodeRefinery lesson (also the HPC capentries lessons) usually has a learning objectives section. +Good learning objectives are quite specific about the intended effect of a lesson on its learners. +We aim to create learning objectives that are specific, accurate, and informative for +both learners and instructors.

+
+
+
Using Bloom’s Taxonomy to write effective learning objectives
+

Bloom’s Taxonomy is a framework for thinking about learning that breaks progress down into discrete, hierarchical steps. +While many ideas have come and gone in education, Bloom’s has remained a useful tool for educators, in particular because the +hierarchy seems to be reasonably valid: outcomes at the top of the hierarchy cannot be achieved without mastery of outcomes at +the bottom. In the long term, everybody wants to be at the top. However, in aiming to meet learners where they are, we also +need to be mindful about helping them to “grow a level,” helping them to recognize when they have achieved that growth, and +guiding them to look ahead to where we might not be able to take them.

+

Bloom's Taxonomy

+

Image credit: Vanderbilt University Center for Teaching

+
+
+
Revisiting Learning objectives
+

When using existing teaching material, reverse instructional design principles might be applied as +follows:

+
    +
  1. Review the lesson’s learning objectives carefully, thinking about how they will work for your audience

  2. +
  3. Scan the lesson to identify promising points to check in with your learners, using formative assessment to verify that objectives have been met

  4. +
  5. Review the connecting content in detail to be sure everything works and you have anticipated likely problems and questions.

  6. +
+

We strongly encourage you to read them before teaching a lesson and to review whether they still match the content of the lesson:

+
+
+
+
+

Workshop manuals

+

CodeRefinery maintains a number of workshop manuals +with most of the “primary” information. This episode condenses this +into a quick overview.

+
+
+

Running a workshop: online

+
+

Online teaching discussion

+
+

Discussion: Online vs in-person

+

In notes:

+
    +
  • Compare and contrast the benefits of online teaching with +in-person: {advantage, disadvantage} × {content, presentation}

  • +
  • How do you have to prepare differently?

  • +
  • What are your own experiences?

  • +
+
+
+
+

Case study: Mega-CodeRefinery and Finland HPC Kickstart

+
    +
  • Mega-CodeRefinery

    +
      +
    • Audience of around 90-100

    • +
    • “bring your own breakout room” (see below)

    • +
    • 3 days/week, 6 days total

    • +
    • Lessons as normal in CodeRefinery

    • +
    +
  • +
  • HPC Kickstart

    +
      +
    • 250 registered, ~180 max participants

    • +
    • Multi-university: local differences made this much harder to manage.

    • +
    • Breakout rooms not pre-planned.

    • +
    +
  • +
+

Mega-CodeRefinery worked very well, HPC kickstart didn’t - but not +because of the size.

+
+
+

General workshop arrangements

+ +
    +
  • Select a coordinator, recruit instructors (at least 3 is important), +find helpers

  • +
  • Find a good lecture room: +requirements

  • +
  • Set up workshop webpage using the [Github, template +repository](https://github.com/coderefinery/template-workshop-webpage]: +see +manuals

  • +
  • Advertising the workshop

  • +
  • Communication with registered participants

  • +
+
+
+

CodeRefinery online scaling strategy

+
    +
  • We started online workshops in 2020 March, for the obvious reasons.

  • +
  • First, we started with two “normal size” (20 people) practice +workshops

  • +
  • Then we did a 100 person workshop. It went well, but there is less +tolerance for problems.

  • +
+
+
Basic preparation
+
    +
  • You need more breaks are needed

  • +
  • People have a way of doing too many things and not focusing.

  • +
  • How to attend an online +workshop” +guide to prepare learners

  • +
+
+
+
Basic platform: Zoom
+
    +
  • Zoom (not the most ethical, but worked well and was available)

  • +
  • Zoom mechanics: instructions for +students.

    +
      +
    • Mostly things that are known

    • +
    • We don’t use Zoom interaction features much anymore +(faster/slower/etc), but breakout rooms and HackMD instead

    • +
    +
  • +
  • See also: Online training +manual +(which is getting a bit old compared to what is below).

  • +
+
+
+
Breakout rooms, bring your own team
+
    +
  • Breakout rooms are

    +
      +
    • Static: same people across whole workshop

    • +
    • Contain one helper per room (see below)

    • +
    +
  • +
  • Team registration: accept a “team” field when registering, people on the +same team are put together.

    +
      +
    • Gives motivations for learners to bring their colleagues and +learn together.

    • +
    • More than one person learning together greatly increases update

    • +
    +
  • +
  • You need a powerful enough registration system to assign rooms and +email them to people!

  • +
  • We ask people to name themselves “(N) Firstname Lastname” or “(N,H) +Firstname Lastname” for helpers. Then it is fast to assign them to +their designated breakout rooms.

  • +
  • See also: Breakout room +mechanics

  • +
+
+
+
Helper training
+
    +
  • Each breakout room has a helper

  • +
  • Helper should be a little bit familiar, but not expected to be able +to answer all questions.

  • +
  • Special, custom helper +training +since helpers make or break the workshop

  • +
  • Helper recruitment:

    +
      +
    • Our networks

    • +
    • Team registration: if a team registers with their own helper, then +they are guaranteed to get in together. “bring your own breakout +room”

    • +
    • Former learners, ask them to come back.

    • +
    +
  • +
  • Two helper trainings the week before the workshop.

  • +
+
+
+
Staff roles
+

To reduce stress on any one person, we clearly define the different +roles and try to avoid overlap. We actually have enough people for +all of these, so it works well.

+
    +
  • Workshop coordinator

    +
      +
    • Registration, etc.

    • +
    +
  • +
  • Zoom host

    +
      +
    • Handles registration, breakout rooms, recording, Zoom chat.

    • +
    +
  • +
  • HackMD helper

    +
      +
    • Dedicated to watching HackMD and answering questions quickly.

    • +
    • Host on manuals

    • +
    +
  • +
  • Expert helpers

    +
      +
    • “Spare hands” who rotate between breakout rooms and make sure +helpers are doing well.

    • +
    • Give feedback to instructor about how breakout rooms are going.

    • +
    • Take the place of missing helpers.

    • +
    • Easy way for any people with a bit of spare time to help out.

    • +
    • Expert helpers in workshop

    • +
    +
  • +
  • Instructors

    +
      +
    • Teach, they shouldn’t overlap with the above roles (but serve as +expert helpers other times).

    • +
    • Usually also improve the lesson a bit before teaching

    • +
    • General staff intro in manuals

    • +
    +
  • +
  • Workshop preparation meeting

    + +
  • +
+
+
+
HackMD
+
    +
  • We’ve been using it here

  • +
  • Chat doesn’t work wen large, written +document does.

  • +
  • HackMD can just about scale to ~100 person workshop. Recommend +learners keep it in view mode while not editing.

  • +
  • Voice questions are still allowed, but will be recorded. Staff +raise important questions from HackMD to the instructor immediately.

  • +
  • HackMD also allows communication when in breakout rooms.

  • +
  • You can get multiple answers, and answers can be improved over +time.

  • +
  • HackMD +mechanics +and HackMD +helpers.

  • +
+
+
+
Recording and streaming
+
    +
  • When you have 100 people, main room is quiet anyway: you don’t lose +much by recording.

    +
      +
    • Questions anonymously in HackMD, privacy loss is not so bad

    • +
    +
  • +
  • Breakout rooms are never recorded

  • +
  • Streaming

    +
      +
    • We streamed via Twitch: https://twitch.tv/coderefinery

    • +
    • We typically get 5-40 viewers.

    • +
    • Zoom can directly send the stream to Twitch: no extra software +needed.

    • +
    • Twitch archives videos for 14 days, which allows learners to get +an instant reply (we get hundreds of views in the next days).

    • +
    • So while possibly not useful for new people to learn, the instant +reply is very useful. Instructor can also work on problems in +main stream during breakout rooms, which learners can watch +later.

    • +
    • Streamers also have access to HackMD to ask questions.

    • +
    +
  • +
  • Certain tricks needed to keep learners from appearing in recording +or stream

    +
      +
    • “Spotlight video”, host does not go to gallery view, uses dual +monitor mode. We are still figuring this out.

    • +
    +
  • +
+
+
+
Installation time
+
    +
  • People have to be ready once we start, or else everything fails.

  • +
  • Two installation help times the week before.

  • +
  • Every email emphasizes that you have to be prepared, and “requires” +you to attend workshops (but really it’s only)

  • +
  • Installation instructions include steps to verify

  • +
  • Installation instructions also include video demonstrations of +installation and verification.

  • +
  • We haven’t had that many installation problems, but also we keep the +requirements simple.

  • +
  • Helper introduction is right before software install time, so +helpers can stay and help with install if they want.

  • +
  • Design to be easy to install and get set up.

  • +
+
+
+
Other notes
+
    +
  • Make breakout sessions as long as possible: 10 minutes is really too +short. 20 minutes is a good minimum time.

  • +
  • Be very clear about exercise expectations

  • +
  • Keep HackMD updated as a log.

  • +
  • Don’t combine breaks and breakout times.

  • +
  • The more people you have, the more diverse audience you have and the +more people overwhelmed and under whelmed.

  • +
+
+
+
+

Workshop collaborations

+

Why limit ourselves to CodeRefinery workshop? Why not use our network +and techniquess for more

+
    +
  • Case study: Python for Scientific +Computing

    +
      +
    • Started by Aalto

    • +
    • Announced to CodeRefinery, five more instructors from three +countries joined.

    • +
    • Rapid collaboration, taught course shortly later.

    • +
    • Announced to all institutions. Some places had physical rooms, +some were pure online

    • +
    • Also streamed

    • +
    • It was much more fun and less stressful to work together

    • +
    +
  • +
  • We want to continue this kind of collaboration in other workshops.

  • +
+
+
+
+

How to teach online

+
+

Objectives

+
    +
  • Understand the benefits and disadvantage of online teaching, +compared to in-person

  • +
  • Set up a good screen share

  • +
  • Understand the benefits and disadvantages of team teaching

  • +
  • Prepare for the teaching practice

  • +
+
+
+

Why teaching mechanics matter

+
    +
  • When you teach, you are mainly showing a basic example for the +learner to follow along

  • +
  • The learner has a lot more to think about than you do, so you need +to minimize the possible distractions and unnecessary weirdness.

  • +
  • A learner will often only one small screen, limiting the number of +things that they can think about.

  • +
  • You are must faster than learners (5 times possibly?) You have to +do things to slow yourself down.

  • +
  • It’s easy to save these mechanics until the end, and then you run +out of time.

  • +
+
+
+

Shell sharing

+ +

When doing any demonstration, there are difficulties:

+
    +
  • If one misses something, you can’t rewind to see it - is there any +way to catch up?

  • +
  • The learner must get oriented with the whole picture, while +instructor knows precisely where to focus.

  • +
+

A good shell share has some of the following properties:

+
    +
  • Large font

  • +
  • Shell history, available separately from the main shell window

  • +
  • Closely matches the type-along instructions

  • +
+

We have a collection of shell sharing systems:

+ +
+

Discussion

+

The instructor will demonstrate several shell-sharing systems. You +will use this in the teaching practice.

+
+
+
+

Screen sharing

+
+

Discussion

+

Look at the various screen layouts in the CodeRefinery +manuals. +Use the HackMD to comment about what which are better or worse.

+ +
+
    +
  • Many learners will have a smaller screen than you.

  • +
  • You should plan for learners with only one small screen.

  • +
  • A learner will need to focus on both your screen share and their +work.

  • +
  • Sharing your a whole screen is almost always a bad idea, if you want +the learners to do anything at the same time.

  • +
  • If you constrict yourself, then your experience is more similar to +that of a learner.

  • +
+

Vertical sharing:

+
    +
  • CodeRefinery has recently started trialing a vertical share +system, where you share a vertical half of your screen.

  • +
  • This allows learners with one screen to display your screen +side-by-side with their learn

  • +
  • Zoom provides a “Share a part of screen” that is good for this.

  • +
+
+
+

Meta-talk

+

Don’t just teach, also make sure you guide the learners through the +course.

+
    +
  • You know what you just discussed, and what is coming next, but +learners are often stuck thinking about now.

  • +
  • Give a lot of “meta-talk” that is not just about the topic you are +teaching, but how you are teaching it.

  • +
  • Examples

    +
      +
    • Why you are doing each episode

    • +
    • What is the purpose of each exercise

    • +
    • Clearly state what someone should accomplish in each exercise and +how long it will take - don’t assume this is obvious.

    • +
    • What is the point of each lesson. How much should people expect +to get from it? Should you follow everything, or are some things +advanced and optional? Make that clear.

    • +
    +
  • +
+
+
+

Teach teaching

+
    +
  • Demonstration-based teaching require two different types of focus:

    +
      +
    • Doing the mechanical steps as a demonstration

    • +
    • Explaining why you are doing it

    • +
    +
  • +
  • This is a lot for one person to keep in mind, so can multiple people +work together for this?

  • +
  • Team teaching idea:

    +
      +
    • One person is doing the demonstrations

    • +
    • One person is giving the commentary about what they are doing

    • +
    • The lecture becomes a discussion between two people instead.

    • +
    +
  • +
+

Advantages:

+
    +
  • This reduces the pressure on each person (reduces demo effect)

  • +
  • You are less likely to forget things

  • +
  • It slows you down in teaching

  • +
  • It makes the lesson more interesting to listen to

  • +
  • One person can follow questions

  • +
  • Great for introducing new instructors (which half is easier to start +with?)

  • +
+

Disadvantage:

+
    +
  • Requires two people’s time

  • +
  • Requires coordination when preparing (slows you down in preparation)

  • +
  • Unfamiliar concept to most people

  • +
+
+
+

Questions

+
    +
  • Questions are great, and important for any practical and interactive +class

  • +
  • But questions in main room doesn’t scale to very large rooms.

  • +
  • CodeRefinery strategy: HackMD for questions

    +
      +
    • Chat is not good enough, you can’t reply to old things

    • +
    • HackMD allows threaded replies and follow up later

    • +
    • You need some other helpers to watch HackMD and answer, and bring +things up to you. And let you know how things are going.

    • +
    • Learners can ask anonymously

    • +
    • Learners don’t have to worry about interrupting the flow.

    • +
    • Disadvantage: can produce information overload, warn people to not +follow too closely

    • +
    • With too few people, it can turn out to be very quiet.

    • +
    +
  • +
  • We will learn more about HackMD questions tomorrow in +Running a workshop: online.

  • +
+
+

See also

+ +
+
+
+

Teaching practice

+

In Teaching practice and feedback, you will break into groups and try to +apply these strategies to a five-minute example session.

+
+
+

See also

+

In this lesson:

+ +

CodeRefinery manuals:

+ +
+
+
+

Teaching practice and feedback

+

Goals of the teaching practice:

+
    +
  • In groups of 4-5 persons we will practice teaching a 5-minute segment +of a lesson of your choice.

  • +
  • The section you pick should require screen sharing and be of some +demonstration or follow-along task (preferably using a shell) to also +practice having a good screen-sharing setup.

  • +
  • We will practice giving constructive feedback.

  • +
  • We will practice improving our 5-minute segment by taking the feedback into account.

  • +
  • In both session you can teach the same topic/segment but if you prefer you can also +change the topic/aspect for the second session.

  • +
+
+
+

Instructor demo

+
    +
  • In order to demonstrate the goals of this section, the instructor +will make a 5-minute demo for your evaluation.

  • +
  • It is designed to include some good and bad practices for you to +notice.

  • +
+
+
+
+

Teaching demos part 1

+

In group rooms, 50 minutes.

+
+

Exercise

+
    +
  • We organize the breakout rooms to not only discuss one lesson/topic so that it is more interesting +to listen and also probably we will all get more useful feedback.

  • +
  • Give each other constructive verbal feedback on the teaching demos, for example +using this demo rubric.

  • +
  • Write down questions (in the collaborative document) that you would like to +discuss in the main room or interesting conclusions which you would like to +share with others.

  • +
+
+
+
+

Teaching demos, part 2

+

In group rooms, 50 minutes.

+
+

Exercise

+
    +
  • In the second round we distribute the rooms differently so that you can +present it to a new group of workshop participants and can receive new +feedback.

  • +
  • Ask for feedback and one/few point(s) you want to improve.

  • +
  • In your second trial check whether you feel the demonstration improved.

  • +
  • Share your lessons learned in the collaborative document.

  • +
  • Give us also feedback on this exercise format. Was it useful? What can we improve?

  • +
+
+
+
+
+

Discussion

+
+

Main room discussion

+
    +
  • We discuss questions and conclusions which came up during the group work session.

  • +
+
+
+
+
+

Optional: feedback for two live-coding examples

+
+

Exercise

+

Teaching by live coding is a +performance art which requires practice. +This exercise highlights some typical pitfalls that most instructors +fall into sooner or later, and also shows how to avoid them. +Watch closely since we will be giving feedback!

+
    +
  • Watch these two videos: video 1 and +video 2

  • +
  • What was better in video 1 and what was better in video 2?

  • +
  • Please give feedback in the shared workshop document.

  • +
+
+
+
+
+

test

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020-, The contributors.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/singlehtml/objects.inv b/branch/ignore/singlehtml/objects.inv new file mode 100644 index 0000000..2b7a4ef Binary files /dev/null and b/branch/ignore/singlehtml/objects.inv differ diff --git a/branch/ignore/teaching-online/index.html b/branch/ignore/teaching-online/index.html new file mode 100644 index 0000000..817b9c5 --- /dev/null +++ b/branch/ignore/teaching-online/index.html @@ -0,0 +1,211 @@ + + + + + + + Teaching online — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Teaching online

+

Is online teaching better or worse? As usual for that question, “it’s +all a trade-off”. We believe that many people tried to directly +translate in-person strategies to online, and teaching suffered. In +some ways, this even revealed the flaws of in-person pedagogy (remove +some interaction and not much is left other than an info-dump).

+
+

Exercise

+

Using HackMD, brainstorm advantages and disadvantages of online and +in-person teaching. For each disadvantage of each, think of ways to compensate.

+
+
    +
  • We won’t elaborate more here right now - most of the rest of the +course somehow relates to online teaching!

  • +
  • We will see many techniques which compensate for some of the +disadvantages in the section tools of teaching.

  • +
  • Workshop organization will discuss new collaborative +opportunities with online teaching.

  • +
+
+

See also

+
    +
  • The rest of this course

  • +
  • CodeRefinery manuals: https://coderefinery.github.io/manuals/

  • +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/teaching-practice/index.html b/branch/ignore/teaching-practice/index.html new file mode 100644 index 0000000..5e9ee1d --- /dev/null +++ b/branch/ignore/teaching-practice/index.html @@ -0,0 +1,271 @@ + + + + + + + Teaching practice and feedback — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Teaching practice and feedback

+

Goals of the teaching practice:

+
    +
  • In groups of 4-5 persons we will practice teaching a 5-minute segment +of a lesson of your choice.

  • +
  • The section you pick should require screen sharing and be of some +demonstration or follow-along task (preferably using a shell) to also +practice having a good screen-sharing setup.

  • +
  • We will practice giving constructive feedback.

  • +
  • We will practice improving our 5-minute segment by taking the feedback into account.

  • +
  • In both session you can teach the same topic/segment but if you prefer you can also +change the topic/aspect for the second session.

  • +
+
+
+

Instructor demo

+
    +
  • In order to demonstrate the goals of this section, the instructor +will make a 5-minute demo for your evaluation.

  • +
  • It is designed to include some good and bad practices for you to +notice.

  • +
+
+
+
+

Teaching demos part 1

+

In group rooms, 50 minutes.

+
+

Exercise

+
    +
  • We organize the breakout rooms to not only discuss one lesson/topic so that it is more interesting +to listen and also probably we will all get more useful feedback.

  • +
  • Give each other constructive verbal feedback on the teaching demos, for example +using this demo rubric.

  • +
  • Write down questions (in the collaborative document) that you would like to +discuss in the main room or interesting conclusions which you would like to +share with others.

  • +
+
+
+
+

Teaching demos, part 2

+

In group rooms, 50 minutes.

+
+

Exercise

+
    +
  • In the second round we distribute the rooms differently so that you can +present it to a new group of workshop participants and can receive new +feedback.

  • +
  • Ask for feedback and one/few point(s) you want to improve.

  • +
  • In your second trial check whether you feel the demonstration improved.

  • +
  • Share your lessons learned in the collaborative document.

  • +
  • Give us also feedback on this exercise format. Was it useful? What can we improve?

  • +
+
+
+
+
+

Discussion

+
+

Main room discussion

+
    +
  • We discuss questions and conclusions which came up during the group work session.

  • +
+
+
+
+
+

Optional: feedback for two live-coding examples

+
+

Exercise

+

Teaching by live coding is a +performance art which requires practice. +This exercise highlights some typical pitfalls that most instructors +fall into sooner or later, and also shows how to avoid them. +Watch closely since we will be giving feedback!

+
    +
  • Watch these two videos: video 1 and +video 2

  • +
  • What was better in video 1 and what was better in video 2?

  • +
  • Please give feedback in the shared workshop document.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/teaching-strategies/index.html b/branch/ignore/teaching-strategies/index.html new file mode 100644 index 0000000..a2080ef --- /dev/null +++ b/branch/ignore/teaching-strategies/index.html @@ -0,0 +1,421 @@ + + + + + + + How to teach online — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

How to teach online

+
+

Objectives

+
    +
  • Understand the benefits and disadvantage of online teaching, +compared to in-person

  • +
  • Set up a good screen share

  • +
  • Understand the benefits and disadvantages of team teaching

  • +
  • Prepare for the teaching practice

  • +
+
+
+

Why teaching mechanics matter

+
    +
  • When you teach, you are mainly showing a basic example for the +learner to follow along

  • +
  • The learner has a lot more to think about than you do, so you need +to minimize the possible distractions and unnecessary weirdness.

  • +
  • A learner will often only one small screen, limiting the number of +things that they can think about.

  • +
  • You are must faster than learners (5 times possibly?) You have to +do things to slow yourself down.

  • +
  • It’s easy to save these mechanics until the end, and then you run +out of time.

  • +
+
+
+

Shell sharing

+ +

When doing any demonstration, there are difficulties:

+
    +
  • If one misses something, you can’t rewind to see it - is there any +way to catch up?

  • +
  • The learner must get oriented with the whole picture, while +instructor knows precisely where to focus.

  • +
+

A good shell share has some of the following properties:

+
    +
  • Large font

  • +
  • Shell history, available separately from the main shell window

  • +
  • Closely matches the type-along instructions

  • +
+

We have a collection of shell sharing systems:

+ +
+

Discussion

+

The instructor will demonstrate several shell-sharing systems. You +will use this in the teaching practice.

+
+
+
+

Screen sharing

+
+

Discussion

+

Look at the various screen layouts in the CodeRefinery +manuals. +Use the HackMD to comment about what which are better or worse.

+ +
+
    +
  • Many learners will have a smaller screen than you.

  • +
  • You should plan for learners with only one small screen.

  • +
  • A learner will need to focus on both your screen share and their +work.

  • +
  • Sharing your a whole screen is almost always a bad idea, if you want +the learners to do anything at the same time.

  • +
  • If you constrict yourself, then your experience is more similar to +that of a learner.

  • +
+

Vertical sharing:

+
    +
  • CodeRefinery has recently started trialing a vertical share +system, where you share a vertical half of your screen.

  • +
  • This allows learners with one screen to display your screen +side-by-side with their learn

  • +
  • Zoom provides a “Share a part of screen” that is good for this.

  • +
+
+
+

Meta-talk

+

Don’t just teach, also make sure you guide the learners through the +course.

+
    +
  • You know what you just discussed, and what is coming next, but +learners are often stuck thinking about now.

  • +
  • Give a lot of “meta-talk” that is not just about the topic you are +teaching, but how you are teaching it.

  • +
  • Examples

    +
      +
    • Why you are doing each episode

    • +
    • What is the purpose of each exercise

    • +
    • Clearly state what someone should accomplish in each exercise and +how long it will take - don’t assume this is obvious.

    • +
    • What is the point of each lesson. How much should people expect +to get from it? Should you follow everything, or are some things +advanced and optional? Make that clear.

    • +
    +
  • +
+
+
+

Teach teaching

+
    +
  • Demonstration-based teaching require two different types of focus:

    +
      +
    • Doing the mechanical steps as a demonstration

    • +
    • Explaining why you are doing it

    • +
    +
  • +
  • This is a lot for one person to keep in mind, so can multiple people +work together for this?

  • +
  • Team teaching idea:

    +
      +
    • One person is doing the demonstrations

    • +
    • One person is giving the commentary about what they are doing

    • +
    • The lecture becomes a discussion between two people instead.

    • +
    +
  • +
+

Advantages:

+
    +
  • This reduces the pressure on each person (reduces demo effect)

  • +
  • You are less likely to forget things

  • +
  • It slows you down in teaching

  • +
  • It makes the lesson more interesting to listen to

  • +
  • One person can follow questions

  • +
  • Great for introducing new instructors (which half is easier to start +with?)

  • +
+

Disadvantage:

+
    +
  • Requires two people’s time

  • +
  • Requires coordination when preparing (slows you down in preparation)

  • +
  • Unfamiliar concept to most people

  • +
+
+
+

Questions

+
    +
  • Questions are great, and important for any practical and interactive +class

  • +
  • But questions in main room doesn’t scale to very large rooms.

  • +
  • CodeRefinery strategy: HackMD for questions

    +
      +
    • Chat is not good enough, you can’t reply to old things

    • +
    • HackMD allows threaded replies and follow up later

    • +
    • You need some other helpers to watch HackMD and answer, and bring +things up to you. And let you know how things are going.

    • +
    • Learners can ask anonymously

    • +
    • Learners don’t have to worry about interrupting the flow.

    • +
    • Disadvantage: can produce information overload, warn people to not +follow too closely

    • +
    • With too few people, it can turn out to be very quiet.

    • +
    +
  • +
  • We will learn more about HackMD questions tomorrow in +Running a workshop: online.

  • +
+
+

See also

+ +
+
+
+

Teaching practice

+

In Teaching practice and feedback, you will break into groups and try to +apply these strategies to a five-minute example session.

+
+
+

See also

+

In this lesson:

+ +

CodeRefinery manuals:

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/team-teaching/index.html b/branch/ignore/team-teaching/index.html new file mode 100644 index 0000000..07737d8 --- /dev/null +++ b/branch/ignore/team-teaching/index.html @@ -0,0 +1,257 @@ + + + + + + + Team teaching — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Team teaching

+

One of the most significant improvemest of our teaching has been the +concept of co-teaching.

+
+

Co-teaching

+

Wikipedia: Co-teaching or team teaching is the division of labor +between educators to plan, organize, instruct and make assessments +on the same group of students, generally in the a common +classroom,[1] and often with a strong focus on those teaching as a +team complementing one another’s particular skills or other +strengths.

+
+

This is not strictly an effect of moving online. However, the +larger number of instructors and larger audiences make this practical +on a wide scale.

+
+

Primary article

+

https://coderefinery.github.io/manuals/team-teaching/

+
+
+

Benefits

+
    +
  • The course seems very interactive, much more so than expecting +students to speak up. The co-teacher can take on the “voice of the +audience”.

  • +
  • Quicker preparation time since co-teachers can rely on each other in +unexpected situations.

  • +
  • One co-teacher can be effectively learning at the same time and thus +acting as the “voice of the audience” in another way.

  • +
  • Great way to onboard new instructors - extensive training and +preparation no longer needed.

  • +
  • More active minds means better able to watch and react to other +feedback, such as HackMD or chat.

  • +
  • Less workload - one person does not have to prepare perfectly, any +uncertainty can usually be quickly answered by the other.

  • +
+
+
+

Strategies

+

In reality, these strategies are mixed and matched even within a +lesson, and there are many things between these:

+
    +
  • One person gives lectures, one does the typing during demos.

  • +
  • “Interview”: One primarily doing the “teaching”, one guiding by +asking questions - either as an interviewer or as a virtual learner.

  • +
+

Things that don’t work (are not team teaching):

+
    +
  • Dividing up a lesson into parts, each person gives different parts +independently.

  • +
+
+
+

Exercises

+
+

Exercise

+

Divide into groups of two or three. Choose one of the two models +in the team-teaching page, and quickly (5 min) prepare a short +topic (3-5 min) to team teach. You can quickly scan the +“preparation” section at the bottom.

+

The challenge is not just to give the lesson, but to prepare the +lesson quickly and rely on each other to give a good lesson anyway.

+
+
+
+

See also

+

(none yet)

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/teams/index.html b/branch/ignore/teams/index.html new file mode 100644 index 0000000..3a23315 --- /dev/null +++ b/branch/ignore/teams/index.html @@ -0,0 +1,287 @@ + + + + + + + Teams — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Teams

+

Everyone wants interaction in courses, yet when a group size gets too +large, it doesn’t have much interaction. A event in a physical space +naturally makes teams based on who is nearby. When done online, this +needs to be more explicit.

+
+

Primary articles

+ +
+
+

Basic concepts

+
    +
  • Teams are pre-assigned

  • +
  • Exercise leaders (aka helpers) assigned per team

  • +
  • Teams stay together during the whole workshop.

  • +
  • Learners can sign up either alone…

  • +
  • … or they can sign up with a pre-made team: people who know +each. “bring your own breakout room”:

    +
      +
    • When two people in a work group learn a skill, uptake within the +group is often much higher. Thus, we strongly encourage pre-made +teams that know each other.

    • +
    • Teams that all come from the same group or field, with a helper +from that field, can transition to help

    • +
    +
  • +
+
+
+

Online

+

In the best online implementations, our teams have these properties:

+
    +
  • Coordination of breakout rooms is a lot of work.

  • +
  • In zoom, we could request learners to rename to (N) Learner +Name, and then quickly assign people. Now, you can have learners +self-select their rooms. But will they actually do this, or stay in +main room?

  • +
  • One helper is assigned per team.

    +
      +
    • In fact, we would limit the number of registrations to 5× the +number of helpers so that all teams have a helper

    • +
    +
  • +
  • Our registration system (indico) is capable of mailing personalized +messages per person with their team information. This is quite a +bit of work to manage.

  • +
+

But they have these disadvantages:

+
    +
  • Much, much harder registration coordination, almost to the point of +being impossible.

  • +
  • Number of attendees.

  • +
  • Difficulties when attendees drop out partway through a course.

  • +
+
+
+

In-person

+

Teams may natuarally form based on setting location, but

+
    +
  • Teams may happen naturally by sitting at the same table

  • +
  • Do teams stay the same day after day?

  • +
  • Do teams get arranged in a manner useful for learning?

  • +
  • Do you have one helper per team?

  • +
  • Do you encourage people to interact explicitly enough?

  • +
  • Do you ensure that no one gets left out in the crowd? Are the teams +explicit enough?

  • +
+
+
+

Discussion: what we actually do

+
    +
  • For large enough CodeRefinery workshops, assign teams with one +helper each. Deal with re-adjustment

  • +
  • The livestream option allows everyone else to follow along.

  • +
  • In other workshops, create breakout rooms but somehow try let people +self-assign. Most don’t.

  • +
  • For large workshops without enough staff help, livestream and +encourage people to form their own teams and watch themselves - we +don’t actually need to be involved.

  • +
  • Teams can be delegated to a local organizer.

  • +
+
+
+

Exercises

+
+

Teams

+

Consider these questions:

+
    +
  • Should teams have similar or different people in them?

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/video-editing/index.html b/branch/ignore/video-editing/index.html new file mode 100644 index 0000000..4166cca --- /dev/null +++ b/branch/ignore/video-editing/index.html @@ -0,0 +1,564 @@ + + + + + + + Video editing — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Video editing

+

Video recordings could be useful for people attending a course later, +but also are (perhaps more) useful for immediate review and catching +up after missing a day in a workshop. For this, they need to be +released immediately, within a few hours of the workshop. +CodeRefinery can do this.

+

Hypothesis: videos must be processed the same evening as they were +recorded, otherwise (it may never happen) or (it’s too late to be +useful). To do that, we have to make processing good enough (not +perfect) and fast and distributeable

+
+

Primary articles

+ +
+
+

Summary

+
    +
  • Basic principle: privacy is more important than any other factor. +If we can’t guarantee privacy, we can’t release videos at all.

    +
      +
    • Disclaimers such as “if you don’t want to appear in a recording, +leave your video off and don’t say anything”, since a) accidents +happen especially when coming back from breakout rooms. b) it +creates an incentive to not interact or participate in the course.

    • +
    +
  • +
  • Livestreaming is important here: by separating the instruction from +the audience audio/video, there is no privacy risk in the raw +recording. They could be released or shared unprocessed.

  • +
  • Our overall priorities

    +
      +
    1. No learner (or anyone not staff) video, audio, names, etc. are +present in the recordings.

    2. +
    3. Good descriptions.

    4. +
    5. Removing breaks and other dead time.

    6. +
    7. Splitting videos into useful chunks (e.g. per-episode), perhaps +equal with the next one:

    8. +
    9. Good Table of Contents information so learners can jump to the +right spots (this also helps with “good description”.)

    10. +
    +
  • +
  • ffmpeg-editlist allows us to +define an edit in a text file (crowdsourceable on Github), and then +generate videos very quickly.

  • +
+
+
+

Exercises

+
+

Exercise A

+

These exercises will take you through the whole sequence.

+
+

Editing-1: Get your sample video

+

Download a sample video:

+
+
+
+
+

Editing-2: Run Whisper to generate raw subtitles and test video.

+

First off, install Whisper and generate the base subtitles, based +on the. Since this is probably too much to expect for a short +lesson, they are provided for you (above), but if you want you can +try using Whisper, or generating the subtitles some other way.

+

You can start generating subtitles now, while you do the next +steps, so that they are ready by the time you are ready to apply +the editlist. ffmpeg-editlist can also slice up the subtitles from +the main video to make subtitles for each segment you cut out.

+

Whisper is left as an exercise to the reader.

+ +
+
+

Editing-3: Create the basic editlist.yaml file

+

Install ffmpeg-editlist and try to +follow its instructions, to create an edit with these features:

+
    +
  • The input definition.

  • +
  • Two output sections: the “Intro to the course”, and “From data +storage to your science” talks (Remember it said the recording +started at 11:35… look at the schedule for hints on when it +might start!). This should have a start/end timestamp from the +original video.

  • +
+

A basic example:

+
- input: day1-raw.mkv
+
+# This is the output from one section.  Your result should have two of these sections.
+- output: part1.mkv
+  title: something
+  description: >-
+    some long
+    description of the
+    segment
+  editlist:
+    - start: 10:00    # start timestamp of the section, in *original* video
+    - end: 20:00      # end timestamp of the section, in the *original* video
+
+
+ +
+
+

Discussion: what makes a video easy to edit?

+
    +
  • Clear speaking and have high audio quality.

  • +
  • For subtitle generation: Separate sentences cleanly, otherwise it +gets in a “stream of words” instead of “punctuated sentences” +mode.

  • +
  • Clearly screen-sharing the place you are at, including section +name.

  • +
  • Clear transitions, “OK, now let’s move on to the next lesson, +LESSON-NAME. Going back to the main page, we see it here.”

  • +
  • Clearly indicate where the transitions are

  • +
  • Hover mouse cursor over the area you are currently talking about.

  • +
  • Scroll screen when you move on to a new topic.

  • +
  • Accurate course webpage and sticking to the schedule

  • +
+

All of these are also good for learners. By editing videos, you +become an advocate for good teaching overall.

+
+
+

Editing-4: Run ffmpeg-editlist

+

Install ffmpeg-editlist: pip install ffmpeg-editlist[srt] (you +may want to use a virtual environment, but these are very minimal +dependencies).

+

The ffmpeg command line tool must be available in your +PATH.

+ +
+
+

Editing-5: Add more features

+
    +
  • Several chapter definitions.(re-run and you should see a +.info.txt file also generated). Video chapter definitions +are timestamps of the original video, that get translated to +timestamps of the output video.

    +
    - output: part1.mkv
    +  editlist:
    +  - start: 10:00
    +  - -: Introduction    #  <-- New, `-` means "at start time"
    +  - 10:45: Part 1      #  <-- New
    +  - 15:00: Part 2      #  <-- New
    +  - end: 20:00
    +
    +
    +

    Look at the .info.txt files that come out now. What is new in it?

    +
  • +
  • Add in “workshop title”, “workshop description”, and see the +.info.txt files that come out now. This is ready for +copy-pasting into a YouTube description (first line is the title, +rest is the description).

    +

    Look at the new .info.txt files. What is new?

    +
  • +
+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+
+
+

Editing-7: Generate the final output file.

+
    +
  • Run ffmpeg-editlist with the --reencode option: this +re-encodes the video and makes sure that there is no black point +at the start.

  • +
  • If you re-run with --check, it won’t output a new video file, +but it will re-output the .info.txt and .srt files. +This is useful when you adjust descriptions or chapters.

  • +
+
+
+

Discussion: how to distribute this?

+

Create a flowchat of all the parts that need to be done, and which +parts can be done in parallel. Don’t forget things that you might +need to do before the workshop starts.

+

How hard was this editing? Was it worth it?

+
+
+
+

Exercise B

+

This is similar to the above but more brief and not on a real example +video.

+
+

Use ffmpeg-editlist to edit this sample video

+

Prerequisites: ffmpeg must be installed on your computer +outside of Python. Be able to install ffmpeg-editlist. This is +simple in a Python virtual environment, but if not the only +dependency is PyYAML.

+ +
+ +
+
+
+

See also

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/video-recording/index.html b/branch/ignore/video-recording/index.html new file mode 100644 index 0000000..6ed8228 --- /dev/null +++ b/branch/ignore/video-recording/index.html @@ -0,0 +1,245 @@ + + + + + + + Video recording — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Video recording

+
+

Keypoints

+
    +
  • We don’t expect many people to watch the recording from scratch later (but +some do) (some might look afterwards a few pieces, cmp. reading a book vs +look ing sth up from a book)

  • +
  • Learners getting an “instant replay” to review, or to make up for a lost day, is great.

  • +
  • Privacy is more important than any other factor

  • +
  • Recording only works if privacy is guaranteed and effort is low. +This is only possible with the instructor-audience split setup of livestreaming.

  • +
+
+
+

We try to release videos on the same day

+

Video recordings could be useful for people attending a course later, but also +are (perhaps more) useful for immediate review and catching up after missing +a day in a workshop.

+

For this, they need to be released immediately, within a few hours of the +workshop (see Video editing). CodeRefinery can do this.

+

For the videos to be released soon we need to make sure we guarantee privacy of +learners (see below). Our livestream setup makes the privacy guarantee easy at +the cost of separating instructors and learners into different video rooms.

+

Good preparation and documentation helps to make video recording and video +editing easier.

+
+
+

Privacy is more important than any other factor

+

If we can’t guarantee privacy, we can’t release videos at all.

+

Some events add a disclaimers such as “if you don’t want to appear +in a recording, leave your video off and don’t say anything”. We +would prefer not to do this, since:

+
    +
  • we know accidents happen (especially when coming back from breakout rooms)

  • +
  • it creates an incentive to not interact by voice/video

  • +
  • it could pressure participants to not object in order “to not be difficult”

  • +
+

Livestreaming solves this for us:

+
    +
  • By separating the instruction from +the audience audio/video, there is no privacy risk in the raw +recording. They could be released or shared unprocessed.

  • +
  • Recording with Zoom in a large meeting with all the instructors and +learners is simple, but not good for privacy: there are always +mistakes, reviewing takes too long.

  • +
  • Livestream platforms also provide instant recordings of the whole +stream, and some make instant replays possible. This could remove +the need for making our own videos, since one of the most important +cases is this instant replay idea.

  • +
+
+
+

Broadcasting role and setup

+

In the live-streaming setup, the Broadcasting role is central to video +recording.

+

Broadcaster description (most is not directly about recording): +https://coderefinery.github.io/manuals/broadcaster/

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/welcome/index.html b/branch/ignore/welcome/index.html new file mode 100644 index 0000000..5894db1 --- /dev/null +++ b/branch/ignore/welcome/index.html @@ -0,0 +1,269 @@ + + + + + + + Welcome and introduction — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Welcome and introduction

+
+

What do we want to get out of this workshop

+
    +
  • Introduction of instructors and helpers

  • +
  • Each instructor can say what we want to get out of the instructor training

  • +
  • But we want to know from everybody and collect these in the live notes

  • +
+
+
+
+

Goals for this workshop

+
+

Goals for this instructor training

+
    +
  • Inspire teachers and staff who have to teach indirectly as part of +their job: use best practices for the modern world, especially +for online teaching.

  • +
  • Promote collaboration in teaching: less going alone.

  • +
  • Promote CodeRefinery sustainability: form a network that can +work together to share the work and benefits.

  • +
+
+
+

Giving confidence

+
+

Goal number one should be that we give participants the confidence to +independently apply the tools or knowledge learnt. This is more important +that giving a “complete” overview. [Lucy Whalley gave this great comment at one of our workshops]

+
+
    +
  • You don’t have to know everything to use (or teach) something.

  • +
  • For the large majority of topics we teach, there are many resources online +which provide how-to guides or tutorials. And the Stack Overflow answer bank +isn’t getting any smaller. So we need to ask why do people attend in-person +sessions if there is information freely available? Our impression is that +it is for confidence building, identity formation, perhaps signposting to +resources.

  • +
  • This also links with building a welcoming/inclusive environment: for example, +imposter syndrome, which disproportionately affects under-represented groups +(link), +can manifest as low self-confidence –> building the confidence of +students in the classroom may lead to a more diverse community.

  • +
+
+
+
+
+

Tools for this workshop

+

We often start workshops with these:

+ +
+
+
+

Code of Conduct

+
    +
  • We follow The CodeRefinery Code of +Conduct.

  • +
  • This is a hands-on, interactive workshop.

    +
      +
    • Be kind to each other and help each other as best you can.

    • +
    • If you can’t help someone or there is some problem, let someone know.

    • +
    • If you notice something that prevents you from learning as well as you can, let us know and don’t suffer silently.

    • +
    +
  • +
  • It’s also about the little things:

    +
      +
    • volume

    • +
    • font size

    • +
    • generally confusing instructor

    • +
    • not enough breaks

    • +
    +
  • +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/why-are-computers-hard/index.html b/branch/ignore/why-are-computers-hard/index.html new file mode 100644 index 0000000..2154463 --- /dev/null +++ b/branch/ignore/why-are-computers-hard/index.html @@ -0,0 +1,237 @@ + + + + + + + Why are computers hard? — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Why are computers hard?

+

Most of the time, when teaching, our difficulty is not what you expect.

+
+

Initial reading

+

Read the following:

+ +

Of each of the points made, how many are related to:

+
    +
  • The computing itself

  • +
  • The user interface

  • +
  • The ability of the user to work in the computing environment

  • +
  • Something else

  • +
+
+
+

Usability

+

As said in the text above:

+
+

Most user interfaces are terrible. When people make mistakes it’s +usually the fault of the interface. You’ve forgotten how many ways +you’ve learned to adapt to bad interfaces. You’ve forgotten how +many things you once assumed that the interface would be able to +do for you.

+
+
+
+

Deep abstraction layers

+

Most technology is built on abstraction layers, for good reason. They +help simplify implementation and understanding.

+
+

Exercise

+

Think of a tool or technology that is easy to understand and use if +you understand the underlying abstraction layers, but is almost +impossible otherwise.

+
+
+
+

Conclusion: what are we teaching, then?

+

As teachers of computing, we fill a critical role that is more +determined by our audience, than the technology we are teaching.

+
+
+

See also

+

(none yet)

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/why-teach-together/index.html b/branch/ignore/why-teach-together/index.html new file mode 100644 index 0000000..408b6be --- /dev/null +++ b/branch/ignore/why-teach-together/index.html @@ -0,0 +1,270 @@ + + + + + + + Why teach together? — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Why teach together?

+

We usually say so much about the value of collaboration. Despite us +saying this, our teaching is still far too alone. Covid-19 gave us a +kick that reduced our barriers and led to lasting changes in how we +taught (eventually leading to this very course).

+

Open Science / FAIR data is heavily emphazised these days. But let’s +add a “C” to FAIR: “collaborative”. Instead of people doing their own +thing and releasing, develop, iterate, and maintain collaboratively.

+
+

Ways to teach together

+
    +
  • Develop materials together - avoid duplication.

  • +
  • Team teaching

  • +
  • Extensive use of helpers and team leaders.

  • +
  • HackMD for parallel and mass answers.

  • +
+
+
+

Advantages

+
    +
  • You need to teach anyway, less effort if you combine.

  • +
  • If done right, minimal extra effort for others to receive benefit (+ +you get publicity).

  • +
  • Many of the previously presented teaching strategies work best in +large courses - this makes the course more engaging than a small +event with minimal interaction.

  • +
  • More engaging for the audience.

  • +
  • Easier on-boarding of new instructors (less “scary” to teach a new course +with other instructors).

  • +
+
+
+

Challenges and disadvantages

+
    +
  • Coordination

    +
      +
    • Finding suitable partners with the same vision

    • +
    • Coordination efforts (if others don’t understand the vision).

    • +
    +
  • +
  • Materials

    +
      +
    • May not be perfectly tuned to your own audience

    • +
    • May not iterate as fast as you need

    • +
    +
  • +
  • Co-teaching

    +
      +
    • Difficulty in finding co-teachers

    • +
    • Required effort of syncing among staff

    • +
    • It might revert to independent teaching if you aren’t careful.

    • +
    +
  • +
  • HackMD

    +
      +
    • Can possibly overload both student and teacher.

    • +
    +
  • +
+
+
+

Exercises

+
+

What similarities do we have?

+

Using HackMD, make two lists:

+
    +
  • What courses do you think your local community would benefit +from, which you don’t currently have? +1 other people’s items +which are also relevant to you.

  • +
  • Which courses are you thinking of preparing for your local +community? +1 other people’s items which you would be +interested in helping out with.

  • +
+
+
+
+

See also

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/workshop-roles/index.html b/branch/ignore/workshop-roles/index.html new file mode 100644 index 0000000..1e5e2eb --- /dev/null +++ b/branch/ignore/workshop-roles/index.html @@ -0,0 +1,259 @@ + + + + + + + Workshop roles — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Workshop roles

+

Running massive workshops requires a lot of people. We have a variety +of roles with different levels of support.

+

As usual, roles are a plan, and a plans are made to be updated.

+
+

Primary articles

+ +
+
+

Summary

+

Lower levels mean “top level sometimes split into some of these +sub-roles”.

+
    +
  • Instructor coordinator: coordinates schedule and instructors

    +
      +
    • Instructor: Teaches along with a co-teacher.

    • +
    • Expert helper: Spare person, usually watching HackMD but also +rotates among breakout rooms. Often instructs some lessons.

    • +
    • Director: Manages the flow of the schedule during the +workshop, introduces each lesson, etc. (often the instructor +coordinator)

      +
        +
      • Broadcaster: Manages the livestreaming

        +
          +
        • Video editor: Edits and publishes videos the day of the +workshop.

        • +
        +
      • +
      +
    • +
    +
  • +
  • Registration coordinator: coordinates registration, helpers, and +breakout rooms.

    +
      +
    • Exercise leader coordinator: Onboards exercise leaders

    • +
    • Host: Manages the learner breakout rooms, learner questions, +etc. (often the registration coordinator)

    • +
    • Advertisement coordinator: Advertises and outreaches

    • +
    +
  • +
  • Under both registration coordinator and instructor coordinator

    +
      +
    • HackMD manager: always watches and formats HackMD and +publishes it same-day. “Eyes on the ground” via HackMD and chat +and quickly communicates important information to instructor and +registration coordinators.

    • +
    +
  • +
  • Learner: attends and learns

  • +
  • Exercise leader: serves as a guide to the team, receives small +amount of training before the workshop.

  • +
+
+
+

Exercises

+
+

How many people teach in your workshops?

+
    +
  • Using HackMD, make a histogram of how many (instructors + +organizers) you typically have in your workshops.

  • +
  • List some of the common roles you have used.

  • +
+
+
+
+

See also

+

(none yet)

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/ignore/workshops-online/index.html b/branch/ignore/workshops-online/index.html new file mode 100644 index 0000000..ba9792e --- /dev/null +++ b/branch/ignore/workshops-online/index.html @@ -0,0 +1,499 @@ + + + + + + + Running a workshop: online — Community teaching training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Workshop manuals

+

CodeRefinery maintains a number of workshop manuals +with most of the “primary” information. This episode condenses this +into a quick overview.

+
+
+

Running a workshop: online

+
+

Online teaching discussion

+
+

Discussion: Online vs in-person

+

In notes:

+
    +
  • Compare and contrast the benefits of online teaching with +in-person: {advantage, disadvantage} × {content, presentation}

  • +
  • How do you have to prepare differently?

  • +
  • What are your own experiences?

  • +
+
+
+
+

Case study: Mega-CodeRefinery and Finland HPC Kickstart

+
    +
  • Mega-CodeRefinery

    +
      +
    • Audience of around 90-100

    • +
    • “bring your own breakout room” (see below)

    • +
    • 3 days/week, 6 days total

    • +
    • Lessons as normal in CodeRefinery

    • +
    +
  • +
  • HPC Kickstart

    +
      +
    • 250 registered, ~180 max participants

    • +
    • Multi-university: local differences made this much harder to manage.

    • +
    • Breakout rooms not pre-planned.

    • +
    +
  • +
+

Mega-CodeRefinery worked very well, HPC kickstart didn’t - but not +because of the size.

+
+
+

General workshop arrangements

+ +
    +
  • Select a coordinator, recruit instructors (at least 3 is important), +find helpers

  • +
  • Find a good lecture room: +requirements

  • +
  • Set up workshop webpage using the [Github, template +repository](https://github.com/coderefinery/template-workshop-webpage]: +see +manuals

  • +
  • Advertising the workshop

  • +
  • Communication with registered participants

  • +
+
+
+

CodeRefinery online scaling strategy

+
    +
  • We started online workshops in 2020 March, for the obvious reasons.

  • +
  • First, we started with two “normal size” (20 people) practice +workshops

  • +
  • Then we did a 100 person workshop. It went well, but there is less +tolerance for problems.

  • +
+
+

Basic preparation

+
    +
  • You need more breaks are needed

  • +
  • People have a way of doing too many things and not focusing.

  • +
  • How to attend an online +workshop” +guide to prepare learners

  • +
+
+
+

Basic platform: Zoom

+
    +
  • Zoom (not the most ethical, but worked well and was available)

  • +
  • Zoom mechanics: instructions for +students.

    +
      +
    • Mostly things that are known

    • +
    • We don’t use Zoom interaction features much anymore +(faster/slower/etc), but breakout rooms and HackMD instead

    • +
    +
  • +
  • See also: Online training +manual +(which is getting a bit old compared to what is below).

  • +
+
+
+

Breakout rooms, bring your own team

+
    +
  • Breakout rooms are

    +
      +
    • Static: same people across whole workshop

    • +
    • Contain one helper per room (see below)

    • +
    +
  • +
  • Team registration: accept a “team” field when registering, people on the +same team are put together.

    +
      +
    • Gives motivations for learners to bring their colleagues and +learn together.

    • +
    • More than one person learning together greatly increases update

    • +
    +
  • +
  • You need a powerful enough registration system to assign rooms and +email them to people!

  • +
  • We ask people to name themselves “(N) Firstname Lastname” or “(N,H) +Firstname Lastname” for helpers. Then it is fast to assign them to +their designated breakout rooms.

  • +
  • See also: Breakout room +mechanics

  • +
+
+
+

Helper training

+
    +
  • Each breakout room has a helper

  • +
  • Helper should be a little bit familiar, but not expected to be able +to answer all questions.

  • +
  • Special, custom helper +training +since helpers make or break the workshop

  • +
  • Helper recruitment:

    +
      +
    • Our networks

    • +
    • Team registration: if a team registers with their own helper, then +they are guaranteed to get in together. “bring your own breakout +room”

    • +
    • Former learners, ask them to come back.

    • +
    +
  • +
  • Two helper trainings the week before the workshop.

  • +
+
+
+

Staff roles

+

To reduce stress on any one person, we clearly define the different +roles and try to avoid overlap. We actually have enough people for +all of these, so it works well.

+
    +
  • Workshop coordinator

    +
      +
    • Registration, etc.

    • +
    +
  • +
  • Zoom host

    +
      +
    • Handles registration, breakout rooms, recording, Zoom chat.

    • +
    +
  • +
  • HackMD helper

    +
      +
    • Dedicated to watching HackMD and answering questions quickly.

    • +
    • Host on manuals

    • +
    +
  • +
  • Expert helpers

    +
      +
    • “Spare hands” who rotate between breakout rooms and make sure +helpers are doing well.

    • +
    • Give feedback to instructor about how breakout rooms are going.

    • +
    • Take the place of missing helpers.

    • +
    • Easy way for any people with a bit of spare time to help out.

    • +
    • Expert helpers in workshop

    • +
    +
  • +
  • Instructors

    +
      +
    • Teach, they shouldn’t overlap with the above roles (but serve as +expert helpers other times).

    • +
    • Usually also improve the lesson a bit before teaching

    • +
    • General staff intro in manuals

    • +
    +
  • +
  • Workshop preparation meeting

    + +
  • +
+
+
+

HackMD

+
    +
  • We’ve been using it here

  • +
  • Chat doesn’t work wen large, written +document does.

  • +
  • HackMD can just about scale to ~100 person workshop. Recommend +learners keep it in view mode while not editing.

  • +
  • Voice questions are still allowed, but will be recorded. Staff +raise important questions from HackMD to the instructor immediately.

  • +
  • HackMD also allows communication when in breakout rooms.

  • +
  • You can get multiple answers, and answers can be improved over +time.

  • +
  • HackMD +mechanics +and HackMD +helpers.

  • +
+
+
+

Recording and streaming

+
    +
  • When you have 100 people, main room is quiet anyway: you don’t lose +much by recording.

    +
      +
    • Questions anonymously in HackMD, privacy loss is not so bad

    • +
    +
  • +
  • Breakout rooms are never recorded

  • +
  • Streaming

    +
      +
    • We streamed via Twitch: https://twitch.tv/coderefinery

    • +
    • We typically get 5-40 viewers.

    • +
    • Zoom can directly send the stream to Twitch: no extra software +needed.

    • +
    • Twitch archives videos for 14 days, which allows learners to get +an instant reply (we get hundreds of views in the next days).

    • +
    • So while possibly not useful for new people to learn, the instant +reply is very useful. Instructor can also work on problems in +main stream during breakout rooms, which learners can watch +later.

    • +
    • Streamers also have access to HackMD to ask questions.

    • +
    +
  • +
  • Certain tricks needed to keep learners from appearing in recording +or stream

    +
      +
    • “Spotlight video”, host does not go to gallery view, uses dual +monitor mode. We are still figuring this out.

    • +
    +
  • +
+
+
+

Installation time

+
    +
  • People have to be ready once we start, or else everything fails.

  • +
  • Two installation help times the week before.

  • +
  • Every email emphasizes that you have to be prepared, and “requires” +you to attend workshops (but really it’s only)

  • +
  • Installation instructions include steps to verify

  • +
  • Installation instructions also include video demonstrations of +installation and verification.

  • +
  • We haven’t had that many installation problems, but also we keep the +requirements simple.

  • +
  • Helper introduction is right before software install time, so +helpers can stay and help with install if they want.

  • +
  • Design to be easy to install and get set up.

  • +
+
+
+

Other notes

+
    +
  • Make breakout sessions as long as possible: 10 minutes is really too +short. 20 minutes is a good minimum time.

  • +
  • Be very clear about exercise expectations

  • +
  • Keep HackMD updated as a log.

  • +
  • Don’t combine breaks and breakout times.

  • +
  • The more people you have, the more diverse audience you have and the +more people overwhelmed and under whelmed.

  • +
+
+
+
+

Workshop collaborations

+

Why limit ourselves to CodeRefinery workshop? Why not use our network +and techniquess for more

+
    +
  • Case study: Python for Scientific +Computing

    +
      +
    • Started by Aalto

    • +
    • Announced to CodeRefinery, five more instructors from three +countries joined.

    • +
    • Rapid collaboration, taught course shortly later.

    • +
    • Announced to all institutions. Some places had physical rooms, +some were pure online

    • +
    • Also streamed

    • +
    • It was much more fun and less stressful to work together

    • +
    +
  • +
  • We want to continue this kind of collaboration in other workshops.

  • +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/instructor-training/00-preparation/index.html b/branch/instructor-training/00-preparation/index.html new file mode 100644 index 0000000..56ee49e --- /dev/null +++ b/branch/instructor-training/00-preparation/index.html @@ -0,0 +1,181 @@ + + + + + + + Pre-workshop preparation — CodeRefinery instructor training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Pre-workshop preparation

+
+

You don’t have to be a Carpentries instructor

+

Being a Carpentries instructor is not +required to attend CodeRefinery instructor training workshop.

+
+

Preparation before the workshop (takes ca. 1 hour)

+
    +
  • Complete our pre-workshop survey. Your responses will help us to customize the workshop appropriately.

  • +
  • Read this short paper The Science of Learning which provides a brief overview of some key evidence-based results in teaching. This paper is also used by The Carpentries for their Instructor Training workshops.

  • +
  • Watch at least two of recorded ca. 5-minute +lightning overview videos +introducing various +CodeRefinery lessons +to get an overview of what we teach in CodeRefinery and also to be +able to practice CodeRefinery teaching on day 2 of this course.

  • +
  • Watch at least two of recorded +“this is my training philosophy” videos +which we will +discuss in group discussions and which will form the basis for a group +exercise.

  • +
  • Please go through a CodeRefinery lesson and find one +topic/episode/aspect that you find interesting. During a group session you +will be asked to present a topic/episode/aspect of your choice for 5 +minutes and get constructive feedback.

  • +
+
+
+

Remark

+

Don’t worry if there are sections you do not understand. The main objective +is to have a baseline for our discussions, not to check your ability to teach +the lesson during the instructor training workshop.

+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/instructor-training/02-teaching-philosophies/index.html b/branch/instructor-training/02-teaching-philosophies/index.html new file mode 100644 index 0000000..6ff942e --- /dev/null +++ b/branch/instructor-training/02-teaching-philosophies/index.html @@ -0,0 +1,338 @@ + + + + + + + CodeRefinery teaching philosophies — CodeRefinery instructor training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CodeRefinery teaching philosophies

+
+

Ice-breaker in groups (20 minutes)

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also +Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+

Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops.

+

It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us.

+
+

Video recordings

+

Recently we have recorded some of the below as videos: +https://www.youtube.com/playlist?list=PLpLblYHCzJAAHF89P-GCjEXWC8CF-7nhX

+
+
+

Anne Fouilloux

+

I regularly teach Carpentries workshops so I try to apply what I have learnt to CodeRefinery workshops. However, I know our target audience is very much different and that I need to adapt my teaching style. I am still trying to find what works best in which situations and this is why I like so much CodeRefinery workshops. We usually have a wider range of skills and very mixed backgrounds so we usually have to be more careful with the pace and time given for exercises.

+

Some considerations:

+
    +
  • I spend quite a lot of time reading the CodeRefinery material and practising myself exercises. I particularly like to read the instructor notes just before teaching: they usually highlight important aspects both for preparing and teaching.

  • +
  • I usually do not show too much in advance the material as I think it prevents asking questions. If you have less competent practitioners in the classroom, they can easily copy-paste to avoid slowing down the entire classroom.

  • +
  • Ideally, I’d like to give several exercises so anyone can work at its own pace. I find it is important that everybody gets something different from the workshop.

  • +
  • I love breaks as it gives us an opportunity to discuss with attendees on their research topics. I am especially interested to understand what software they write and how they plan to use what they learn during our workshops.

  • +
+
+
+

Bjørn Lindi

+

My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this “BLOB” (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the “BLOB”, to be able to share it with others.

+

In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic.

+

When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson.

+

Tools that I find useful in preparing a lesson is concept maps and Learner Personas, though I have develop to few them.

+ +
+
+

Thor Wikfeldt

+

I never want to leave any learner behind and I really don’t like seeing confused, blank faces in the classroom. +At the same time I sometimes worry about some participants getting bored if a lesson is progressing slowly. +This is always a difficult compromise and something I struggle with!

+

I try to focus on making concepts intuitive, to “make sense” to the learners. Of course this is usually +based on how I learned the topic myself and how it makes sense to me.

+

I try to establish connections between topics: “this thing here is similar to what we saw in the previous +lesson where we learned about X…”.

+

Before mastering a lesson by teaching in many times I try to “follow the script”. After becoming very +familiar with a lesson I start to improvise more and react more dynamically to questions, e.g. by taking a +detour to explain a confusing topic more clearly.

+

What I think I do too often: copy-paste code/text from lesson material. This can leave learners behind - +typing out the code and describing it is slower, but more learning takes place. More advanced learners +will hopefully “be compensated” by interesting advanced exercises which follow.

+
+
+

Stefan Negru

+

A lesson is a conversation, it is useful if both the trainer and the trainee are engaged. +For that reason I try to have, most of the time, a conversation with the classroom and +after we finish parts of a lesson, step back and see how we might use what we learned.

+

That brings me to another point I follow throughout the lessons, answering questions like:

+
    +
  • How can we apply in practice what we just learned?

  • +
  • Do you see yourself (the trainee) using that in practice, why or why not?

  • +
+

Most of the times those seem like open-ended questions to the trainees that just learned +something new, so I try to find examples, most of the times from personal experience.

+

Last thing is that analogies are important when I teach, I try to find analogies in order +to simplify a convoluted part of a lesson.

+
+
+

Radovan Bast

+

My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos.

+

My goal for a lesson is to spark curiosity to try things after the lesson, +both for the novices (“This looks like a useful tool, I want to try using it +after the workshop.”) and the more experienced participants (“Aha - I did not +know you could do this. I wonder whether I can make it work with X.”). I like +to start lessons with a question because this makes participants look up from +their browsers.

+

Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise.

+

For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate +the answer.

+

I try to avoid jargon and “war stories” from the professional developers’ +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid “customer”, +“production”, also a lot of Agile jargon is hard to relate to.

+

Less and clear is better than more and unclear. Simple examples are better +than complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +“simply”, “just”, “easy”. If participants take home one or two points from +a lesson, that’s for me success.

+

I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don’t want to +be surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or +slide. This allows me to skip and distill the essence and not read bullet +point by bullet point.

+

I try to never deviate from the script and if I do, be very explicit about +it.

+

A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel.

+

I find it very helpful if there is somebody else in the room who helps me +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson but when doing that to +others, I am often worried of interrupting their flow and timing too much.

+

A mistake I often do is to type too fast and in my mind I force myself +to slow down.

+
+
+

Sabry Razick

+

My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case.

+
+
+

Juho Lehtonen

+

I’m gradually realising the different ways to get a hint whether the workshop +participants are still following or perhaps bored. I assume it’s communicating +with the class, with exercises and simply by asking now and then. I also try +to remember to observe how people look like (puzzled, bored) while I teach, not +so obvious for me.

+

I believe that learners communicating with each other, in addition to with +instructors and helpers, really helps them to understand things faster. (At least +it helps me). So I try to make sure that no one sits or works alone at the workshops.

+
+
+

Richard Darst

+

Like many people, I’ve often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I’ve realized long ago that my most important lessons weren’t +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I’ve realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds.

+

My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I’m often start at the +very basics, because this is what I see missing most often.

+

When teaching, I like lots of audience questions and don’t mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don’t have to know everything perfectly, just show how +you’d approach a problem.

+
+
+

João M. da Silva

+

I started giving technical trainings twenty years ago, and hence my perspective +is perhaps more inclined towards the development of hands-on abilities and +capability to solve problems, independently or in a team.

+

But the development of hands-on practical skills, requires some essential +knowledge about the domain and some willingness to try different approaches +in case one gets stuck. Some call this the “KSA approach” +(“Knowledge-Skills-Attitude). Hence, I +try to impart the essential knowledge (and where to find out more) at my +trainings. And to encourage and challenge students in order to make them +overcome their self-perceived limits (e.g. “I’m a Humanist, I can’t use +Python virtualenv”).

+

I’ve been trying to study more about the Cognitive aspects of learning over the years, +and I should find out the time to return to that. There’s very interesting +research in Problem Solving, with Learning being a important component in that domain.

+

Storytelling: humans are neurologically made for paying attention to good +stories, and that’s something that I try to put into account: to give +a lesson like it would be a relevant narrative for the students, one that they +could relate to and help them in their work

+

I like to draw and be creative with that, but have to pay attention to +my handwriting during my trainings. I reckon that Architectural diagrams +help students to understand the big picture, so I should invest more on +those when development training material. I would also like to start looking into +Concept Maps and Semantic Trees in training.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/instructor-training/03-teaching-style/index.html b/branch/instructor-training/03-teaching-style/index.html new file mode 100644 index 0000000..342b243 --- /dev/null +++ b/branch/instructor-training/03-teaching-style/index.html @@ -0,0 +1,469 @@ + + + + + + + Interactive teaching style — CodeRefinery instructor training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Interactive teaching style

+
+

What are the top issues new instructors face?

+ +
+
+
+

The Carpentries and CodeRefinery approaches to teaching

+

Here we will give you a very short overview of the Carpentries approach to teaching and highlight +parts that are most important for teaching CodeRefinery style lessons.

+

Most CodeRefinery instructors have completed the +Carpentry instructor training workshop, which +anyone can apply for

+
+

This material

+

This section is derived from the +Carpentries instructor training material. +We encourage you to further study this material later, and to sign up for a 2-day Carpentry +intructor training workshop.

+
+
+
+

Key principles

+

The “Carpentries” approach to teaching is based on:

+
    +
  • Applying research-based teaching principles, especially as they apply to the +Carpentries audience.

  • +
  • Understanding the importance of a respectful and inclusive classroom environment.

  • +
+
+

Carpentries teaching principles

+
    +
  • Learners need to practice what they are learning in real time and get feedback on what they +are doing. That is why the teaching approach relies on live coding.

  • +
  • Learners best learn in a respectful classroom environment, so the Carpentries use a +Code of Conduct.

  • +
  • Learners are encouraged to help each other during workshops as this improves their confidence +and reinforces concepts taught.

  • +
  • Carpentry instructors try to have learners do something that they think is useful in their +daily work within 15 minutes of starting each lesson.

  • +
+

What to Teach

+

In CodeRefinery, we follow The Carpentries teaching principles but in addition to live coding +we often use group discussions to put in context the concepts we are teaching.

+

Applying these teaching principles are not sufficient and in addition we need to be able to check +the effectiveness of our methods.

+
+
+
+
+

On the importance of feedback

+

Feedback is an essential part of effective learning. Feedback is bi-directional:

+
    +
  • To be effective, instructors need feedback on their learners’ progress. Learners can also check their progress and ask relevant questions to get clarification.

  • +
  • Instructors also need feedback on their teaching. For instance, this can help them to adapt the pace, add/skip optional exercises and improve their teaching.

  • +
+
+

Getting/giving feedback on learners’ progress

+

This feedback comes through what is called formative assessments (in contrast +to summative assessment).

+
+

Summative Assessment

+

Summative assessment is used +to judge whether a learner has reached an acceptable level of competence. +Usually at the end of a course +Learners either “pass” or “fail” a summative assessment. +One example is a driving exam, +which tells the rest of society whether someone can safely be allowed on the road. Most assessment done in university +courses is summative, and is used to assign course grades.

+
+
+

Formative assessment

+

Formative assessment takes place during teaching and learning. It sounds like +a fancy term, but it can be used to describe any interaction or activity +that provides feedback to both instructors and learners about learners’ level of understanding of the +material. For learners, this feedback can help focus their study efforts. For instructors, it allows them to refocus +their instruction to respond to challenges that learners are facing. +Used continuously

+
+

Learners don’t “pass” or “fail” formative assessments; they are simply a feedback mechanism. +For example, a music teacher might ask a learner to play a scale very slowly +in order to see whether they are breathing correctly, +and if not, what they should change.

+

Formative assessment is most useful when it happens frequently (we’ll talk about how frequently later) +and when the results are easily interpretable by the learner and instructor.

+

CodeRefinery uses different instruments to get feedback from learners:

+
    +
  • Surveys: we will discuss about CodeRefinery pre/post-surveys in the episode +Running a workshop: online.

  • +
  • Exercises: we have many exercises during CodeRefinery workshops and use polls too but not necessarily many multiple-choice questions. +This is something that we may change in the future but the initial reason was that we build on existing knowledge +(see below section on our target audience) and give recommendations for best software practices: +there is no unique solution and you would like our learners to choose the approach that is most suitable for them. +For the same reasons, we have many optional exercises to accommodate the different levels. +We would like everyone to get something useful out of the CodeRefinery workshops.

  • +
+
+
+

Getting/giving feedback on teaching

+

Teaching is a skill. One of the objective of the CodeRefinery Instructor training is to give you +the confidence in teaching CodeRefinery lessons. Later we will have group work where we will +practice teaching some lessons.

+

Before doing so, we will learn here to give feedback on teaching using the same +positive-vs-negative and content-vs-presentation rubric.

+
+

Give feedback on teaching (optional, 10 mn)

+

This exercise aims at learning to give feedback. It is optional as we have +similar exercises when practising teaching). +As a group, we will watch this video of teaching and +give feedback on two axes: positive vs. negative and content vs. presentation. Have each person in +the class add one point to a 2x2 grid on a whiteboard or in the shared notes (hackMD, etherpad, google doc) without duplicating any points. +For online instructor training event, use breakout room (4-5 persons per group) to facilitate discussion. Then each group reports to the shared notes. +You can use a rubric (used during The Carpentries teaching demos) to help you take notes. +What did other people see that you missed? What did they think that you strongly agree or disagree with?

+
+
+
+
+
+

Who are the learners

+

The first task in teaching is to figure out who your learners are. The Carpentries approach is +based on the work of researchers like Patricia Benner, +who applied the +Dreyfus model of skill acquisition +in her studies of +how nurses progress from novice to expert +(see also books by Benner). +This work indicates that through practice and formal instruction, learners acquire skills and advance +through distinct stages. In simplified form, the three stages of this model are:

+
+

Novices, competent practitioners and experts

+

Novice, Competent Practitioner, Expert

+
    +
  • Novice: someone who doesn’t know what they don’t know, i.e., +they don’t yet know what the key ideas in the domain are or how they relate. +One sign that someone is a novice is that their questions “aren’t even wrong”.

    +
      +
    • Example: A novice learner in a Carpentries workshop might never have heard of the bash +shell, and therefore may have no understanding of how it relates to their file system or +other programs on their computer.

    • +
    • Example HPC: A learner who has never executed a program on remote computer in headless mode

    • +
    • Example HPC: A learner who has no understanding about using a queue system and having a +hard time why a program can not be run directly after login in.

    • +
    +
  • +
  • Competent practitioner: someone who has enough understanding for everyday purposes. +They won’t know all the details of how something works and their understanding may not +be entirely accurate, but it is sufficient for completing normal tasks with normal +effort under normal circumstances.

    +
      +
    • Example: A competent practitioner in a Carpentries workshop might have used the shell +before and understand how to move around directories and use individual programs, but +they might not understand how they can fit these programs together to build scripts +and automate large tasks.

    • +
    • Example: A competent practitioner in a CodeRefinery workshop is someone that understands +the concepts of best software practices and its importance. He/she clearly sees the +benefits of applying best software practices but he/she does not fully know yet how and +what to use for their own projects.

    • +
    • Example HPC: Knows how to establish a connection to a cluster and have submitted jobs. +But may not know how to request optimal amount of resources in a job and how to setup +parallel jobs

    • +
    +
  • +
  • Expert: someone who can easily handle situations that are out of the ordinary.

    +
      +
    • Example: An expert in a Carpentries workshop may have experience writing and running shell +scripts and, when presented with a problem, immediately sees how these skills can be used +to solve the problem.

    • +
    • Example HPC: A learner who has a good understanding of the queue system, parallel processing +and understand how to interpret error reports when something goes wrong and knows how to +get help.

    • +
    +
  • +
+
+
+

Cognitive Development and Mental Models

+

Effective learning is facilitated by the creation of a well-founded mental model. A mental model +is a collection of concepts and facts, along with the relationships between those concepts, which +a person has about a topic. For example, a long-time resident of the United States may have an +advanced understanding of the location of US states, major cities and landmarks, weather patterns, +regional economies and demographic patterns, as well as the relationships among these, compared +with their understanding of these relationships for other countries. In other words, their mental +model of the United States is more complex compared with their mental model of other countries.

+

We can distinguish between a novice and a competent practitioner for a given domain based +on the complexity of their mental models.

+
    +
  • A novice is someone who has not yet built a mental model of the domain. +They therefore reason by analogy and guesswork, borrowing bits and pieces +of their mental models of other domains which seem superficially similar.

  • +
  • A competent practitioner is someone who has a mental model that’s good enough +for everyday purposes. This model does not have to be completely accurate in order +to be useful: for example, the average driver’s mental model of how a car works +probably doesn’t include most of the complexities that a mechanical engineer +would be concerned with.

  • +
+

We could expect a mixture of learners from novice and competent practitioner groups +in HPC training events.

+

Mental Models

+
+
+
+

How “knowledge” gets in the way

+

Mental models are hardly ever built from scratch. Every learner comes to a topic with +some amount of information, ideas and opinions about the topic. This is true even in +the case where a learner can’t articulate their prior knowledge and beliefs.

+

In many cases, this prior knowledge is incomplete or inaccurate. Inaccurate beliefs +can be termed “misconceptions” and can impede learning by making it more difficult for +learners to incorporate new, correct information into their mental models. +Correcting learners’ misconceptions is at least as important as presenting them with +correct information. Broadly speaking, misconceptions fall into three categories:

+
    +
  • Simple factual errors, such as believing that Vancouver is the capital of +British Columbia. These are the easiest to correct.

  • +
  • Broken models, such as believing that motion and acceleration must be in the +same direction. We can address these by having learners reason through examples to +see contradictions.

  • +
  • Fundamental beliefs, such as “the world is only a few thousand years old” or +“human beings cannot affect the planet’s climate”. These beliefs are deeply connected +to the learner’s social identity and are the hardest to change.

  • +
+

The current HPC carpentry workshop material are aimed at Novice of HPC

+

Among Novice learners there might be learners who are experts in their domain and very +competent in the program they are executing, but may not have used a HPC system before. +Then among the competent practitioners There might be learners who repeat some procedures +they have inherited but lack a in-depth understanding of what’s going on. That is why it is +important to get accurate feedback, before and during the workshops to understand the learner profiles.

+
+

Exercise: How to identify learner profiles?

+
    +
  1. How to identify leaner profiles from surveys and during the class

  2. +
  3. Which types of learners should the leassons focus on

  4. +
+
+
+
+
+
+

CodeRefinery Curriculum and Reverse Instructional Design (with recommendations for HPC carpentries)

+

When writing a CodeRefinery lesson, we take a “reverse” approach to instruction, +as described in Wiggins and McTighe’s +Understanding by Design, +that keeps the focus firmly on learning outcomes. The order of preparation in this case becomes

+
    +
  • Determine your learning objectives

  • +
  • Decide what constitutes evidence that objectives have been met, and design assessments +to target that evidence

  • +
  • Design instruction: Sort assessments in order of increasing complexity, +and write content that connects everything together

  • +
+
+

Working with learning objectives

+

Each CodeRefinery lesson (also the HPC capentries lessons) usually has a learning objectives section. +Good learning objectives are quite specific about the intended effect of a lesson on its learners. +We aim to create learning objectives that are specific, accurate, and informative for +both learners and instructors.

+
+
+

Using Bloom’s Taxonomy to write effective learning objectives

+

Bloom’s Taxonomy is a framework for thinking about learning that breaks progress down into discrete, hierarchical steps. +While many ideas have come and gone in education, Bloom’s has remained a useful tool for educators, in particular because the +hierarchy seems to be reasonably valid: outcomes at the top of the hierarchy cannot be achieved without mastery of outcomes at +the bottom. In the long term, everybody wants to be at the top. However, in aiming to meet learners where they are, we also +need to be mindful about helping them to “grow a level,” helping them to recognize when they have achieved that growth, and +guiding them to look ahead to where we might not be able to take them.

+

Bloom's Taxonomy

+

Image credit: Vanderbilt University Center for Teaching

+
+
+

Revisiting Learning objectives

+

When using existing teaching material, reverse instructional design principles might be applied as +follows:

+
    +
  1. Review the lesson’s learning objectives carefully, thinking about how they will work for your audience

  2. +
  3. Scan the lesson to identify promising points to check in with your learners, using formative assessment to verify that objectives have been met

  4. +
  5. Review the connecting content in detail to be sure everything works and you have anticipated likely problems and questions.

  6. +
+

We strongly encourage you to read them before teaching a lesson and to review whether they still match the content of the lesson:

+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/instructor-training/_sources/00-preparation.md.txt b/branch/instructor-training/_sources/00-preparation.md.txt new file mode 100644 index 0000000..ebe5d58 --- /dev/null +++ b/branch/instructor-training/_sources/00-preparation.md.txt @@ -0,0 +1,50 @@ +--- +layout: episode +title: "Pre-workshop preparation" +teaching: 0 +exercises: 60 +questions: + - "What should I do before the CodeRefinery instructor training workshop?" + - "How long is the preparation work?" + - "Do I need to be Carpentries instructor to attend this workshop?" +--- + +# Pre-workshop preparation + + +## You don't have to be a [Carpentries instructor](https://carpentries.org/instructors/) + +Being a [Carpentries instructor](https://carpentries.org/instructors/) is not +required to attend CodeRefinery instructor training workshop. + +> ## Preparation before the workshop (takes ca. 1 hour) +> +> - Complete our pre-workshop survey. Your responses will help us to customize the workshop appropriately. +> +> - Read this short paper [The Science of Learning](https://carpentries.github.io/instructor-training/files/papers/science-of-learning-2015.pdf) which provides a brief overview of some key evidence-based results in teaching. This paper is also used by [The Carpentries](https://carpentries.org/) for their Instructor Training workshops. +> +> - Watch at least two of recorded ca. 5-minute +> [lightning overview videos](https://www.youtube.com/playlist?list=PLpLblYHCzJABvt25VY0wNIgbaQfTQaND7) +> introducing various +> [CodeRefinery lessons](https://coderefinery.org/lessons/) +> to get an overview of what we teach in CodeRefinery and also to be +> able to practice CodeRefinery teaching on day 2 of this course. +> +> - Watch at least two of recorded +> ["this is my training philosophy" videos](https://www.youtube.com/playlist?list=PLpLblYHCzJAAHF89P-GCjEXWC8CF-7nhX) +> which we will +> discuss in group discussions and which will form the basis for a group +> exercise. +> +> - Please go through a [CodeRefinery lesson](https://coderefinery.org/lessons/) and find one +> topic/episode/aspect that you find interesting. During a group session you +> will be asked to present a topic/episode/aspect of your choice for 5 +> minutes and get constructive feedback. +{: .prereq} + +> ## Remark +> +> Don't worry if there are sections you do not understand. The main objective +> is to have a baseline for our discussions, not to check your ability to teach +> the lesson during the instructor training workshop. +{: .callout} diff --git a/branch/instructor-training/_sources/02-teaching-philosophies.md.txt b/branch/instructor-training/_sources/02-teaching-philosophies.md.txt new file mode 100644 index 0000000..66bae95 --- /dev/null +++ b/branch/instructor-training/_sources/02-teaching-philosophies.md.txt @@ -0,0 +1,237 @@ +--- +layout: episode +title: "Our teaching philosophies" +teaching: 0 +exercises: 30 +questions: + - "What are our teaching philosophies?" +--- + +# CodeRefinery teaching philosophies + +> ## Ice-breaker in groups (20 minutes) +> +> - Share your approach to teaching and your teaching philosophy with your group. +> - Please share your tricks and solutions in the live document for others. +> +> Additional ice-breaker questions: +> - What is your motivation for taking this training? +> - How structured or informal are your own teaching needs? +> - What difference do you notice between the teaching what we (also +> Carpentries) do and traditional academic teaching? +> - What other skills need to be taught, but academic teaching isn't the right setting? +{: .challenge} + +--- + +Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops. + +It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us. + +> ## Video recordings +> +> Recently we have recorded some of the below as videos: +> +{: .prereq} + +> ## Anne Fouilloux +> +> I regularly teach Carpentries workshops so I try to apply what I have learnt to CodeRefinery workshops. However, I know our target audience is very much different and that I need to adapt my teaching style. I am still trying to find what works best in which situations and this is why I like so much CodeRefinery workshops. We usually have a wider range of skills and very mixed backgrounds so we usually have to be more careful with the pace and time given for exercises. +> +> Some considerations: +> - I spend quite a lot of time reading the CodeRefinery material and practising myself exercises. I particularly like to read the instructor notes just before teaching: they usually highlight important aspects both for preparing and teaching. +> - I usually do not show too much in advance the material as I think it prevents asking questions. If you have less competent practitioners in the classroom, they can easily copy-paste to avoid slowing down the entire classroom. +> - Ideally, I'd like to give several exercises so anyone can work at its own pace. I find it is important that everybody gets something different from the workshop. +> - I love breaks as it gives us an opportunity to discuss with attendees on their research topics. I am especially interested to understand what software they write and how they plan to use what they learn during our workshops. +{: .challenge} + +> ## Bjørn Lindi +> +> My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this "BLOB" (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the "BLOB", to be able to share it with others. +> +>In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic. +> +>When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson. +> +>Tools that I find useful in preparing a lesson is concept maps and Learner Personas, though I have develop to few them. +>- [Concept Maps](https://teachtogether.tech/#s:memory-concept-maps) +>- [Learner Personas](https://teachtogether.tech/#s:process-personas) +{: .challenge} + +> ## Thor Wikfeldt +> +> I never want to leave any learner behind and I really don't like seeing confused, blank faces in the classroom. +> At the same time I sometimes worry about some participants getting bored if a lesson is progressing slowly. +> This is always a difficult compromise and something I struggle with! +> +> I try to focus on making concepts intuitive, to "make sense" to the learners. Of course this is usually +> based on how I learned the topic myself and how it makes sense to me. +> +> I try to establish connections between topics: "this thing here is similar to what we saw in the previous +> lesson where we learned about X...". +> +> Before mastering a lesson by teaching in many times I try to "follow the script". After becoming very +> familiar with a lesson I start to improvise more and react more dynamically to questions, e.g. by taking a +> detour to explain a confusing topic more clearly. +> +> What I think I do too often: copy-paste code/text from lesson material. This can leave learners behind - +> typing out the code and describing it is slower, but more learning takes place. More advanced learners +> will hopefully "be compensated" by interesting advanced exercises which follow. +{: .challenge} + +> ## Stefan Negru +> +> A lesson is a conversation, it is useful if both the trainer and the trainee are engaged. +> For that reason I try to have, most of the time, a conversation with the classroom and +> after we finish parts of a lesson, step back and see how we might use what we learned. +> +> That brings me to another point I follow throughout the lessons, answering questions like: +> * How can we apply in practice what we just learned? +> * Do you see yourself (the trainee) using that in practice, why or why not? +> +> Most of the times those seem like open-ended questions to the trainees that just learned +> something new, so I try to find examples, most of the times from personal experience. +> +> Last thing is that analogies are important when I teach, I try to find analogies in order +> to simplify a convoluted part of a lesson. +{: .challenge} + +> ## Radovan Bast +> +> My teaching changed by 180 degrees after taking the Carpentries instructor +> training. Before that I used slides, 45 minute lecture blocks, and separate +> exercise sessions. After the Carpentries instructor training I embraced the +> interaction, exercises, demos, and typos. +> +> My goal for a lesson is to spark curiosity to try things after the lesson, +> both for the novices ("This looks like a useful tool, I want to try using it +> after the workshop.") and the more experienced participants ("Aha - I did not +> know you could do this. I wonder whether I can make it work with X."). I like +> to start lessons with a question because this makes participants look up from +> their browsers. +> +> Keeping both the novices and the experts engaged during a lesson can be +> difficult and offering additional exercises seems to be a good compromise. +> +> For me it is a good sign if there are many questions. I like to encourage +> questions by asking questions to the participants. But I also try not to go +> into a rabbit hole when I get a question where only experts will appreciate +> the answer. +> +> I try to avoid jargon and "war stories" from the professional developers' +> perspective or the business world. Most researchers may not relate to them. +> For examples I always try to use the research context. Avoid "customer", +> "production", also a lot of Agile jargon is hard to relate to. +> +> Less and clear is better than more and unclear. Simple examples are better +> than complicated examples. Almost never I have felt or got the feedback that +> something was too simple. I am repeating in my head to not use the words +> "simply", "just", "easy". If participants take home one or two points from +> a lesson, that's for me success. +> +> I prepare for the lesson by reading the instructor guide and all issues and +> open pull requests. I might not be able to solve issues, but I don't want to +> be surprised by known issues. I learn the material to a point where I know +> precisely what comes next and am never surprised by the next episode or +> slide. This allows me to skip and distill the essence and not read bullet +> point by bullet point. +> +> I try to never deviate from the script and if I do, be very explicit about +> it. +> +> A great exercise I can recommend is to watch a tutorial on a new programming +> language/tool you have never used. It can feel very overwhelming and fast to +> get all these new concepts and tools thrown at self. This can prepare me for +> how a participant might feel. +> +> I find it very helpful if there is somebody else in the room who helps me +> detecting when I go too fast or become too confusing. I like when two +> instructors complement each other during a lesson but when doing that to +> others, I am often worried of interrupting their flow and timing too much. +> +> A mistake I often do is to type too fast and in my mind I force myself +> to slow down. +{: .challenge} + +> ## Sabry Razick +> My approach is to show it is fun to demystify concepts. Once a concept is +> not a mystery anymore, the learners will understand is what it means, where +> it is coming from, why it is in place and what it could it offer for their future. +> I try to relate concepts to real life with a twist of humour whenever possible if +> the outcome is certain not be offensive to any one. I use diagrams whenever possible, +> I have spent weeks creating diagrams that is sometime three or four sentences. That +> effort I consider worthwhile as my intention is not to teach, but to demystify. +> Once that is achieved, learners will learn the nitty gritty on their own easily +> and with confidence, when they have the use-case. +> +> +{: .challenge} + +> ## Juho Lehtonen +> I'm gradually realising the different ways to get a hint whether the workshop +> participants are still following or perhaps bored. I assume it's communicating +> with the class, with exercises and simply by asking now and then. I also try +> to remember to observe how people look like (puzzled, bored) while I teach, not +> so obvious for me. +> +> I believe that learners communicating with each other, in addition to with +> instructors and helpers, really helps them to understand things faster. (At least +> it helps me). So I try to make sure that no one sits or works alone at the workshops. +{: .challenge} + +> ## Richard Darst +> +> Like many people, I've often been teaching, but rarely a teacher. I +> tend to teach like I am doing an informal mentorship. +> I've realized long ago that my most important lessons weren't +> learned in classes, but by a combination of seeing things done by +> friends and independent study after that. I've realized that +> teaching (the things I teach) is trying to correct these differences +> in backgrounds. +> +> My main job is supporting computing infrastructure, so my teaching +> is very grounded in real-world problems. I'm often start at the +> very basics, because this is what I see missing most often. +> +> When teaching, I like lots of audience questions and don't mind +> going off-script a bit (even though I know it should be minimized). +> I find that sufficient audience interest allows any lesson to be a +> success - you don't have to know everything perfectly, just show how +> you'd approach a problem. +> +{: .challenge} + +> ## João M. da Silva +> +> I started giving technical trainings twenty years ago, and hence my perspective +> is perhaps more inclined towards the development of hands-on abilities and +> capability to solve problems, independently or in a team. +> +> But the development of hands-on practical skills, requires some essential +> knowledge about the domain and some willingness to try different approaches +> in case one gets stuck. Some call this the "KSA approach" +> ("Knowledge-Skills-Attitude). Hence, I +> try to impart the essential knowledge (and where to find out more) at my +> trainings. And to encourage and challenge students in order to make them +> overcome their self-perceived limits (e.g. "I'm a Humanist, I can't use +> Python virtualenv"). +> +> I've been trying to study more about the Cognitive aspects of learning over the years, +> and I should find out the time to return to that. There's very interesting +> research in Problem Solving, with Learning being a important component in that domain. +> +> Storytelling: humans are neurologically made for paying attention to good +> stories, and that's something that I try to put into account: to give +> a lesson like it would be a relevant narrative for the students, one that they +> could relate to and help them in their work +> +> I like to draw and be creative with that, but have to pay attention to +> my handwriting during my trainings. I reckon that Architectural diagrams +> help students to understand the big picture, so I should invest more on +> those when development training material. I would also like to start looking into +> Concept Maps and Semantic Trees in training. +{: .challenge} diff --git a/branch/instructor-training/_sources/03-teaching-style.md.txt b/branch/instructor-training/_sources/03-teaching-style.md.txt new file mode 100644 index 0000000..8164130 --- /dev/null +++ b/branch/instructor-training/_sources/03-teaching-style.md.txt @@ -0,0 +1,336 @@ +--- +layout: episode +title: "Carpentries and CodeRefinery approach to teaching" +teaching: 30 +exercises: 30 +questions: + - "What pedagogical concepts underpin CodeRefinery and Carpentry workshops?" + - "How to get and give feedback?" + - "Who are the CodeRefinery learners?" + - "Why is it important to define learning objectives?" +objectives: + - "Explain The Carpentries and CodeRefinery approaches to teaching" + - "Understand what is meant by feedback, cognitive development, mental models and reverse instructional design" + - "Explain and practice important pedagogical concepts" +keypoints: + - "CodeRefinery lessons and teaching build on these principles" +--- +# Interactive teaching style + + +## What are the top issues new instructors face? + +```{solution} + - Breaks are not negotiable, minimum 10 minutes. + - Breakout sessions too short. Make them as long as possible, don't expect to come back for + new intro, then go back. + - Get the speed correct. Not too fast and not too slow. + - People will accomplish less than you expect. Expect learners to be 5 times slower than you, at best! + - All the other tools and stuff will go wrong. Try to not bring in a dependency when you don't need it. + - Trying to accomplish too much: it's OK to cut out and adapt to the audience. + Have a reserve session at the end you prepare, but are ready to skip. + - Explaining how, but not why. + - Running out of time to making your environment match the learner's. + - Running out of time to set up good screen sharing practices + - (terminal history, portion of screen, remote history) in advance. + - Assuming learners remember what they have already learned, or know the prerequisites. Or have stuff installed and configured. + - Not managing expectations: learners think that you will accomplish everything, and feel sad when you don't. + - Special issues when lessons delivered online (discussed during Workshop preparation and organization) +``` + + +# The Carpentries and CodeRefinery approaches to teaching + +Here we will give you a very short overview of the Carpentries approach to teaching and highlight +parts that are most important for teaching CodeRefinery style lessons. + +Most CodeRefinery instructors have completed the +[Carpentry instructor training workshop](https://carpentries.github.io/instructor-training/), which +[anyone can apply for](https://carpentries.org/become-instructor/) + +> ## This material +> +> This section is derived from the +> [Carpentries instructor training material](https://carpentries.github.io/instructor-training/). +> We encourage you to further study this material later, and to sign up for a 2-day Carpentry +> intructor training workshop. +{: .callout} + +--- + +## Key principles + +The "Carpentries" approach to teaching is based on: + +- Applying research-based teaching principles, especially as they apply to the + Carpentries audience. +- Understanding the importance of a respectful and inclusive classroom environment. + + +### Carpentries teaching principles + +- Learners need to practice what they are learning in real time and get **feedback** on what they + are doing. That is why the teaching approach relies on **live coding**. +- Learners best learn in a respectful classroom environment, so the Carpentries use a + [Code of Conduct](https://docs.carpentries.org/topic_folders/policies/code-of-conduct.html). +- Learners are encouraged to help each other during workshops as this improves their confidence + and reinforces concepts taught. +- Carpentry instructors try to have learners do something that they think is useful in their + daily work within **15 minutes of starting each lesson**. + +![What to Teach](https://carpentries.github.io/instructor-training/fig/what-to-teach.png) + +In CodeRefinery, we follow The Carpentries teaching principles but in addition to **live coding** +we often use **group discussions** to put in context the concepts we are teaching. + +Applying these teaching principles are not sufficient and in addition we need to be able to check +the effectiveness of our methods. + +--- + +## On the importance of feedback + +Feedback is an essential part of effective learning. Feedback is bi-directional: +- To be effective, instructors need feedback on their learners' progress. Learners can also check their progress and ask relevant questions to get clarification. +- Instructors also need feedback on their teaching. For instance, this can help them to adapt the pace, add/skip optional exercises and improve their teaching. + +### Getting/giving feedback on learners' progress + +This feedback comes through what is called *formative assessments* (in contrast + to *summative assessment*). + +> ## Summative Assessment +> *Summative assessment* is used +> to judge whether a learner has reached an acceptable level of competence. +> Usually at the end of a course +> Learners either "pass" or "fail" a summative assessment. +> One example is a driving exam, +> which tells the rest of society whether someone can safely be allowed on the road. Most assessment done in university +> courses is summative, and is used to assign course grades. +{: .callout} + +> ## Formative assessment +> *Formative assessment* takes place during teaching and learning. It sounds like +> a fancy term, but it can be used to describe any interaction or activity +> that provides feedback to both instructors and learners about learners' level of understanding of the +> material. For learners, this feedback can help focus their study efforts. For instructors, it allows them to refocus +> their instruction to respond to challenges that learners are facing. +> Used continuously +{: .callout} + +Learners don't "pass" or "fail" formative assessments; they are simply a feedback mechanism. +For example, a music teacher might ask a learner to play a scale very slowly +in order to see whether they are breathing correctly, +and if not, what they should change. + +Formative assessment is most useful when it happens frequently (we'll talk about how frequently later) +and when the results are easily interpretable by the learner and instructor. + + +CodeRefinery uses different instruments to get feedback from learners: + +- Surveys: we will discuss about CodeRefinery pre/post-surveys in the episode + {doc}`workshops-online`. +- Exercises: we have many exercises during CodeRefinery workshops and use polls too but not necessarily many multiple-choice questions. + This is something that we may change in the future but the initial reason was that we build on existing knowledge + (see below section on our target audience) and give recommendations for best software practices: + there is no unique solution and you would like our learners to choose the approach that is most suitable for them. + For the same reasons, we have many optional exercises to accommodate the different levels. + We would like everyone to get something useful out of the CodeRefinery workshops. + +### Getting/giving feedback on teaching + +Teaching is a skill. One of the objective of the CodeRefinery Instructor training is to give you +the confidence in teaching CodeRefinery lessons. Later we will have group work where we will +practice teaching some lessons. + +Before doing so, we will learn here to give feedback on teaching using the same +positive-vs-negative and content-vs-presentation rubric. + +> ## Give feedback on teaching (optional, 10 mn) +> This exercise aims at learning to give feedback. It is optional as we have +> similar exercises when {doc}`practising teaching `). +> As a group, we will watch [this video of teaching](https://www.youtube.com/watch?v=-ApVt04rB4U) and +> give feedback on two axes: positive vs. negative and content vs. presentation. Have each person in +> the class add one point to a 2x2 grid on a whiteboard or in the shared notes (hackMD, etherpad, google doc) without duplicating any points. +> For online instructor training event, use breakout room (4-5 persons per group) to facilitate discussion. Then each group reports to the shared notes. +> You can use a [rubric](http://carpentries.github.io/instructor-training/demos_rubric/) (used during The Carpentries teaching demos) to help you take notes. +> What did other people see that you missed? What did they think that you strongly agree or disagree with? +> +{: .challenge} + +--- + +## Who are the learners + +The first task in teaching is to figure out who your learners are. The Carpentries approach is +based on the work of researchers like [Patricia Benner](https://en.wikipedia.org/wiki/Patricia_Benner), +who applied the +[Dreyfus model of skill acquisition](https://en.wikipedia.org/wiki/Dreyfus_model_of_skill_acquisition) +in her studies of +[how nurses progress from novice to expert](http://journals.sagepub.com/doi/10.1177/0270467604265061) +([see also books by Benner](https://www.worldcat.org/search?q=au%3ABenner%2C+Patricia+E.&qt=hot_author)). +This work indicates that through practice and formal instruction, learners acquire skills and advance +through distinct stages. In simplified form, the three stages of this model are: + +### Novices, competent practitioners and experts + +![Novice, Competent Practitioner, Expert](https://carpentries.github.io/instructor-training/fig/skill-level.svg) + +* *Novice*: someone who doesn't know what they don't know, i.e., + they don't yet know what the key ideas in the domain are or how they relate. + One sign that someone is a novice is that their questions "aren't even wrong". + + - Example: A *novice* learner in a Carpentries workshop might never have heard of the bash + shell, and therefore may have no understanding of how it relates to their file system or + other programs on their computer. + + - Example HPC: A learner who has never executed a program on remote computer in headless mode + + - Example HPC: A learner who has no understanding about using a queue system and having a + hard time why a program can not be run directly after login in. + +* *Competent practitioner*: someone who has enough understanding for everyday purposes. + They won't know all the details of how something works and their understanding may not + be entirely accurate, but it is sufficient for completing normal tasks with normal + effort under normal circumstances. + + - Example: A *competent practitioner* in a Carpentries workshop might have used the shell + before and understand how to move around directories and use individual programs, but + they might not understand how they can fit these programs together to build scripts + and automate large tasks. + + - Example: A *competent practitioner* in a CodeRefinery workshop is someone that understands + the concepts of best software practices and its importance. He/she clearly sees the + benefits of applying best software practices but he/she does not fully know yet how and + what to use for their own projects. + + - Example HPC: Knows how to establish a connection to a cluster and have submitted jobs. + But may not know how to request optimal amount of resources in a job and how to setup + parallel jobs + + +* *Expert*: someone who can easily handle situations that are out of the ordinary. + + - Example: An *expert* in a Carpentries workshop may have experience writing and running shell + scripts and, when presented with a problem, immediately sees how these skills can be used + to solve the problem. + + - Example HPC: A learner who has a good understanding of the queue system, parallel processing + and understand how to interpret error reports when something goes wrong and knows how to + get help. + + +### Cognitive Development and Mental Models + +Effective learning is facilitated by the creation of a well-founded mental model. A mental model +is a collection of concepts and facts, along with the relationships between those concepts, which +a person has about a topic. For example, a long-time resident of the United States may have an +advanced understanding of the location of US states, major cities and landmarks, weather patterns, +regional economies and demographic patterns, as well as the relationships among these, compared +with their understanding of these relationships for other countries. In other words, their mental +model of the United States is more complex compared with their mental model of other countries. + +We can distinguish between a *novice* and a *competent practitioner* for a given domain based +on the complexity of their mental models. + +* A *novice* is someone who has not yet built a mental model of the domain. + They therefore reason by analogy and guesswork, borrowing bits and pieces + of their mental models of other domains which seem superficially similar. +* A *competent practitioner* is someone who has a mental model that's good enough + for everyday purposes. This model does not have to be completely accurate in order + to be useful: for example, the average driver's mental model of how a car works + probably doesn't include most of the complexities that a mechanical engineer + would be concerned with. + +We could expect a mixture of learners from *novice* and *competent practitioner* groups +in HPC training events. + +![Mental Models](https://carpentries.github.io/instructor-training/fig/mental_models.svg) + +--- + +### How “knowledge” gets in the way + +Mental models are hardly ever built from scratch. Every learner comes to a topic with +some amount of information, ideas and opinions about the topic. This is true even in +the case where a learner can’t articulate their prior knowledge and beliefs. + +In many cases, this prior knowledge is incomplete or inaccurate. Inaccurate beliefs +can be termed “misconceptions” and can impede learning by making it more difficult for +learners to incorporate new, correct information into their mental models. +Correcting learners’ misconceptions is at least as important as presenting them with +correct information. Broadly speaking, misconceptions fall into three categories: + +- **Simple factual errors**, such as believing that Vancouver is the capital of + British Columbia. These are the easiest to correct. +- **Broken models**, such as believing that motion and acceleration must be in the + same direction. We can address these by having learners reason through examples to + see contradictions. +- **Fundamental beliefs**, such as “the world is only a few thousand years old” or + “human beings cannot affect the planet’s climate”. These beliefs are deeply connected + to the learner’s social identity and are the hardest to change. + + +The current HPC carpentry workshop material are aimed at **Novice** of HPC + +Among *Novice* learners there might be learners who are experts in their domain and very +competent in the program they are executing, but may not have used a HPC system before. +Then among the **competent practitioners** There might be learners who repeat some procedures +they have inherited but lack a in-depth understanding of what's going on. That is why it is +important to get accurate feedback, before and during the workshops to understand the learner profiles. + + +> ## Exercise: How to identify learner profiles? +> +> 1. How to identify leaner profiles from surveys and during the class +> 2. Which types of learners should the leassons focus on +{: .challenge} + +--- + +## CodeRefinery Curriculum and Reverse Instructional Design (with recommendations for HPC carpentries) + +When writing a CodeRefinery lesson, we take a “reverse” approach to instruction, +as described in Wiggins and McTighe’s +[Understanding by Design](http://www.worldcat.org/title/understanding-by-design/oclc/56491025), +that keeps the focus firmly on learning outcomes. The order of preparation in this case becomes + +- Determine your learning objectives +- Decide what constitutes evidence that objectives have been met, and design assessments + to target that evidence +- Design instruction: Sort assessments in order of increasing complexity, + and write content that connects everything together + +### Working with learning objectives + +Each CodeRefinery lesson (also the HPC capentries lessons) usually has a *learning objectives* section. +Good learning objectives are quite specific about the intended effect of a lesson on its learners. +We aim to create learning objectives that are specific, accurate, and informative for +both learners and instructors. + + +### Using Bloom's Taxonomy to write effective learning objectives + +[Bloom's Taxonomy](https://cft.vanderbilt.edu/guides-sub-pages/blooms-taxonomy/) is a framework for thinking about learning that breaks progress down into discrete, hierarchical steps. +While many ideas have come and gone in education, Bloom's has remained a useful tool for educators, in particular because the +hierarchy seems to be reasonably valid: outcomes at the top of the hierarchy cannot be achieved without mastery of outcomes at +the bottom. In the long term, everybody wants to be at the top. However, in aiming to meet learners where they are, we also +need to be mindful about helping them to ["grow a level,"](https://software-carpentry.org/blog/2018/03/tractenberg-summary.html) helping them to recognize when they have achieved that growth, and +guiding them to look ahead to where we might not be able to take them. + +![Bloom's Taxonomy](https://carpentries.github.io/instructor-training/fig/Blooms.png) + +Image credit: Vanderbilt University Center for Teaching + +### Revisiting Learning objectives + +When using existing teaching material, *reverse instructional design* principles might be applied as +follows: + +1. Review the lesson's learning objectives carefully, thinking about how they will work for your audience +2. Scan the lesson to identify promising points to check in with your learners, using formative assessment to verify that objectives have been met +3. Review the connecting content in detail to be sure everything works and you have anticipated likely problems and questions. + + +We strongly encourage you to read them before teaching a lesson and to review whether they still match the content of the lesson: diff --git a/branch/instructor-training/_sources/about-coderefinery.md.txt b/branch/instructor-training/_sources/about-coderefinery.md.txt new file mode 100644 index 0000000..1c9ba2c --- /dev/null +++ b/branch/instructor-training/_sources/about-coderefinery.md.txt @@ -0,0 +1,112 @@ +# About the CodeRefinery project + +CodeRefinery is a +[Nordic e-Infrastructure Collaboration (NeIC)](https://neic.no/) +project that has started in October 2016 and is +funded until October 2021. + +We hope to keep this project active beyond 2021 by forming a support network +and building a community of instructors and contributors. + +--- + +> ## History +> +> The CodeRefinery project idea grew out of two [SeSE](http://sese.nu) courses given at KTH Stockholm in 2014 and 2016: +> - [http://sese.nu/scientific-software-development-toolbox/](http://sese.nu/scientific-software-development-toolbox/) +> - [http://sese.nu/scientific-software-development-toolbox-2016/](http://sese.nu/scientific-software-development-toolbox-2016/) +> +> The project proposal was submitted to NeIC in 2015, accepted in 2015, and started in 2016. +> +> We have started by porting own lessons to the Carpentries teaching style and +> format, and collaboratively and iteratively grew and improved the material to +> its present form. +{: .discussion} + +--- + +## Main goals + +- Develop and maintain **training material on software best practices** for researchers that already write code. Our material addresses all academic disciplines and tries to be as programming language-independent as possible. +- Provide a [code repository hosting service](https://coderefinery.org/repository/) that is open and free for all researchers based in universities and research institutes from Nordic countries. +- Provide **training opportunities** in the Nordics using Carpentries and CodeRefinery training materials. +- Articulate and implement the CodeRefinery **sustainability plan**. + +--- + +## Impact + +We collect feedback and survey results to measure our impact. + +3-6 months after attending a workshop, past participants are asked to complete a short post-workshop survey. +The survey questions aim to establish what impact CodeRefinery workshops have on how past participants develop +research software. + +post-workshop survey results + +- Overall quality of research software has improved: more reusable, modular, reproducible and documented. +- Collaboration on research software development has become easier +- Past participants share their new knowledge with colleagues +- Usage of several tools is improved, and new tools are adopted + +[Free-form answers](https://coderefinery.org/#what-do-our-participants-say-after-attending-a-workshop) +also suggest that workshops are having the intended effects on how people develop code. A common theme is: +> *I wish I had known this stuff already as a grad student 10+ years ago...* + +We would love to get suggestions on how we can better quantify our impact. This +would make it easier for us to convince institutions to partner with us and +also open up funding opportunities. + +--- + +## Carpentries membership + +Since November 2018, [NeIC](https://neic.no) is a [Platinum Partner](https://carpentries.org/members/) to [The Carpentries](https://carpentries.org/). + +The Carpentries is an international project that comprises Software Carpentry and Data Carpentry, communities of instructors, trainers, maintainers, helpers, +and supporters who share a mission to teach foundational computational and data science skills to researchers. +The Carpentries teach foundational coding and data science skills to researchers worldwide and as such are complementary to CodeRefinery. + +Within the membership the Nordic research community has access to: + +- 6 Carpentries workshops in the Nordics each year. The workshop fee is covered by the membership, only the instructor travel is on the host institution. +- 15 seats in the Carpentries instructor training each year. Carpentries train the trainer program aims at building partnerships with Research Software Engineers and researchers who are willing to lead skill transfer within their local communities in the Nordics. + +--- + +## Target audience + +### Carpentries audience + + +The Carpentries aims to teach computational **competence** to learners through an applied approach, avoiding the theoretical and general in favor of the practical and specific. + +**Learners do not need to have any prior experience in programming.** One major goal of a Carpentry workshop is to raise awareness on the tools researchers can learn/use to speed up their research. + +By showing learners how to solve specific problems with specific tools and providing hands-on practice, learners develops confidence for future learning. + +> ## Novices +> We often qualify Carpentry learners as **novices**: they do not know what they need to learn yet. A typical example is the usage of version control: the Carpentry `git` lesson aims to give a very high level conceptual overview of Git but it does not explain how it can be used in research projects. +{: .callout} + + +### CodeRefinery audience + +In that sense, CodeRefinery workshops differ from Carpentry workshops as we assume our audience already writes code and scripts and we aim at teaching them **best software practices**. + +Our learners usually do not have a good overview of **best software practices** but are aware of the need to learn them. Very often, they know the tools (Git, Jupyter, etc.) we are teaching but have difficulties to make the best use of them in their software development workflow. + +Whenever we can, we should direct learners that do not have sufficient coding experience to Carpentries workshops. + +> ## Competent practitioners +> We often qualify CodeRefinery learners as **competent practitioners** because they already have an understanding of their needs. +> *Novices* and *competent practitioners* will be more clearly defined in the {doc}`next section <03-teaching-style>`. +{: .callout} + +> ## Best software practices for whom? +> It can be useful to ask the question: *best software practices for whom*? +> CodeRefinery teaches *best software practices* derived from producing and +> shipping software. These practices are also very good for sharing software, +> though our audience will probably not need to embrace *all* aspects of +> software engineering. +{: .callout} diff --git a/branch/instructor-training/_sources/coderefinery-workshops.md.txt b/branch/instructor-training/_sources/coderefinery-workshops.md.txt new file mode 100644 index 0000000..4979f54 --- /dev/null +++ b/branch/instructor-training/_sources/coderefinery-workshops.md.txt @@ -0,0 +1,37 @@ +# Organize a CodeRefinery workshop + +You or us? +- Historically, most workshops are CodeRefinery workshops were + organized centrally with a local host. +- Now, we want to transition to locally-invited workshops, so we know + we have a audience and advertisement. +- In the future, we need to transition to "independently run". + +Anyone can organize a CodeRefinery workshop and teach the CodeRefinery lessons which are +licensed under [CC-BY](https://creativecommons.org/licenses/by/4.0/). +However, making it a successful workshop requires careful planning and preparation. Here we will go +through practical aspects of organizing a workshop. + +## Centrally organized workshops + +- CodeRefinery staff organize, we try to reach as many people as + possible. +- Workshops in our own institutions tend to be best-attended, going to + a new institution sometimes has low attendance. +- We started this way. + + +## Locally invited workshops + +- A local team requests CodeRefinery (usually with a known audience). +- There is usually pretty good attendance. +- CodeRefinery staff travels to site and teaches - at least with local + helpers, ideally with a local instructor. + +## Independently organized workshops + +- In the future, we want to encourage independently organized + workshops: a site can organize the workshops without needing to go + through the core team. +- We don't yet know exactly how this will work, but this instructor + training is part of it. diff --git a/branch/instructor-training/_sources/future.md.txt b/branch/instructor-training/_sources/future.md.txt new file mode 100644 index 0000000..4a52d12 --- /dev/null +++ b/branch/instructor-training/_sources/future.md.txt @@ -0,0 +1,69 @@ +# Future + +## Activities + +### What is CodeRefinery? +- Teaching tools and best practices for version control and reproducibility in modern research software development +- Over 30 workshops to almost 1000 participants +- Typical workshop: +- Lessons: +- Carpentries membership + +### This workshop +- Was it a useful format and useful content? Please give us feedback. +- Should we collaborate on HPC Carpentry workshops? +- Who will end up teaching HPC Carpentry? What do you need from us/somebody as support? + +### Nordic-RSE (research software engineers) +- [Nordic-RSE Get together online event, Nov 30 - Dec 2, 2020](https://nordic-rse.org/events/2020-online-get-together/) +- [Conference May 2021](https://nordic-rse.org/conference/) +- [Map](https://nordic-rse.org/map/) +- Bi-weekly meetings + +### Collaborative workshops +- Example: +- Ideas for more of this? + +--- + +## How to get involved in CodeRefinery + +There are many ways to get involved: + +- Become a workshop helper +- Become a CodeRefinery workshop instructor +- Become a Carpentries workshop instructor +- Contribute to teaching material: +- Create your own teaching material in our constellation of teaching. +- Reuse our material +- Become an institutional partner as a training hub +- Participate in our chat and shape the project and lessons with us: +- Start a study group + +--- + +## Biggest open problems + +- How to give helpers and contributors more credit and visibility +- How to promote/engage new members +- We don't know how we should be in relation with Carpentries +- What are we? Non-profit? Institution collaboration network? Selling services? +- Funding and sustainability (but we have ideas: collaboration network) +- Scalability and marketing question: How to reach more people? + ([Research Software Hour](https://researchsoftwarehour.github.io/), Twitch, streaming-only + workshops, recording, post-processing videos) + +--- + +## Certification for CodeRefinery instructors + +We will set up a more formal process soon but for now you would need to: + +- Attend an instructor training (this workshop). +- Contribute to a lesson, either via pull request, issue, discussion, or as a helper. +- Share a short teaching demo or teach a lesson at a CodeRefinery workshop where you will get some feedback on your teaching. +- Participate in a call with other instructors and helpers either preparing a workshop or during a workshop debrief session. + +There are many ways to learn how to teach well. We and carpentries provide one way and basic material, but we want to find a way for everyone to be a part of us. + +See also https://coderefinery.github.io/manuals/instructor-intro/#from-helper-to-more. diff --git a/branch/instructor-training/_sources/guide.rst.txt b/branch/instructor-training/_sources/guide.rst.txt new file mode 100644 index 0000000..bb15781 --- /dev/null +++ b/branch/instructor-training/_sources/guide.rst.txt @@ -0,0 +1,2 @@ +Instructor's guide +------------------ diff --git a/branch/instructor-training/_sources/index.rst.txt b/branch/instructor-training/_sources/index.rst.txt new file mode 100644 index 0000000..8e5f738 --- /dev/null +++ b/branch/instructor-training/_sources/index.rst.txt @@ -0,0 +1,130 @@ +CodeRefinery instructor training +================================ + +CodeRefinery instructor training is focused on helping competent practitioners +and experts teach their knowledge to others. It also serves a +kickstart to teaching CodeRefinery lessons, but we also have a +gradual pathway of learner → helper → advanced helper → instructor as +well. + + +.. prereq:: + + This course has no strict prerequisites, but + + * It is helpful if you have attended CodeRefinery or Carpentries + workshops, which teach in an interactive and hands-on way. + + * We assume you already have competence in the technical tools you + want to teach. Many of our concepts use examples from + CodeRefinery lessons, such as version control or other software + development tools. + + * While not a prerequisite for this course, version control (git) + is necessary to contribute to lessons development the way we show + here (but the lesson design concepts are applicable to other + styles, too). + + +.. csv-table:: + :widths: auto + :delim: ; + + 60 min ; :doc:`00-preparation` + 10 min ; :doc:`welcome` + 15 min ; :doc:`about-coderefinery` + 30 min ; :doc:`02-teaching-philosophies` + 20 min ; :doc:`03-teaching-style` + 25 min ; :doc:`workshops-online` + 20 min ; :doc:`lesson-design` + 30 min ; :doc:`lesson-development` + 30 min ; :doc:`teaching-strategies` + 100 min ; :doc:`teaching-practice` + 20 min ; :doc:`future` + 5 min ; :doc:`coderefinery-workshops` + + +.. toctree:: + :maxdepth: 1 + :caption: The lesson + + 00-preparation.md + welcome.md + about-coderefinery.md + 02-teaching-philosophies.md + 03-teaching-style.md + workshops-online.md + lesson-design.md + lesson-development.md + teaching-strategies + teaching-practice.md + future.md + coderefinery-workshops + + +.. toctree:: + :maxdepth: 1 + :caption: Reference + + quick-reference + guide + + +.. _learner-personas: + +Who is the course for? +---------------------- + +You are interested in teaching CodeRefinery lessons, and would like a +comprehensive kickstart to how CodeRefinery works either to join us, +or teach its lessons with us or independently. + +You are a technical specialist who is frustrated with the way you +currently try to teach others who need to use your software or +infrastructure. You can't spend too much time to become a +professional, but you know you need something more than what you've +been doing. Thus, you would like to adopt some of the best practices of +designing and teaching interactive, hands-on workshops. + +You've been teaching alone, but would like to join a collaboration +network for more co-teaching and to reduce the amount of duplication +of effort. + +You would like the most important practices from the Carpentries +instructor training/lesson design philosophy, but can not take the +time for the full Carpentries program. + + +About the course +---------------- + +This course gives an introduction to + +* Science and philosophy of teaching +* How to teach interactive, hands-on lessons +* How to design interactive, hands-on lessons +* How CodeRefinery runs workshops +* How CodeRefinery has scaled up and taken the best advantage of + online teaching +* CodeRefinery itself +* The CodeRefinery collaboration network (and related networks in the + Nordics) + + +See also +-------- + +* `CodeRefinery manuals `__ +* Our gradual pathway to instructor from the manuals: `helper intro + `__ and + `instructor intro + `__. +* `Carpentries instructor training + `__ - more + intensive, but focused only on teaching. +* `Carpentries curriculum development handbook + `__ +* `Teaching Tech Together `__, a book + about similar topics by someone involved in Carpentries. +* `Carpentries general organizational documentation + `__ diff --git a/branch/instructor-training/_sources/lesson-design.md.txt b/branch/instructor-training/_sources/lesson-design.md.txt new file mode 100644 index 0000000..a9f6ec7 --- /dev/null +++ b/branch/instructor-training/_sources/lesson-design.md.txt @@ -0,0 +1,183 @@ +# Lesson design + +```{prereq} Recommended reading +- CodeRefinery [lesson-design](https://coderefinery.github.io/manuals/lesson-design/) manual +- [The Carpentries Curriculum Development Handbook](https://cdh.carpentries.org) +- [Teaching Tech Together](http://teachtogether.tech/) +- Our [summary](https://coderefinery.github.io/manuals/teaching-tech-together/) of "Teaching Tech Together" +- [Ten quick tips for creating an effective lesson](https://doi.org/10.1371/journal.pcbi.1006915) +``` + +--- + +## How do you design? + +```{discussion} +Discuss either in groups or via collaborative document: +- How do you start when you design a new lesson/presentation? +- Has your approach changed over the years? If yes, how? +``` + +--- + +## Backwards lesson design + +### The approach + +- You don't think about how to do something and try to explain it. +- Avoid the typical approach *"I want to show a number of things which I think are cool about + tool X - how do I press these into 90 minutes?"* +- Instead, you start defining your target audience by answering to questions + such **What is the expected educational level of my audience?**, **Have they + been already exposed to the technologies I am planning to teach?**, **What + tools do they already use?**, **What are the main issues they are currently + experiencing?**. It is important to discuss these points with a group of + colleagues, preferably from diverse backgrounds and institutions to reduce + biases. Once you clarified your target audience, it is useful to create + **learner personas**; that will help you during the development process by + providing concrete examples of potential learners showing up at your + workshops. For each **learner personas**, try to think of what is **useful to + them**: *"What do they **need** to + [remember/understand/apply/analyze/evaluate/create](https://coderefinery.github.io/instructor-training/03-teaching-style/#using-bloom-s-taxonomy-to-write-effective-learning-objectives)?"*. + Asking and answering to these questions will allow you to define the + background knowledge (starting points) and goals (end points) of your + learners. Then, you create a sequence of exercises which test incrementally + progressing tasks and acquisition of the new skills (from starting to end + points). +- Then, you write the minimum amount + of material to teach the gap between exercises. + +### The process + +For the whole process, see [our +manual](https://coderefinery.github.io/manuals/lesson-design/#backwards-lesson-design) +(instructor discusses these points briefly). + + +### Why is it good to have a process?: + +- Having a semi-rigid design process can **save time** to start drafting. +- It allows collaborative development of teaching material. +- It will probably **increase quality and relevance** of lessons for learners. +- **We aren't perfect yet.** CodeRefinery is still striving to get + better at this, and we are more ad-hoc than you might think. + A number of our lessons have not been designed this way but we are now improving + these lessons with the backwards lesson design in mind. + + +### Designing exercises + + +The goal of exercises is twofold: +- instructors can assess the progress of learners. +- learners put in practice the skills that you have included in your skills list. + +When designing exercises, consider that some participants will get stuck +and may want to re-join at a later exercise. In other words it is nice +if exercises build up on each other but not at the cost that if participants +get stuck at exercise 2, they will not be able to do exercises 3 to N. + +--- + +## Practice backwards design + + +```{discussion} The goal here is to discuss and provide examples on backwards-design of a lesson. + +Let's take as an example the *[HPC Carpentry lesson](https://hpc-carpentry.github.io/hpc-intro/)* + +**Target audience** + - What is the expected educational level of my audience? + - A PhD student, postdoc or young researcher. + - Have they been already exposed to the technologies I am planning to teach? + - The word **HPC** is not new to them and they may have already used an HPC but are still not capable of giving a proper definition of HPC. In addition, we do not expect them to know much about parallelism and they cannot make any distinction between various available parallelism paradigms. + - What tools do they already use? + - serial codes, multi-threaded codes, data parallelism; usually out-of-the-box tools. + - they may have tried to "scale" their code (multiprocessing, threading, GPUs) with more or less success. + - What are the main issues they are currently experiencing? + - they cannot solve their problems either because they would like to run the same code but with many different datasets or because their problem is larger (more computations/memory). + - most of the time they know their codes can run on HPC (from the documentation) but never really had the opportunity to try it out. + - Very few will have their own codes where they may have tried different things to speed it up (threading, task parallelism) but have no clear strategy. + +**Learner persona** + - Sonya is a 1st year PhD student: she recently moved to Oslo and joined the + Computational and Systems Neuroscience group. She will be using the + [NEST](https://nest-simulator.readthedocs.io/), a simulator for spiking + neural network model. She used NEST during her master thesis but on her + small cluster: **she never used an HPC resource** and is really excited about it. + - Robert is a field ecologist who obtained his PhD 6 months ago. He is now + working on a new project with Climate scientists and as a consequence will + need to run global climate models. He is **not very familiar with command + line** even though he attended a Software Carpentry workshop and the idea to + use HPC is a bit terrifying. He knows that he will get support from his + team who has extensive experience with HPC but would like to become more + independent and be able to **run his own simulations** (rather than copying + existing cases). + - Jessica is a postdoc working on a project that investigates numerically the + complex dynamics arising at the tip of a fluid-driven rupture. Fluid + dynamics will be computed by a finite element method solving the + compressible Navier-Stokes equations on a moving mesh. She **uses a code she + has developed** during her PhD and that is based on existing libraries. She + has mostly ran it on a local desktop; her work during her PhD was very + limited due to the lack of computing resources and she is now very keen is + **moving to HPC**; she knows that it will requires some work, in particular to + parallelize her code. This HPC training will be her first experience with + HPC. + +**Learning outcomes** + - Understand the difference between HPCs and other local/remote machines + - Understand the notion of core, nodes, cluster, shared/distributed memory, etc. + - Understand the notion of login nodes. + - Understand the need for a scheduler and how to use it appropriately + - Understand why optimising I/O is important on HPC and how to best use HPC filesystems + - Understand the need to parallelize (or use existing parallel) codes and in which cases HPCs is a must (when communications is required) + - Understand how to get your code ready to use on HPC (access to libraries, installation of your own libraries/software, etc.) + - Understand that an HPC is an operational machine and is not meant for developing codes. + +**Exercises** + - Get basic information such the number of CPUs, memory from your laptop and try to do the same on a HPC. Discuss outcomes. + - Try to create files on the different filesystems on your HPC resource and access them. + - Create different types of job scripts, submit and check outputs. + - Make a concrete example to run a specific software on your HPC (something like GROMACS). +``` + +```{challenge} Demo +Before we let participants present to their groups, one of the instructors +presents a 5-minute segment and we practice together giving feedback. + +The section we demo should require screen sharing and be of some follow-along +task. + +If there is time, we present one demo on the day before, and one demo just +before the group exercise. +``` + +```{challenge} Exercise +Choose a simple lesson topic and apply backwards lesson design. You +won't get all the way through, but come up with a logical +progression of exercises. + +The section you pick should require **screen sharing** and be of some **follow-along +task** (preferably using a shell). + +Some suggestions: +- Regular expressions +- Making papers in LaTeX +- Making figures in your favorite programming language +- Linux shell basics +- Something non-technical, such as painting a room +- An instructor training for CodeRefinery +- Some aspect from an already existing lesson +- [Introduction to high-performance computing](https://hpc-carpentry.github.io/hpc-intro/) (or an episode therein) +- [Unix shell in a HPC context](https://hpc-carpentry.github.io/hpc-shell/) (or an episode therein) +- A lesson you always wanted to teach + +Exercise (30 minutes): +- Collect notes in a shared document. +- Start with learner personas and learning outcomes. +- Come up with a logical progression of exercises. + +Discussion (15 minutes): +- How does this approach compare to other lessons or courses you have designed? +- We read, compare, and discuss our notes. +``` diff --git a/branch/instructor-training/_sources/lesson-development.md.txt b/branch/instructor-training/_sources/lesson-development.md.txt new file mode 100644 index 0000000..5371312 --- /dev/null +++ b/branch/instructor-training/_sources/lesson-development.md.txt @@ -0,0 +1,95 @@ +# Collaborative lesson development + +This session focuses on **organizational** and **technical aspects** +of collaborative lesson development. + +```{discussion} +This session is about **collaborative** lesson development. What advantages do +you see in developing lessons collaboratively and sharing lessons (making +material accessible)? What difficulties are there? +``` + +--- + +## Lesson templates for static sites + +- [Jekyll](https://jekyllrb.com/)-based + - Example: [Introduction to version control with Git](https://coderefinery.github.io/git-intro/) + - [Lesson template](https://github.com/coderefinery/example-lesson) + - Common styling implemented as Git submodule: [jekyll-common](https://github.com/coderefinery/jekyll-common) + - Based on a past version of the [Carpentries lesson style](https://github.com/carpentries/styles/) + - A new Carpentries lesson template is in the works +- [Sphinx](ttps://www.sphinx-doc.org)-based + - Example: this lesson + - Starting point: [sphinx-lesson](https://github.com/coderefinery/sphinx-lesson) + - [Documentation](https://coderefinery.github.io/sphinx-lesson/) +- Templates can be freely re-used + +Why static sites? +- Decentralized (in terms of organization/namespace) +- Forkable +- Anybody can suggest changes + +--- + +## Creating new teaching material + +Creating new teaching material is a longer process, because you should +go through the whole +[backwards lesson design process](/lesson-design/) +and get extensive comments. +Still, don't feel afraid: nothing is perfect (or even good) +the first time. In fact, **it may be an advantage to share an imperfect +lesson with others early** to collect feedback and suggestions before the lesson +"solidifies" too much. Draft it and collect feedback. The result will probably +be better than working in isolation towards a "perfect" lesson. + +```{discussion} +How can we share unfinished work/ideas? +- Draft pull requests (GitHub) or WIP (work in progress) merge requests (GitLab). +- Open an issue and discuss your idea before implementing it. +``` + +--- + +## Contributing to existing lessons + +Our lessons are **collaboratively developed**. They are made by many +people, and there is no single fixed master plan (but there should be, +in the instructors or maintainer's guide). We encourage +everyone to contribute to the lessons. + +Lessons are reviewed very often - essentially, before each workshop by +the instructor of that workshop. This can be a quick review, looking +at issues and fixing easy things, or more thorough. + +Every so often (such as at this training), there is an extensive +hackathon period of fully revising a lesson and making major improvements. + +We've made the [lesson-review](https://coderefinery.github.io/manuals/lesson-review/) checklist +to guide the review process. + +```{discussion} +We now go to the +[lesson-review](https://coderefinery.github.io/manuals/lesson-review/) +checklist and discuss it, instead of duplicating things here. +``` + +--- + +## Recommendations and lessons learned + +- Convert feedback about lessons and suggestions for improvements into *issues* + so that these don't get lost. +- Make your lesson citable: get a DOI. +- Credit contributors (not only Git commits). +- Instructor guide is essential for new instructors. +- Lesson changes should be accompanied with instructor guide changes (it's like + a documentation for the lesson material). +- Apply and validate backwards lesson design again and again. +- Make it possible to try out new ideas (by making the lesson branch-able). +- Before making larger changes, talk with somebody and discuss these changes. +- For substantial changes we recommend to first open an issue and describe your + idea and collect feedback before you start with an extensive rewrite. +- For things still under construction, open a draft pull request to collect + feedback and to signal to others what you are working on. diff --git a/branch/instructor-training/_sources/quick-reference.rst.txt b/branch/instructor-training/_sources/quick-reference.rst.txt new file mode 100644 index 0000000..dab2015 --- /dev/null +++ b/branch/instructor-training/_sources/quick-reference.rst.txt @@ -0,0 +1,2 @@ +Quick Reference +--------------- diff --git a/branch/instructor-training/_sources/teaching-practice.md.txt b/branch/instructor-training/_sources/teaching-practice.md.txt new file mode 100644 index 0000000..1323c86 --- /dev/null +++ b/branch/instructor-training/_sources/teaching-practice.md.txt @@ -0,0 +1,76 @@ +# Teaching practice and feedback + +Goals of the teaching practice: + +- In groups of 4-5 persons we will practice teaching a **5-minute segment + of a lesson of your choice**. +- The section you pick should require **screen sharing** and be of some + **demonstration or follow-along task** (preferably using a shell) to also + practice having a good screen-sharing setup. +- We will practice giving **constructive feedback**. +- We will practice improving our 5-minute segment by taking the feedback into account. +- In both session you can teach the same topic/segment but if you prefer you can also + change the topic/aspect for the second session. + +--- + +## Instructor demo + +- In order to demonstrate the goals of this section, the instructor + will make a 5-minute demo for your evaluation. +- It is designed to include some good and bad practices for you to + notice. + +--- + +## Teaching demos part 1 + +In group rooms, 50 minutes. + +```{challenge} +- We organize the breakout rooms to not only discuss one lesson/topic so that it is more interesting + to listen and also probably we will all get more useful feedback. +- Give each other **constructive verbal feedback** on the teaching demos, for example + using [this demo rubric](https://carpentries.github.io/instructor-training/demos_rubric/). +- Write down questions (in the collaborative document) that you would like to + discuss in the main room or interesting conclusions which you would like to + share with others. +``` + +## Teaching demos, part 2 + +In group rooms, 50 minutes. + +```{challenge} +- In the second round we distribute the rooms differently so that you can + present it to a **new group of workshop participants** and can receive new + feedback. +- Ask for feedback and one/few point(s) you want to improve. +- In your second trial check whether you feel the demonstration improved. +- Share your lessons learned in the collaborative document. +- Give us also feedback on this exercise format. Was it useful? What can we improve? +``` + +--- + +## Discussion + +```{discussion} Main room discussion + - We discuss questions and conclusions which came up during the group work session. +``` + +--- + +## Optional: feedback for two live-coding examples + +```{challenge} +Teaching by live coding is a +[performance art which requires practice](https://teachtogether.tech/#s:performance-exercises). +This exercise highlights some typical pitfalls that most instructors +fall into sooner or later, and also shows how to avoid them. +Watch closely since we will be giving feedback! +- Watch these two videos: [video 1](https://youtu.be/bXxBeNkKmJE) and + [video 2](https://youtu.be/SkPmwe_WjeY) +- What was better in video 1 and what was better in video 2? +- Please give feedback in the shared workshop document. +``` diff --git a/branch/instructor-training/_sources/teaching-strategies.md.txt b/branch/instructor-training/_sources/teaching-strategies.md.txt new file mode 100644 index 0000000..2e93a21 --- /dev/null +++ b/branch/instructor-training/_sources/teaching-strategies.md.txt @@ -0,0 +1,220 @@ +# How to teach online + +```{objectives} +- Understand the benefits and disadvantage of online teaching, + compared to in-person + +- Set up a good screen share + +- Understand the benefits and disadvantages of team teaching + +- Prepare for the teaching practice +``` + + +## Why teaching mechanics matter + +- When you teach, you are mainly showing a basic example for the + learner to follow along +- The learner has a *lot* more to think about than you do, so you need + to minimize the possible distractions and unnecessary weirdness. +- A learner will often only one small screen, limiting the number of + things that they can think about. +- You are must faster than learners (5 times possibly?) You have to + do things to slow yourself down. +- It's easy to save these mechanics until the end, and then you run + out of time. + + + + +## Shell sharing + +```{discussion} Discussion: what goes into a good shell share or demonstration? + +When you are following along with a type-along demonstration, what +things: + +- Are useful to make it easy to follow along +- Make it harder to follow along + +Answer in the collaborative notes +``` + +When doing any demonstration, there are difficulties: + +- If one misses something, you can't rewind to see it - is there any + way to catch up? +- The learner must get oriented with the whole picture, while + instructor knows precisely where to focus. + +A good **shell share** has some of the following properties: + +- Large font +- Shell history, available separately from the main shell window +- Closely matches the type-along instructions + +We have a collection of shell sharing systems: +- We will look over [lesson presentation +hints](https://coderefinery.github.io/manuals/instructor-tech-setup/#terminal-history-window). +- There are other things you can copy +- Whatever you do, do *something*. + +```{discussion} +The instructor will demonstrate several shell-sharing systems. You +will use this in the teaching practice. +``` + + + +## Screen sharing + +`````{discussion} + +Look at the various [screen layouts in the CodeRefinery +manuals](https://coderefinery.github.io/manuals/instructor-tech-setup/#screen-sharing). +Use the HackMD to comment about what which are better or worse. + +````{output} HackMD prototype +:class: dropdown +``` +- S1 + - good: + - bad: +- S2 + - good: + - bad: +- S3 + - good: + - bad: +- S4 + - good: + - bad: +- Student layouts: + - ... +- Instructor layouts: + - ... +``` +```` +````` + +- Many learners will have a smaller screen than you. +- You should plan for learners with only one small screen. +- A learner will **need to focus on both your screen share and their + work**. +- Sharing your a whole screen is almost always a bad idea, if you want + the learners to do anything at the same time. +- If you constrict yourself, then your experience is more similar to + that of a learner. + +Vertical sharing: +- CodeRefinery has recently started trialing a **vertical share** + system, where you share a vertical half of your screen. +- This allows learners with one screen to display your screen + side-by-side with their learn +- Zoom provides a "Share a part of screen" that is good for this. + + + +## Meta-talk + +Don't just teach, also make sure you guide the learners through the +course. + +- You know what you just discussed, and what is coming next, but + learners are often stuck thinking about now. +- Give a lot of "meta-talk" that is not just about the topic you are + teaching, but how you are teaching it. +- Examples + - **Why** you are doing each episode + - What is the purpose of each exercise + - Clearly state what someone should accomplish in each exercise and + how long it will take - don't assume this is obvious. + - What is the point of each lesson. How much should people expect + to get from it? Should you follow everything, or are some things + advanced and optional? Make that clear. + + + +## Teach teaching + +- Demonstration-based teaching require two different types of focus: + - Doing the mechanical steps as a demonstration + - Explaining why you are doing it +- This is a lot for one person to keep in mind, so can multiple people + work together for this? +- Team teaching idea: + - One person is doing the demonstrations + - One person is giving the commentary about what they are doing + - The lecture becomes a discussion between two people instead. + +Advantages: +- This reduces the pressure on each person (reduces demo effect) +- You are less likely to forget things +- It slows you down in teaching +- It makes the lesson more interesting to listen to +- One person can follow questions +- Great for introducing new instructors (which half is easier to start + with?) + +Disadvantage: +- Requires two people's time +- Requires coordination when preparing (slows you down in preparation) +- Unfamiliar concept to most people + + + +## Questions + +- Questions are great, and important for any practical and interactive + class +- But questions in main room doesn't scale to very large rooms. +- CodeRefinery strategy: HackMD for questions + - Chat is not good enough, you can't reply to old things + - HackMD allows threaded replies and follow up later + - You need some other helpers to watch HackMD and answer, and bring + things up to you. And let you know how things are going. + - Learners can ask anonymously + - Learners don't have to worry about interrupting the flow. + - Disadvantage: can produce information overload, warn people to not + follow too closely + - With too few people, it can turn out to be very quiet. +- We will learn more about HackMD questions tomorrow in + {doc}`workshops-online`. + +```{seealso} +* {doc}`workshops-online` +* [HackMD +mechanics](https://coderefinery.github.io/manuals/hackmd-mechanics/) +and [HackMD +helpers](https://coderefinery.github.io/manuals/hackmd-helper/) on +CodeRefinery manulas. +``` + + + +## Teaching practice + +In {doc}`teaching-practice`, you will break into groups and try to +apply these strategies to a five-minute example session. + + + +## See also + +In this lesson: + +* {doc}`workshops-online` + +CodeRefinery manuals: + +* [Instructor tech + setup](https://coderefinery.github.io/manuals/instructor-tech-setup/) +* [Lesson preparation + hints](https://coderefinery.github.io/manuals/presenting/) (more + focused on in-person) +* [Instructor + introduction](https://coderefinery.github.io/manuals/presenting/) - + has a lot of tips for new instructors, but also more things about + the workshop. +* [Workshop prep call](https://coderefinery.github.io/manuals/workshop-prep-call/) diff --git a/branch/instructor-training/_sources/welcome.md.txt b/branch/instructor-training/_sources/welcome.md.txt new file mode 100644 index 0000000..ec9af20 --- /dev/null +++ b/branch/instructor-training/_sources/welcome.md.txt @@ -0,0 +1,88 @@ +# Welcome and introduction + +```{discussion} What do we want to get out of this workshop +- Introduction of instructors and helpers +- Each instructor can say what we want to get out of the instructor training +- But we want to know from everybody and collect these in the live notes +``` + +--- + +## Goals for this workshop + +```{discussion} Goals for this instructor training +- Give future instructors the **tools and confidence** to teach best software practices and tools. +- **Motivate new instructors** to take up lessons, remix them, and to contribute. +- **Get feedback** to improve the material as well as our collaboration model. +- For us to **learn how we can support** related efforts and collaborate. +- **Catalyze and form new networks** and collaborations of teachers and trainers of + practical scientific computing. +``` + + +### Giving confidence + +> *Goal number one should be that we give participants the confidence to +> independently apply the tools or knowledge learnt. This is more important +> that giving a "complete" overview.* [Lucy Whalley gave this great comment at one of our workshops] + +- You don't have to know everything to use (or teach) something. +- For the large majority of topics we teach, there are many resources online + which provide how-to guides or tutorials. And the Stack Overflow answer bank + isn't getting any smaller. So we need to ask why do people attend in-person + sessions if there is information freely available? Our impression is that + it is for confidence building, identity formation, perhaps signposting to + resources. +- This also links with building a welcoming/inclusive environment: for example, + imposter syndrome, which disproportionately affects under-represented groups + ([link](https://www.ncda.org/aws/NCDA/pt/sd/news_article/245005/_PARENT/CC_layout_details/false)), + can manifest as low self-confidence --> building the confidence of + students in the classroom may lead to a more diverse community. + +--- + +## Tools for this workshop + +We always start workshops with these: +- [HackMD mechanics and controls](https://coderefinery.github.io/manuals/hackmd-mechanics/) +- [Zoom mechanics and controls](https://coderefinery.github.io/manuals/zoom-mechanics/) + +--- + +## Code of Conduct + +- We follow [The Carpentries Code of Conduct](https://docs.carpentries.org/topic_folders/policies/code-of-conduct.html). +- This is a hands-on, interactive workshop. + - Be kind to each other and help each other as best you can. + - If you can't help someone or there is some problem, let someone know. + - If you notice something that prevents you from learning as well as you can, let us know and don't suffer silently. +- It's also about the little things: + - volume + - font size + - generally confusing instructor + - **not enough breaks** + +--- + +## Overview of the lessons and a typical workshop + +Here the instructor gives an overview of the lessons and a typical workshop. + +--- + +```{discussion} What we do differently? +- Planing, teaching material available in advance and not PDF slides +- Different roles (instructor, host, hackmd, ...) +- GitHub projects board so all boxes are checked +- Helper recruitment and breakout room planning + - Designing for this as soon as you open registration +- Less is more +- Welcome session and "outro" session +- Clearly defining learning outcomes +- Asking for feedback, encouraging feedback +- Manual +- Screen-sharing +- Using lesson templates +- Lesson review on GitHub +- Sharing material instead of being protective +``` diff --git a/branch/instructor-training/_sources/workshops-online.md.txt b/branch/instructor-training/_sources/workshops-online.md.txt new file mode 100644 index 0000000..abf5222 --- /dev/null +++ b/branch/instructor-training/_sources/workshops-online.md.txt @@ -0,0 +1,256 @@ +--- +layout: episode +title: "Lessons learned from running online and in-person workshops" +teaching: 20 +exercises: 10 +questions: + - "What are the steps for organizing a CodeRefinery workshop?" + - "What can I learn about running my own workshop?" + - "What have we learned from running large online workshops?" +objectives: + - "Learn how to use the manuals to organize and teach a workshop." +keypoints: + - "There are many aspects to consider to deliver a successful workshop." + - "CodeRefinery maintains a number of manuals - use them when preparing a workshop." +--- + +> ## Workshop manuals +> CodeRefinery maintains a number of [workshop manuals](https://github.com/coderefinery/manuals/) +> with most of the "primary" information. This episode condenses this +> into a quick overview. +{: .callout} + + +# Running a workshop: online + + +## Online teaching discussion + +```{discussion} Discussion: Online vs in-person + +In notes: +- Compare and contrast the benefits of online teaching with + in-person: {advantage, disadvantage} × {content, presentation} +- How do you have to prepare differently? +- What are your own experiences? +``` + + + +## Case study: Mega-CodeRefinery and Finland HPC Kickstart + +- Mega-CodeRefinery + - Audience of around 90-100 + - "bring your own breakout room" (see below) + - 3 days/week, 6 days total + - Lessons as normal in CodeRefinery +- HPC Kickstart + - 250 registered, ~180 max participants + - Multi-university: local differences made this much harder to manage. + - Breakout rooms not pre-planned. + +Mega-CodeRefinery worked very well, HPC kickstart didn't - but not +because of the size. + + + +## General workshop arrangements + +> ## Manuals link +> - [before the +> workshop](https://github.com/coderefinery/manuals/blob/master/workshop-administration.md#before-the-workshop) +{: .callout} + +- Select a coordinator, recruit instructors (at least 3 is important), + find helpers +- Find a good lecture room: + [requirements](https://github.com/coderefinery/manuals/blob/master/workshop-requirements-inperson.md) +- Set up workshop webpage using the [Github, template + repository](https://github.com/coderefinery/template-workshop-webpage]: + [see + manuals](https://github.com/coderefinery/manuals/blob/master/workshop-administration.md#set-up-workshop-page) +- Advertising the workshop +- Communication with registered participants + + + +## CodeRefinery online scaling strategy + +- We started online workshops in 2020 March, for the obvious reasons. +- First, we started with two "normal size" (20 people) practice + workshops +- Then we did a 100 person workshop. It went well, but there is less + tolerance for problems. + + +### Basic preparation + +- You need more breaks are needed +- People have a way of doing too many things and not focusing. +- "[How to attend an online + workshop](https://coderefinery.github.io/manuals/how-to-attend-online/)" + guide to prepare learners + +### Basic platform: Zoom + +- Zoom (not the most ethical, but worked well and was available) +- [Zoom mechanics: instructions for + students](https://coderefinery.github.io/manuals/zoom-mechanics/). + - Mostly things that are known + - We don't use Zoom interaction features much anymore + (faster/slower/etc), but breakout rooms and HackMD instead +- See also: [Online training + manual](https://coderefinery.github.io/manuals/online-training/) + (which is getting a bit old compared to what is below). + +### Breakout rooms, bring your own team + +- Breakout rooms are + - Static: same people across whole workshop + - Contain one helper per room (see below) +- Team registration: accept a "team" field when registering, people on the + same team are put together. + - Gives motivations for learners to bring their colleagues and + learn together. + - More than one person learning together greatly increases update +- You need a powerful enough registration system to assign rooms and + email them to people! +- We ask people to name themselves "(N) Firstname Lastname" or "(N,H) + Firstname Lastname" for helpers. Then it is fast to assign them to + their designated breakout rooms. +- See also: [Breakout room + mechanics](https://coderefinery.github.io/manuals/breakout-rooms-helping/) + + +### Helper training + +- Each breakout room has a helper +- Helper should be a little bit familiar, but not expected to be able + to answer all questions. +- Special, custom [helper + training](https://coderefinery.github.io/manuals/helper-intro/) + since helpers make or break the workshop +- Helper recruitment: + - Our networks + - Team registration: if a team registers with their own helper, then + they are guaranteed to get in together. "bring your own breakout + room" + - Former learners, ask them to come back. +- Two helper trainings the week before the workshop. + +### Staff roles + +To reduce stress on any one person, we clearly define the different +roles and try to avoid overlap. We actually have enough people for +all of these, so it works well. + +- Workshop coordinator + - Registration, etc. +- Zoom host + - Handles registration, breakout rooms, recording, Zoom chat. +- HackMD helper + - Dedicated to watching HackMD and answering questions quickly. + - [Host on manuals](https://coderefinery.github.io/manuals/host/) +- Expert helpers + - "Spare hands" who rotate between breakout rooms and make sure + helpers are doing well. + - Give feedback to instructor about how breakout rooms are going. + - Take the place of missing helpers. + - Easy way for any people with a bit of spare time to help out. + - [Expert helpers in workshop](https://coderefinery.github.io/manuals/expert-helpers/) +- Instructors + - Teach, they shouldn't overlap with the above roles (but serve as + expert helpers other times). + - Usually also improve the lesson a bit before teaching + - [General staff intro in manuals](https://coderefinery.github.io/manuals/instructor-intro/) +- Workshop preparation meeting + - Get together, introduce roles, kickstart instructors + - [Workshop prep meeting in manuals](https://coderefinery.github.io/manuals/workshop-prep-call/) + + +### HackMD + +- We've been using it here +- Chat doesn't work wen large, written + document does. +- HackMD can just about scale to ~100 person workshop. Recommend + learners keep it in view mode while not editing. +- Voice questions are still allowed, but will be recorded. Staff + raise important questions from HackMD to the instructor immediately. +- HackMD also allows communication when in breakout rooms. +- You can get multiple answers, and answers can be improved over + time. +- [HackMD + mechanics](https://coderefinery.github.io/manuals/hackmd-mechanics/) + and [HackMD + helpers](https://coderefinery.github.io/manuals/hackmd-helper/). + +### Recording and streaming + +- When you have 100 people, main room is quiet anyway: you don't lose + much by recording. + - Questions anonymously in HackMD, privacy loss is not so bad +- Breakout rooms are never recorded +- Streaming + - We streamed via Twitch: https://twitch.tv/coderefinery + - We typically get 5-40 viewers. + - Zoom can directly send the stream to Twitch: no extra software + needed. + - Twitch archives videos for 14 days, which allows learners to get + an instant reply (we get hundreds of views in the next days). + - So while possibly not useful for new people to learn, the instant + reply *is* very useful. Instructor can also work on problems in + main stream during breakout rooms, which learners can watch + later. + - Streamers also have access to HackMD to ask questions. +- Certain tricks needed to keep learners from appearing in recording + or stream + - "Spotlight video", host does not go to gallery view, uses dual + monitor mode. We are still figuring this out. + +### Installation time + +- People *have* to be ready once we start, or else everything fails. +- Two installation help times the week before. +- Every email emphasizes that you have to be prepared, and "requires" + you to attend workshops (but really it's only) +- Installation instructions include *steps to verify* +- Installation instructions also include *video demonstrations* of + installation and verification. +- We haven't had that many installation problems, but also we keep the + requirements simple. +- Helper introduction is right before software install time, so + helpers can stay and help with install if they want. +- *Design to be easy to install and get set up.* + +### Other notes + +- Make breakout sessions as long as possible: 10 minutes is really too + short. 20 minutes is a good minimum time. +- Be very clear about exercise expectations +- Keep HackMD updated as a log. +- Don't combine breaks and breakout times. +- The more people you have, the more diverse audience you have and the + more people overwhelmed and under whelmed. + + + +## Workshop collaborations + +Why limit ourselves to CodeRefinery workshop? Why not use our network +and techniquess for more + +- Case study: [Python for Scientific + Computing](https://aaltoscicomp.github.io/python-for-scicomp/) + - Started by Aalto + - Announced to CodeRefinery, five more instructors from three + countries joined. + - Rapid collaboration, taught course shortly later. + - Announced to all institutions. Some places had physical rooms, + some were pure online + - Also streamed + - It was much more fun and less stressful to work together + +- We want to continue this kind of collaboration in other workshops. + + diff --git a/branch/instructor-training/_static/_sphinx_javascript_frameworks_compat.js b/branch/instructor-training/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 0000000..8549469 --- /dev/null +++ b/branch/instructor-training/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,134 @@ +/* + * _sphinx_javascript_frameworks_compat.js + * ~~~~~~~~~~ + * + * Compatability shim for jQuery and underscores.js. + * + * WILL BE REMOVED IN Sphinx 6.0 + * xref RemovedInSphinx60Warning + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/branch/instructor-training/_static/basic.css b/branch/instructor-training/_static/basic.css new file mode 100644 index 0000000..4e9a9f1 --- /dev/null +++ b/branch/instructor-training/_static/basic.css @@ -0,0 +1,900 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/branch/instructor-training/_static/check-solid.svg b/branch/instructor-training/_static/check-solid.svg new file mode 100644 index 0000000..92fad4b --- /dev/null +++ b/branch/instructor-training/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/branch/instructor-training/_static/clipboard.min.js b/branch/instructor-training/_static/clipboard.min.js new file mode 100644 index 0000000..54b3c46 --- /dev/null +++ b/branch/instructor-training/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/branch/instructor-training/_static/copybutton.css b/branch/instructor-training/_static/copybutton.css new file mode 100644 index 0000000..f1916ec --- /dev/null +++ b/branch/instructor-training/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/branch/instructor-training/_static/copybutton.js b/branch/instructor-training/_static/copybutton.js new file mode 100644 index 0000000..2ea7ff3 --- /dev/null +++ b/branch/instructor-training/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/branch/instructor-training/_static/copybutton_funcs.js b/branch/instructor-training/_static/copybutton_funcs.js new file mode 100644 index 0000000..dbe1aaa --- /dev/null +++ b/branch/instructor-training/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/branch/instructor-training/_static/css/badge_only.css b/branch/instructor-training/_static/css/badge_only.css new file mode 100644 index 0000000..c718cee --- /dev/null +++ b/branch/instructor-training/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/branch/instructor-training/_static/css/fonts/Roboto-Slab-Bold.woff b/branch/instructor-training/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/branch/instructor-training/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/branch/instructor-training/_static/css/fonts/Roboto-Slab-Bold.woff2 b/branch/instructor-training/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/branch/instructor-training/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/branch/instructor-training/_static/css/fonts/Roboto-Slab-Regular.woff b/branch/instructor-training/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/branch/instructor-training/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/branch/instructor-training/_static/css/fonts/Roboto-Slab-Regular.woff2 b/branch/instructor-training/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/branch/instructor-training/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/branch/instructor-training/_static/css/fonts/fontawesome-webfont.eot b/branch/instructor-training/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/branch/instructor-training/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/branch/instructor-training/_static/css/fonts/fontawesome-webfont.svg b/branch/instructor-training/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/branch/instructor-training/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/branch/instructor-training/_static/css/fonts/fontawesome-webfont.ttf b/branch/instructor-training/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/branch/instructor-training/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/branch/instructor-training/_static/css/fonts/fontawesome-webfont.woff b/branch/instructor-training/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/branch/instructor-training/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/branch/instructor-training/_static/css/fonts/fontawesome-webfont.woff2 b/branch/instructor-training/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/branch/instructor-training/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/branch/instructor-training/_static/css/fonts/lato-bold-italic.woff b/branch/instructor-training/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/branch/instructor-training/_static/css/fonts/lato-bold-italic.woff differ diff --git a/branch/instructor-training/_static/css/fonts/lato-bold-italic.woff2 b/branch/instructor-training/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/branch/instructor-training/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/branch/instructor-training/_static/css/fonts/lato-bold.woff b/branch/instructor-training/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/branch/instructor-training/_static/css/fonts/lato-bold.woff differ diff --git a/branch/instructor-training/_static/css/fonts/lato-bold.woff2 b/branch/instructor-training/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/branch/instructor-training/_static/css/fonts/lato-bold.woff2 differ diff --git a/branch/instructor-training/_static/css/fonts/lato-normal-italic.woff b/branch/instructor-training/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/branch/instructor-training/_static/css/fonts/lato-normal-italic.woff differ diff --git a/branch/instructor-training/_static/css/fonts/lato-normal-italic.woff2 b/branch/instructor-training/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/branch/instructor-training/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/branch/instructor-training/_static/css/fonts/lato-normal.woff b/branch/instructor-training/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/branch/instructor-training/_static/css/fonts/lato-normal.woff differ diff --git a/branch/instructor-training/_static/css/fonts/lato-normal.woff2 b/branch/instructor-training/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/branch/instructor-training/_static/css/fonts/lato-normal.woff2 differ diff --git a/branch/instructor-training/_static/css/theme.css b/branch/instructor-training/_static/css/theme.css new file mode 100644 index 0000000..19a446a --- /dev/null +++ b/branch/instructor-training/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/branch/instructor-training/_static/doctools.js b/branch/instructor-training/_static/doctools.js new file mode 100644 index 0000000..527b876 --- /dev/null +++ b/branch/instructor-training/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/branch/instructor-training/_static/documentation_options.js b/branch/instructor-training/_static/documentation_options.js new file mode 100644 index 0000000..c066c69 --- /dev/null +++ b/branch/instructor-training/_static/documentation_options.js @@ -0,0 +1,14 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'dirhtml', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/branch/instructor-training/_static/file.png b/branch/instructor-training/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/branch/instructor-training/_static/file.png differ diff --git a/branch/instructor-training/_static/jquery-3.6.0.js b/branch/instructor-training/_static/jquery-3.6.0.js new file mode 100644 index 0000000..fc6c299 --- /dev/null +++ b/branch/instructor-training/_static/jquery-3.6.0.js @@ -0,0 +1,10881 @@ +/*! + * jQuery JavaScript Library v3.6.0 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright OpenJS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2021-03-02T17:08Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var flat = arr.flat ? function( array ) { + return arr.flat.call( array ); +} : function( array ) { + return arr.concat.apply( [], array ); +}; + + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 + // Plus for old WebKit, typeof returns "function" for HTML collections + // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) + return typeof obj === "function" && typeof obj.nodeType !== "number" && + typeof obj.item !== "function"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + +var document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.6.0", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return flat( ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), + function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); + } ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.6 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2021-02-16 + */ +( function( window ) { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); + + // Support: Android<4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement( "fieldset" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split( "|" ), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem && elem.namespaceURI, + docElem = elem && ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // ID filter and find + if ( support.getById ) { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find[ "TAG" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); + } : + function( a, b ) { + if ( b ) { + while ( ( b = b.parentNode ) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { + + // Choose the first element that is related to our preferred document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { + return -1; + } + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( ( cur = cur.parentNode ) ) { + ap.unshift( cur ); + } + cur = b; + while ( ( cur = cur.parentNode ) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[ i ] === bp[ i ] ) { + i++; + } + + return i ? + + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[ i ], bp[ i ] ) : + + // Otherwise nodes in our document sort first + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); + + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[ 1 ] = match[ 1 ].toLowerCase(); + + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + + // nth-* requires argument + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); + + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[ 6 ] && match[ 2 ]; + + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + + // Get excess from tokenize (recursively) + ( excess = tokenize( unquoted, true ) ) && + + // advance to the next closing parenthesis + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { + + // excess is a negative index + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + /* eslint-disable max-len */ + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + /* eslint-enable max-len */ + + }; + }, + + "CHILD": function( type, what, _argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, _context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( ( node = node[ dir ] ) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( ( node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + + // Use previously-cached element index if available + if ( useCache ) { + + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + + // Use the same loop as above to seek `elem` from the start + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction( function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); + } + } ) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + + // Potentially complex pseudos + "not": markFunction( function( selector ) { + + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction( function( seed, matches, _context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); + } + } + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; + matcher( input, null, xml, results ); + + // Don't keep the element (issue #299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), + + "has": markFunction( function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + } ), + + "contains": markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + } ), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( ( elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); + return false; + }; + } ), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); + }, + + "selected": function( elem ) { + + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos[ "empty" ]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo( function() { + return [ 0 ]; + } ), + + "last": createPositionalPseudo( function( _matchIndexes, length ) { + return [ length - 1 ]; + } ), + + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + } ), + + "even": createPositionalPseudo( function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "odd": createPositionalPseudo( function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ) + } +}; + +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { + if ( match ) { + + // Don't consume trailing commas as valid + soFar = soFar.slice( match[ 0 ].length ) || soFar; + } + groups.push( ( tokens = [] ) ); + } + + matched = false; + + // Combinators + if ( ( match = rcombinators.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[ i ].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = uniqueCache[ key ] ) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return ( newCache[ 2 ] = oldCache[ 2 ] ); + } else { + + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[ i ]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[ 0 ]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[ i ], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( ( elem = unmatched[ i ] ) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction( function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) ) { + + // Restore matcherIn since elem is not yet a final match + temp.push( ( matcherIn[ i ] = elem ) ); + } + } + postFinder( null, ( matcherOut = [] ), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { + + seed[ temp ] = !( results[ temp ] = elem ); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + } ); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[ j ].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), + len = elems.length; + + if ( outermost ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + + // They will have gone through all possible matchers + if ( ( elem = !matcher && elem ) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( ( matcher = setMatchers[ j++ ] ) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[ i ] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { + + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[ i ]; + + // Abort if we hit a combinator + if ( Expr.relative[ ( type = token.type ) ] ) { + break; + } + if ( ( find = Expr.find[ type ] ) ) { + + // Search, expanding context for leading sibling combinators + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert( function( el ) { + + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert( function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + } ); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert( function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + } ); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; + } + } ); +} + +return Sizzle; + +} )( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +} +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, _i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, _i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, _i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( elem.contentDocument != null && + + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { + + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( _i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the primary Deferred + primary = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + primary.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( primary.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return primary.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); + } + + return primary.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, _key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + + // Support: Chrome 86+ + // In Chrome, if an element having a focusout handler is blurred by + // clicking outside of it, it invokes the handler synchronously. If + // that handler calls `.remove()` on the element, the data is cleared, + // leaving `result` undefined. We need to guard against this. + return result && result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + which: true +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + // Suppress native focus or blur as it's already being fired + // in leverageNative. + _default: function() { + return true; + }, + + delegateType: delegateType + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + // + // Support: Firefox 70+ + // Only Firefox includes border widths + // in computed dimensions. (gh-4529) + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; + tr.style.cssText = "border:1px solid"; + + // Support: Chrome 86+ + // Height set through cssText does not get applied. + // Computed height then comes back as 0. + tr.style.height = "1px"; + trChild.style.height = "9px"; + + // Support: Android 8 Chrome 86+ + // In our bodyBackground.html iframe, + // display for all div elements is set to "inline", + // which causes a problem only in Android 8 Chrome 86. + // Ensuring the div is display: block + // gets around this issue. + trChild.style.display = "block"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + + parseInt( trStyle.borderTopWidth, 10 ) + + parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = { guid: Date.now() }; + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml, parserErrorElem; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) {} + + parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; + if ( !xml || parserErrorElem ) { + jQuery.error( "Invalid XML: " + ( + parserErrorElem ? + jQuery.map( parserErrorElem.childNodes, function( el ) { + return el.textContent; + } ).join( "\n" ) : + data + ) ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ).filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ).map( function( _i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + +originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Use a noop converter for missing script but not if jsonp + if ( !isSuccess && + jQuery.inArray( "script", s.dataTypes ) > -1 && + jQuery.inArray( "json", s.dataTypes ) < 0 ) { + s.converters[ "text script" ] = function() {}; + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( _i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); + + +jQuery._evalUrl = function( url, options, doc ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

About the CodeRefinery project

+

CodeRefinery is a +Nordic e-Infrastructure Collaboration (NeIC) +project that has started in October 2016 and is +funded until October 2021.

+

We hope to keep this project active beyond 2021 by forming a support network +and building a community of instructors and contributors.

+
+
+

History

+

The CodeRefinery project idea grew out of two SeSE courses given at KTH Stockholm in 2014 and 2016:

+ +

The project proposal was submitted to NeIC in 2015, accepted in 2015, and started in 2016.

+

We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form.

+
+
+
+

Main goals

+
    +
  • Develop and maintain training material on software best practices for researchers that already write code. Our material addresses all academic disciplines and tries to be as programming language-independent as possible.

  • +
  • Provide a code repository hosting service that is open and free for all researchers based in universities and research institutes from Nordic countries.

  • +
  • Provide training opportunities in the Nordics using Carpentries and CodeRefinery training materials.

  • +
  • Articulate and implement the CodeRefinery sustainability plan.

  • +
+
+
+
+

Impact

+

We collect feedback and survey results to measure our impact.

+

3-6 months after attending a workshop, past participants are asked to complete a short post-workshop survey. +The survey questions aim to establish what impact CodeRefinery workshops have on how past participants develop +research software.

+
+https://coderefinery.org/assets/img/heatmap_yesno.png +
+
    +
  • Overall quality of research software has improved: more reusable, modular, reproducible and documented.

  • +
  • Collaboration on research software development has become easier

  • +
  • Past participants share their new knowledge with colleagues

  • +
  • Usage of several tools is improved, and new tools are adopted

  • +
+

Free-form answers +also suggest that workshops are having the intended effects on how people develop code. A common theme is:

+
+

I wish I had known this stuff already as a grad student 10+ years ago…

+
+

We would love to get suggestions on how we can better quantify our impact. This +would make it easier for us to convince institutions to partner with us and +also open up funding opportunities.

+
+
+
+

Carpentries membership

+

Since November 2018, NeIC is a Platinum Partner to The Carpentries.

+

The Carpentries is an international project that comprises Software Carpentry and Data Carpentry, communities of instructors, trainers, maintainers, helpers, +and supporters who share a mission to teach foundational computational and data science skills to researchers. +The Carpentries teach foundational coding and data science skills to researchers worldwide and as such are complementary to CodeRefinery.

+

Within the membership the Nordic research community has access to:

+
    +
  • 6 Carpentries workshops in the Nordics each year. The workshop fee is covered by the membership, only the instructor travel is on the host institution.

  • +
  • 15 seats in the Carpentries instructor training each year. Carpentries train the trainer program aims at building partnerships with Research Software Engineers and researchers who are willing to lead skill transfer within their local communities in the Nordics.

  • +
+
+
+
+

Target audience

+
+

Carpentries audience

+

The Carpentries aims to teach computational competence to learners through an applied approach, avoiding the theoretical and general in favor of the practical and specific.

+

Learners do not need to have any prior experience in programming. One major goal of a Carpentry workshop is to raise awareness on the tools researchers can learn/use to speed up their research.

+

By showing learners how to solve specific problems with specific tools and providing hands-on practice, learners develops confidence for future learning.

+
+

Novices

+

We often qualify Carpentry learners as novices: they do not know what they need to learn yet. A typical example is the usage of version control: the Carpentry git lesson aims to give a very high level conceptual overview of Git but it does not explain how it can be used in research projects.

+
+
+
+

CodeRefinery audience

+

In that sense, CodeRefinery workshops differ from Carpentry workshops as we assume our audience already writes code and scripts and we aim at teaching them best software practices.

+

Our learners usually do not have a good overview of best software practices but are aware of the need to learn them. Very often, they know the tools (Git, Jupyter, etc.) we are teaching but have difficulties to make the best use of them in their software development workflow.

+

Whenever we can, we should direct learners that do not have sufficient coding experience to Carpentries workshops.

+
+

Competent practitioners

+

We often qualify CodeRefinery learners as competent practitioners because they already have an understanding of their needs. +Novices and competent practitioners will be more clearly defined in the next section.

+
+
+

Best software practices for whom?

+

It can be useful to ask the question: best software practices for whom? +CodeRefinery teaches best software practices derived from producing and +shipping software. These practices are also very good for sharing software, +though our audience will probably not need to embrace all aspects of +software engineering.

+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/instructor-training/coderefinery-workshops/index.html b/branch/instructor-training/coderefinery-workshops/index.html new file mode 100644 index 0000000..15dce04 --- /dev/null +++ b/branch/instructor-training/coderefinery-workshops/index.html @@ -0,0 +1,191 @@ + + + + + + + Organize a CodeRefinery workshop — CodeRefinery instructor training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Organize a CodeRefinery workshop

+

You or us?

+
    +
  • Historically, most workshops are CodeRefinery workshops were +organized centrally with a local host.

  • +
  • Now, we want to transition to locally-invited workshops, so we know +we have a audience and advertisement.

  • +
  • In the future, we need to transition to “independently run”.

  • +
+

Anyone can organize a CodeRefinery workshop and teach the CodeRefinery lessons which are +licensed under CC-BY. +However, making it a successful workshop requires careful planning and preparation. Here we will go +through practical aspects of organizing a workshop.

+
+

Centrally organized workshops

+
    +
  • CodeRefinery staff organize, we try to reach as many people as +possible.

  • +
  • Workshops in our own institutions tend to be best-attended, going to +a new institution sometimes has low attendance.

  • +
  • We started this way.

  • +
+
+
+

Locally invited workshops

+
    +
  • A local team requests CodeRefinery (usually with a known audience).

  • +
  • There is usually pretty good attendance.

  • +
  • CodeRefinery staff travels to site and teaches - at least with local +helpers, ideally with a local instructor.

  • +
+
+
+

Independently organized workshops

+
    +
  • In the future, we want to encourage independently organized +workshops: a site can organize the workshops without needing to go +through the core team.

  • +
  • We don’t yet know exactly how this will work, but this instructor +training is part of it.

  • +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/instructor-training/future/index.html b/branch/instructor-training/future/index.html new file mode 100644 index 0000000..68d1a9f --- /dev/null +++ b/branch/instructor-training/future/index.html @@ -0,0 +1,237 @@ + + + + + + + Future — CodeRefinery instructor training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Future

+
+

Activities

+
+

What is CodeRefinery?

+ +
+
+

This workshop

+
    +
  • Was it a useful format and useful content? Please give us feedback.

  • +
  • Should we collaborate on HPC Carpentry workshops?

  • +
  • Who will end up teaching HPC Carpentry? What do you need from us/somebody as support?

  • +
+
+
+

Nordic-RSE (research software engineers)

+ +
+
+

Collaborative workshops

+ +
+
+
+
+

How to get involved in CodeRefinery

+

There are many ways to get involved: https://coderefinery.org/get-involved/

+
    +
  • Become a workshop helper

  • +
  • Become a CodeRefinery workshop instructor

  • +
  • Become a Carpentries workshop instructor

  • +
  • Contribute to teaching material: https://github.com/coderefinery/

  • +
  • Create your own teaching material in our constellation of teaching.

  • +
  • Reuse our material

  • +
  • Become an institutional partner as a training hub

  • +
  • Participate in our chat and shape the project and lessons with us: https://coderefinery.zulipchat.com

  • +
  • Start a study group

  • +
+
+
+
+

Biggest open problems

+
    +
  • How to give helpers and contributors more credit and visibility

  • +
  • How to promote/engage new members

  • +
  • We don’t know how we should be in relation with Carpentries

  • +
  • What are we? Non-profit? Institution collaboration network? Selling services?

  • +
  • Funding and sustainability (but we have ideas: collaboration network)

  • +
  • Scalability and marketing question: How to reach more people? +(Research Software Hour, Twitch, streaming-only +workshops, recording, post-processing videos)

  • +
+
+
+
+

Certification for CodeRefinery instructors

+

We will set up a more formal process soon but for now you would need to:

+
    +
  • Attend an instructor training (this workshop).

  • +
  • Contribute to a lesson, either via pull request, issue, discussion, or as a helper.

  • +
  • Share a short teaching demo or teach a lesson at a CodeRefinery workshop where you will get some feedback on your teaching.

  • +
  • Participate in a call with other instructors and helpers either preparing a workshop or during a workshop debrief session.

  • +
+

There are many ways to learn how to teach well. We and carpentries provide one way and basic material, but we want to find a way for everyone to be a part of us.

+

See also https://coderefinery.github.io/manuals/instructor-intro/#from-helper-to-more.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/instructor-training/genindex/index.html b/branch/instructor-training/genindex/index.html new file mode 100644 index 0000000..2d7edc7 --- /dev/null +++ b/branch/instructor-training/genindex/index.html @@ -0,0 +1,143 @@ + + + + + + Index — CodeRefinery instructor training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/branch/instructor-training/guide/index.html b/branch/instructor-training/guide/index.html new file mode 100644 index 0000000..1cafa4e --- /dev/null +++ b/branch/instructor-training/guide/index.html @@ -0,0 +1,143 @@ + + + + + + + Instructor’s guide — CodeRefinery instructor training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/branch/instructor-training/index.html b/branch/instructor-training/index.html new file mode 100644 index 0000000..156d4ca --- /dev/null +++ b/branch/instructor-training/index.html @@ -0,0 +1,276 @@ + + + + + + + CodeRefinery instructor training — CodeRefinery instructor training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CodeRefinery instructor training

+

CodeRefinery instructor training is focused on helping competent practitioners +and experts teach their knowledge to others. It also serves a +kickstart to teaching CodeRefinery lessons, but we also have a +gradual pathway of learner → helper → advanced helper → instructor as +well.

+
+

Prerequisites

+

This course has no strict prerequisites, but

+
    +
  • It is helpful if you have attended CodeRefinery or Carpentries +workshops, which teach in an interactive and hands-on way.

  • +
  • We assume you already have competence in the technical tools you +want to teach. Many of our concepts use examples from +CodeRefinery lessons, such as version control or other software +development tools.

  • +
  • While not a prerequisite for this course, version control (git) +is necessary to contribute to lessons development the way we show +here (but the lesson design concepts are applicable to other +styles, too).

  • +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

60 min

Pre-workshop preparation

10 min

Welcome and introduction

15 min

About the CodeRefinery project

30 min

CodeRefinery teaching philosophies

20 min

Interactive teaching style

25 min

Running a workshop: online

20 min

Lesson design

30 min

Collaborative lesson development

30 min

How to teach online

100 min

Teaching practice and feedback

20 min

Future

5 min

Organize a CodeRefinery workshop

+ + +
+

Who is the course for?

+

You are interested in teaching CodeRefinery lessons, and would like a +comprehensive kickstart to how CodeRefinery works either to join us, +or teach its lessons with us or independently.

+

You are a technical specialist who is frustrated with the way you +currently try to teach others who need to use your software or +infrastructure. You can’t spend too much time to become a +professional, but you know you need something more than what you’ve +been doing. Thus, you would like to adopt some of the best practices of +designing and teaching interactive, hands-on workshops.

+

You’ve been teaching alone, but would like to join a collaboration +network for more co-teaching and to reduce the amount of duplication +of effort.

+

You would like the most important practices from the Carpentries +instructor training/lesson design philosophy, but can not take the +time for the full Carpentries program.

+
+
+

About the course

+

This course gives an introduction to

+
    +
  • Science and philosophy of teaching

  • +
  • How to teach interactive, hands-on lessons

  • +
  • How to design interactive, hands-on lessons

  • +
  • How CodeRefinery runs workshops

  • +
  • How CodeRefinery has scaled up and taken the best advantage of +online teaching

  • +
  • CodeRefinery itself

  • +
  • The CodeRefinery collaboration network (and related networks in the +Nordics)

  • +
+
+
+

See also

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/instructor-training/lesson-design/index.html b/branch/instructor-training/lesson-design/index.html new file mode 100644 index 0000000..08090b4 --- /dev/null +++ b/branch/instructor-training/lesson-design/index.html @@ -0,0 +1,358 @@ + + + + + + + Lesson design — CodeRefinery instructor training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Lesson design

+ +
+
+

How do you design?

+
+

Discussion

+

Discuss either in groups or via collaborative document:

+
    +
  • How do you start when you design a new lesson/presentation?

  • +
  • Has your approach changed over the years? If yes, how?

  • +
+
+
+
+
+

Backwards lesson design

+
+

The approach

+
    +
  • You don’t think about how to do something and try to explain it.

  • +
  • Avoid the typical approach “I want to show a number of things which I think are cool about +tool X - how do I press these into 90 minutes?”

  • +
  • Instead, you start defining your target audience by answering to questions +such What is the expected educational level of my audience?, Have they +been already exposed to the technologies I am planning to teach?, What +tools do they already use?, What are the main issues they are currently +experiencing?. It is important to discuss these points with a group of +colleagues, preferably from diverse backgrounds and institutions to reduce +biases. Once you clarified your target audience, it is useful to create +learner personas; that will help you during the development process by +providing concrete examples of potential learners showing up at your +workshops. For each learner personas, try to think of what is useful to +them: “What do they need to +remember/understand/apply/analyze/evaluate/create?”. +Asking and answering to these questions will allow you to define the +background knowledge (starting points) and goals (end points) of your +learners. Then, you create a sequence of exercises which test incrementally +progressing tasks and acquisition of the new skills (from starting to end +points).

  • +
  • Then, you write the minimum amount +of material to teach the gap between exercises.

  • +
+
+
+

The process

+

For the whole process, see our +manual +(instructor discusses these points briefly).

+
+
+

Why is it good to have a process?:

+
    +
  • Having a semi-rigid design process can save time to start drafting.

  • +
  • It allows collaborative development of teaching material.

  • +
  • It will probably increase quality and relevance of lessons for learners.

  • +
  • We aren’t perfect yet. CodeRefinery is still striving to get +better at this, and we are more ad-hoc than you might think. +A number of our lessons have not been designed this way but we are now improving +these lessons with the backwards lesson design in mind.

  • +
+
+
+

Designing exercises

+

The goal of exercises is twofold:

+
    +
  • instructors can assess the progress of learners.

  • +
  • learners put in practice the skills that you have included in your skills list.

  • +
+

When designing exercises, consider that some participants will get stuck +and may want to re-join at a later exercise. In other words it is nice +if exercises build up on each other but not at the cost that if participants +get stuck at exercise 2, they will not be able to do exercises 3 to N.

+
+
+
+
+

Practice backwards design

+
+

The goal here is to discuss and provide examples on backwards-design of a lesson.

+

Let’s take as an example the HPC Carpentry lesson

+

Target audience

+
    +
  • What is the expected educational level of my audience?

    +
      +
    • A PhD student, postdoc or young researcher.

    • +
    +
  • +
  • Have they been already exposed to the technologies I am planning to teach?

    +
      +
    • The word HPC is not new to them and they may have already used an HPC but are still not capable of giving a proper definition of HPC. In addition, we do not expect them to know much about parallelism and they cannot make any distinction between various available parallelism paradigms.

    • +
    +
  • +
  • What tools do they already use?

    +
      +
    • serial codes, multi-threaded codes, data parallelism; usually out-of-the-box tools.

    • +
    • they may have tried to “scale” their code (multiprocessing, threading, GPUs) with more or less success.

    • +
    +
  • +
  • What are the main issues they are currently experiencing?

    +
      +
    • they cannot solve their problems either because they would like to run the same code but with many different datasets or because their problem is larger (more computations/memory).

    • +
    • most of the time they know their codes can run on HPC (from the documentation) but never really had the opportunity to try it out.

    • +
    • Very few will have their own codes where they may have tried different things to speed it up (threading, task parallelism) but have no clear strategy.

    • +
    +
  • +
+

Learner persona

+
    +
  • Sonya is a 1st year PhD student: she recently moved to Oslo and joined the +Computational and Systems Neuroscience group. She will be using the +NEST, a simulator for spiking +neural network model. She used NEST during her master thesis but on her +small cluster: she never used an HPC resource and is really excited about it.

  • +
  • Robert is a field ecologist who obtained his PhD 6 months ago. He is now +working on a new project with Climate scientists and as a consequence will +need to run global climate models. He is not very familiar with command +line even though he attended a Software Carpentry workshop and the idea to +use HPC is a bit terrifying. He knows that he will get support from his +team who has extensive experience with HPC but would like to become more +independent and be able to run his own simulations (rather than copying +existing cases).

  • +
  • Jessica is a postdoc working on a project that investigates numerically the +complex dynamics arising at the tip of a fluid-driven rupture. Fluid +dynamics will be computed by a finite element method solving the +compressible Navier-Stokes equations on a moving mesh. She uses a code she +has developed during her PhD and that is based on existing libraries. She +has mostly ran it on a local desktop; her work during her PhD was very +limited due to the lack of computing resources and she is now very keen is +moving to HPC; she knows that it will requires some work, in particular to +parallelize her code. This HPC training will be her first experience with +HPC.

  • +
+

Learning outcomes

+
    +
  • Understand the difference between HPCs and other local/remote machines

  • +
  • Understand the notion of core, nodes, cluster, shared/distributed memory, etc.

  • +
  • Understand the notion of login nodes.

  • +
  • Understand the need for a scheduler and how to use it appropriately

  • +
  • Understand why optimising I/O is important on HPC and how to best use HPC filesystems

  • +
  • Understand the need to parallelize (or use existing parallel) codes and in which cases HPCs is a must (when communications is required)

  • +
  • Understand how to get your code ready to use on HPC (access to libraries, installation of your own libraries/software, etc.)

  • +
  • Understand that an HPC is an operational machine and is not meant for developing codes.

  • +
+

Exercises

+
    +
  • Get basic information such the number of CPUs, memory from your laptop and try to do the same on a HPC. Discuss outcomes.

  • +
  • Try to create files on the different filesystems on your HPC resource and access them.

  • +
  • Create different types of job scripts, submit and check outputs.

  • +
  • Make a concrete example to run a specific software on your HPC (something like GROMACS).

  • +
+
+
+

Demo

+

Before we let participants present to their groups, one of the instructors +presents a 5-minute segment and we practice together giving feedback.

+

The section we demo should require screen sharing and be of some follow-along +task.

+

If there is time, we present one demo on the day before, and one demo just +before the group exercise.

+
+
+

Exercise

+

Choose a simple lesson topic and apply backwards lesson design. You +won’t get all the way through, but come up with a logical +progression of exercises.

+

The section you pick should require screen sharing and be of some follow-along +task (preferably using a shell).

+

Some suggestions:

+
    +
  • Regular expressions

  • +
  • Making papers in LaTeX

  • +
  • Making figures in your favorite programming language

  • +
  • Linux shell basics

  • +
  • Something non-technical, such as painting a room

  • +
  • An instructor training for CodeRefinery

  • +
  • Some aspect from an already existing lesson

  • +
  • Introduction to high-performance computing (or an episode therein)

  • +
  • Unix shell in a HPC context (or an episode therein)

  • +
  • A lesson you always wanted to teach

  • +
+

Exercise (30 minutes):

+
    +
  • Collect notes in a shared document.

  • +
  • Start with learner personas and learning outcomes.

  • +
  • Come up with a logical progression of exercises.

  • +
+

Discussion (15 minutes):

+
    +
  • How does this approach compare to other lessons or courses you have designed?

  • +
  • We read, compare, and discuss our notes.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/instructor-training/lesson-development/index.html b/branch/instructor-training/lesson-development/index.html new file mode 100644 index 0000000..ca6f056 --- /dev/null +++ b/branch/instructor-training/lesson-development/index.html @@ -0,0 +1,250 @@ + + + + + + + Collaborative lesson development — CodeRefinery instructor training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Collaborative lesson development

+

This session focuses on organizational and technical aspects +of collaborative lesson development.

+
+

Discussion

+

This session is about collaborative lesson development. What advantages do +you see in developing lessons collaboratively and sharing lessons (making +material accessible)? What difficulties are there?

+
+
+
+

Lesson templates for static sites

+ +

Why static sites?

+
    +
  • Decentralized (in terms of organization/namespace)

  • +
  • Forkable

  • +
  • Anybody can suggest changes

  • +
+
+
+
+

Creating new teaching material

+

Creating new teaching material is a longer process, because you should +go through the whole +backwards lesson design process +and get extensive comments. +Still, don’t feel afraid: nothing is perfect (or even good) +the first time. In fact, it may be an advantage to share an imperfect +lesson with others early to collect feedback and suggestions before the lesson +“solidifies” too much. Draft it and collect feedback. The result will probably +be better than working in isolation towards a “perfect” lesson.

+
+

Discussion

+

How can we share unfinished work/ideas?

+
    +
  • Draft pull requests (GitHub) or WIP (work in progress) merge requests (GitLab).

  • +
  • Open an issue and discuss your idea before implementing it.

  • +
+
+
+
+
+

Contributing to existing lessons

+

Our lessons are collaboratively developed. They are made by many +people, and there is no single fixed master plan (but there should be, +in the instructors or maintainer’s guide). We encourage +everyone to contribute to the lessons.

+

Lessons are reviewed very often - essentially, before each workshop by +the instructor of that workshop. This can be a quick review, looking +at issues and fixing easy things, or more thorough.

+

Every so often (such as at this training), there is an extensive +hackathon period of fully revising a lesson and making major improvements.

+

We’ve made the lesson-review checklist +to guide the review process.

+
+

Discussion

+

We now go to the +lesson-review +checklist and discuss it, instead of duplicating things here.

+
+
+
+
+

Recommendations and lessons learned

+
    +
  • Convert feedback about lessons and suggestions for improvements into issues +so that these don’t get lost.

  • +
  • Make your lesson citable: get a DOI.

  • +
  • Credit contributors (not only Git commits).

  • +
  • Instructor guide is essential for new instructors.

  • +
  • Lesson changes should be accompanied with instructor guide changes (it’s like +a documentation for the lesson material).

  • +
  • Apply and validate backwards lesson design again and again.

  • +
  • Make it possible to try out new ideas (by making the lesson branch-able).

  • +
  • Before making larger changes, talk with somebody and discuss these changes.

  • +
  • For substantial changes we recommend to first open an issue and describe your +idea and collect feedback before you start with an extensive rewrite.

  • +
  • For things still under construction, open a draft pull request to collect +feedback and to signal to others what you are working on.

  • +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/instructor-training/objects.inv b/branch/instructor-training/objects.inv new file mode 100644 index 0000000..609a4de Binary files /dev/null and b/branch/instructor-training/objects.inv differ diff --git a/branch/instructor-training/quick-reference/index.html b/branch/instructor-training/quick-reference/index.html new file mode 100644 index 0000000..b62b366 --- /dev/null +++ b/branch/instructor-training/quick-reference/index.html @@ -0,0 +1,145 @@ + + + + + + + Quick Reference — CodeRefinery instructor training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/branch/instructor-training/search/index.html b/branch/instructor-training/search/index.html new file mode 100644 index 0000000..136b5fd --- /dev/null +++ b/branch/instructor-training/search/index.html @@ -0,0 +1,157 @@ + + + + + + Search — CodeRefinery instructor training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2020, The contributors.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/branch/instructor-training/searchindex.js b/branch/instructor-training/searchindex.js new file mode 100644 index 0000000..f62b2cd --- /dev/null +++ b/branch/instructor-training/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["00-preparation", "02-teaching-philosophies", "03-teaching-style", "about-coderefinery", "coderefinery-workshops", "future", "guide", "index", "lesson-design", "lesson-development", "quick-reference", "teaching-practice", "teaching-strategies", "welcome", "workshops-online"], "filenames": ["00-preparation.md", "02-teaching-philosophies.md", "03-teaching-style.md", "about-coderefinery.md", "coderefinery-workshops.md", "future.md", "guide.rst", "index.rst", "lesson-design.md", "lesson-development.md", "quick-reference.rst", "teaching-practice.md", "teaching-strategies.md", "welcome.md", "workshops-online.md"], "titles": ["Pre-workshop preparation", "CodeRefinery teaching philosophies", "Interactive teaching style", "About the CodeRefinery project", "Organize a CodeRefinery workshop", "Future", "Instructor\u2019s guide", "CodeRefinery instructor training", "Lesson design", "Collaborative lesson development", "Quick Reference", "Teaching practice and feedback", "How to teach online", "Welcome and introduction", "Running a workshop: online"], "terms": {"Being": 0, "i": [0, 1, 2, 3, 4, 9, 11, 12, 13, 14], "requir": [0, 1, 4, 8, 11, 12, 14], "attend": [0, 3, 4, 5, 7, 8, 13, 14], "coderefineri": [0, 8, 12], "train": [0, 1, 2, 3, 4, 5, 8, 9], "complet": [0, 2, 3, 13], "our": [0, 1, 2, 3, 4, 5, 7, 8, 9, 11, 13, 14], "survei": [0, 2, 3], "your": [0, 1, 2, 5, 7, 8, 9, 11, 12], "respons": 0, "help": [0, 1, 2, 7, 8, 13, 14], "u": [0, 1, 2, 3, 4, 5, 7, 11, 13], "custom": [0, 1, 14], "appropri": [0, 8], "read": [0, 1, 2], "thi": [0, 1, 3, 4, 7, 8, 9, 11, 12, 14], "short": [0, 2, 3, 5, 14], "paper": [0, 8], "The": [0, 1, 3, 9, 11, 12, 13, 14], "scienc": [0, 3, 7], "learn": [0, 1, 3, 5, 8, 11, 12, 13, 14], "which": [0, 1, 2, 4, 7, 8, 11, 12, 13, 14], "provid": [0, 2, 3, 5, 12, 13], "brief": 0, "overview": [0, 2, 3, 14], "some": [0, 1, 2, 5, 7, 8, 11, 12, 13, 14], "kei": 0, "evid": [0, 2], "base": [0, 1, 2, 3, 8, 9, 12], "result": [0, 2, 3, 9], "teach": [0, 3, 4, 5, 7, 8, 13], "also": [0, 1, 2, 3, 5, 11, 13, 14], "us": [0, 1, 3, 5, 7, 8, 9, 11, 12, 13, 14], "watch": [0, 1, 2, 11, 12, 14], "least": [0, 1, 2, 4, 14], "two": [0, 1, 2, 3, 12, 14], "record": [0, 5], "5": [0, 2, 7, 8, 11, 12, 14], "minut": [0, 2, 8, 11, 12, 14], "lightn": 0, "video": [0, 2, 5, 11, 14], "introduc": [0, 12, 14], "variou": [0, 8, 12], "lesson": [0, 1, 2, 3, 4, 5, 11, 12, 14], "get": [0, 1, 3, 8, 9, 11, 12, 14], "an": [0, 1, 2, 3, 5, 7, 8, 9, 13, 14], "what": [0, 1, 3, 7, 8, 9, 11, 14], "we": [0, 1, 2, 3, 4, 5, 7, 8, 9, 11, 12, 14], "abl": [0, 1, 2, 8, 9, 14], "practic": [0, 1, 2, 4, 5, 7, 13, 14], "dai": [0, 2, 8, 14], "2": [0, 2, 5, 8], "cours": [0, 1, 2, 3, 8, 12, 14], "my": [0, 1, 8], "philosophi": [0, 7], "discuss": [0, 1, 2, 5], "group": [0, 2, 5, 8, 11, 12, 13], "form": [0, 3, 13], "basi": 0, "exercis": [0, 1, 12, 14], "pleas": [0, 1, 5, 11], "go": [0, 1, 2, 4, 9, 12, 14], "through": [0, 2, 3, 4, 8, 9, 12], "find": [0, 1, 5, 14], "one": [0, 1, 2, 5, 8, 11, 12, 13, 14], "topic": [0, 1, 2, 7, 8, 11, 12, 13], "episod": [0, 1, 2, 8, 12, 14], "aspect": [0, 1, 3, 4, 8, 9, 11], "interest": [0, 1, 7, 11, 12], "dure": [0, 1, 2, 5, 8, 11, 14], "session": [0, 1, 2, 5, 9, 11, 12, 13, 14], "ask": [0, 1, 2, 3, 8, 11, 12, 13, 14], "present": [0, 2, 3, 8, 11, 12, 14], "choic": [0, 2, 11], "construct": [0, 9, 11], "feedback": [0, 1, 3, 5, 7, 8, 9, 12, 13, 14], "worri": [0, 1, 12], "ar": [0, 1, 3, 4, 5, 7, 8, 9, 12, 13, 14], "section": [0, 2, 3, 8, 11], "do": [0, 1, 2, 3, 5, 7, 9, 12, 14], "understand": [0, 1, 2, 3, 8, 12], "main": [0, 1, 8, 12, 14], "object": [0, 1], "baselin": 0, "check": [0, 1, 2, 8, 11, 13], "abil": [0, 1], "share": [1, 2, 3, 5, 8, 9, 11, 13], "approach": [1, 3, 7], "trick": [1, 14], "solut": 1, "live": [1, 2, 13], "document": [1, 3, 7, 8, 9, 11, 14], "other": [1, 2, 5, 7, 8, 9, 11, 12, 13], "addit": [1, 2, 8], "question": [1, 2, 3, 5, 8, 11, 14], "motiv": [1, 13, 14], "take": [1, 2, 7, 8, 11, 12, 13, 14], "how": [1, 3, 4, 7, 9, 11, 13, 14], "structur": 1, "inform": [1, 2, 8, 12, 13, 14], "own": [1, 2, 3, 4, 5, 8], "need": [1, 2, 3, 4, 5, 7, 8, 12, 13, 14], "differ": [1, 2, 3, 8, 11, 12, 14], "you": [1, 2, 4, 5, 7, 9, 11, 12, 13, 14], "notic": [1, 11, 13], "between": [1, 2, 8, 12, 14], "carpentri": [1, 5, 7, 8, 9, 13], "tradit": 1, "academ": [1, 3], "skill": [1, 2, 3, 8], "taught": [1, 2, 14], "isn": [1, 13], "t": [1, 2, 4, 5, 7, 8, 9, 12, 13, 14], "right": [1, 14], "set": [1, 2, 5, 12, 14], "here": [1, 2, 4, 7, 9, 13, 14], "instructor": [1, 3, 4, 8, 9, 12, 14], "show": [1, 3, 7, 8, 11, 12], "all": [1, 2, 3, 8, 11, 13, 14], "have": [1, 2, 3, 4, 5, 7, 11, 12, 13, 14], "style": [1, 3, 7, 9], "benefici": 1, "workshop": [1, 2, 3, 7, 8, 9, 11, 12], "It": [1, 2, 3, 7, 8, 11, 12, 13, 14], "import": [1, 7, 8, 12, 13, 14], "explain": [1, 2, 3, 8, 12], "much": [1, 2, 7, 8, 9, 12, 14], "valu": 1, "individu": [1, 2], "wai": [1, 4, 5, 7, 8, 12, 14], "mani": [1, 2, 4, 5, 7, 8, 9, 12, 13, 14], "want": [1, 2, 4, 5, 7, 8, 11, 12, 14], "each": [1, 2, 3, 8, 9, 11, 12, 13, 14], "best": [1, 2, 4, 5, 7, 8, 13], "recent": [1, 8, 12], "below": [1, 2, 14], "http": [1, 3, 5, 14], "www": 1, "youtub": 1, "com": [1, 5, 14], "playlist": 1, "list": [1, 8], "plplblyhczjaahf89p": 1, "gcjexwc8cf": 1, "7nhx": 1, "regularli": 1, "so": [1, 2, 4, 9, 11, 12, 13, 14], "try": [1, 2, 4, 7, 8, 9, 12, 14], "appli": [1, 2, 3, 8, 9, 12, 13], "learnt": [1, 13], "howev": [1, 2, 4], "know": [1, 2, 3, 4, 5, 7, 8, 12, 13], "target": [1, 2, 8], "audienc": [1, 2, 4, 8, 14], "veri": [1, 2, 3, 8, 9, 12, 14], "adapt": [1, 2], "am": [1, 8], "still": [1, 2, 8, 9, 14], "work": [1, 4, 7, 8, 9, 11, 12, 14], "situat": [1, 2], "why": [1, 2, 9, 13, 14], "like": [1, 2, 7, 8, 9, 11, 12], "usual": [1, 2, 3, 4, 8, 14], "wider": 1, "rang": 1, "mix": 1, "background": [1, 8], "more": [1, 2, 3, 5, 7, 8, 9, 11, 12, 13, 14], "care": [1, 4], "pace": [1, 2], "time": [1, 2, 7, 8, 9, 12], "given": [1, 2, 3], "consider": 1, "spend": [1, 7], "quit": [1, 2], "lot": [1, 12], "materi": [1, 3, 5, 8, 13], "practis": [1, 2], "myself": 1, "particularli": 1, "note": [1, 2, 8, 12, 13], "just": [1, 8, 12, 14], "befor": [1, 2, 8, 9, 14], "thei": [1, 2, 3, 8, 9, 12, 14], "highlight": [1, 2, 11], "both": [1, 2, 11, 12], "prepar": [1, 2, 4, 5, 7, 12], "too": [1, 2, 7, 9, 12, 14], "advanc": [1, 2, 7, 12, 13], "think": [1, 2, 8, 12], "prevent": [1, 13], "If": [1, 8, 12, 13], "less": [1, 2, 8, 12, 13, 14], "compet": [1, 7], "practition": [1, 7], "classroom": [1, 2, 13], "can": [1, 2, 3, 4, 7, 8, 9, 11, 12, 13, 14], "easili": [1, 2], "copi": [1, 8, 12], "past": [1, 3, 9], "avoid": [1, 3, 8, 11, 14], "slow": [1, 2, 12], "down": [1, 2, 11, 12], "entir": [1, 2], "ideal": [1, 4], "d": 1, "give": [1, 3, 5, 7, 8, 11, 12, 14], "sever": [1, 3, 12], "anyon": [1, 2, 4], "its": [1, 2, 3, 7], "everybodi": [1, 2, 13], "someth": [1, 2, 7, 8, 12, 13], "from": [1, 2, 3, 5, 7, 8, 12, 13, 14], "love": [1, 3], "break": [1, 2, 12, 13, 14], "opportun": [1, 3, 8], "attende": 1, "research": [1, 2, 3, 8], "especi": [1, 2], "softwar": [1, 2, 7, 8, 13, 14], "write": [1, 3, 8, 11], "plan": [1, 3, 4, 8, 9, 12, 13, 14], "ha": [1, 2, 3, 4, 7, 8, 12, 14], "chang": [1, 2, 8, 9, 11], "bit": [1, 2, 8, 14], "sinc": [1, 3, 11, 14], "start": [1, 2, 3, 4, 5, 8, 9, 12, 13, 14], "In": [1, 2, 3, 4, 8, 9, 11, 12, 14], "begin": 1, "had": [1, 3, 8, 14], "blob": 1, "binari": 1, "larg": [1, 2, 12, 13, 14], "knowledg": [1, 3, 7, 8, 13], "experi": [1, 2, 3, 8, 12, 14], "convei": 1, "particip": [1, 3, 5, 8, 11, 13, 14], "With": [1, 12], "realiz": 1, "serial": [1, 8], "similar": [1, 2, 7, 12], "fashion": 1, "would": [1, 2, 3, 5, 7, 8, 11], "intend": [1, 2, 3], "send": [1, 14], "over": [1, 5, 8, 12, 14], "wire": 1, "stop": 1, "signal": [1, 9], "sum": 1, "re": [1, 8, 9], "transmiss": 1, "when": [1, 2, 8, 12, 14], "lectur": [1, 12, 14], "come": [1, 2, 8, 12, 14], "appreci": 1, "natur": 1, "period": [1, 9], "offer": 1, "rais": [1, 3, 14], "error": [1, 2], "appear": [1, 14], "type": [1, 2, 8, 12], "along": [1, 2, 8, 11, 12], "co": [1, 7], "good": [1, 2, 3, 4, 9, 11, 14], "broaden": 1, "specif": [1, 2, 3, 8], "inclin": 1, "wa": [1, 2, 3, 5, 8, 11, 14], "todai": 1, "guid": [1, 2, 7, 9, 12, 13, 14], "includ": [1, 2, 8, 11, 14], "me": 1, "well": [1, 2, 5, 7, 13, 14], "That": [1, 2], "mai": [1, 2, 5, 8, 9, 13], "sound": [1, 2], "self": [1, 13], "centric": 1, "fact": [1, 2, 9], "opposit": 1, "sensit": 1, "room": [1, 2, 8, 12, 13], "consciou": 1, "being": [1, 13], "better": [1, 3, 8, 9, 11, 12], "tool": [1, 2, 3, 5, 7, 8], "concept": [1, 2, 7, 12], "map": [1, 5], "learner": [1, 3, 7, 8, 12, 14], "persona": [1, 8], "though": [1, 3, 8], "develop": [1, 3, 5, 7, 8], "few": [1, 2, 8, 11, 12], "them": [1, 2, 3, 8, 11, 13, 14], "never": [1, 2, 8, 14], "leav": 1, "ani": [1, 2, 3, 8, 12, 13, 14], "behind": 1, "realli": [1, 8, 14], "don": [1, 2, 4, 5, 8, 9, 12, 13, 14], "see": [1, 2, 5, 8, 9, 14], "confus": [1, 13], "blank": 1, "face": 1, "At": 1, "same": [1, 2, 8, 11, 12, 14], "sometim": [1, 4], "about": [1, 2, 8, 9, 12, 13, 14], "bore": 1, "progress": [1, 8, 9], "slowli": [1, 2], "alwai": [1, 8, 12, 13], "difficult": [1, 2], "compromis": 1, "struggl": 1, "focu": [1, 2, 12], "make": [1, 2, 3, 4, 8, 9, 11, 12, 14], "intuit": 1, "sens": [1, 3], "Of": 1, "establish": [1, 2, 3], "connect": [1, 2], "thing": [1, 8, 9, 12, 13, 14], "saw": 1, "previou": 1, "where": [1, 2, 5, 8, 12], "x": [1, 8], "master": [1, 8, 9], "follow": [1, 2, 8, 11, 12, 13], "script": [1, 2, 3, 8], "after": [1, 2, 3], "becom": [1, 2, 3, 5, 7, 8, 12], "familiar": [1, 8, 14], "improvis": 1, "react": 1, "dynam": [1, 8], "e": [1, 2, 3], "g": 1, "detour": 1, "clearli": [1, 2, 3, 12, 13, 14], "often": [1, 2, 3, 9, 12], "code": [1, 2, 3, 8], "text": 1, "out": [1, 2, 3, 8, 9, 12, 14], "describ": [1, 2, 9], "slower": [1, 2, 14], "place": [1, 2, 14], "hopefulli": 1, "compens": 1, "A": [1, 2, 3, 4, 8, 9, 12], "convers": 1, "trainer": [1, 3, 13], "traine": 1, "engag": [1, 5], "For": [1, 2, 8, 9, 13], "reason": [1, 2, 14], "most": [1, 2, 4, 7, 8, 11, 12, 14], "finish": 1, "part": [1, 2, 4, 5, 12], "step": [1, 2, 12, 14], "back": [1, 2, 14], "might": [1, 2, 8], "bring": [1, 2, 12], "anoth": 1, "point": [1, 2, 8, 9, 11, 12], "throughout": 1, "answer": [1, 3, 8, 12, 13, 14], "yourself": [1, 12], "those": [1, 2], "seem": [1, 2], "open": [1, 3, 9, 13], "end": [1, 2, 5, 8, 12], "new": [1, 3, 4, 5, 8, 11, 12, 13, 14], "exampl": [1, 2, 3, 5, 7, 9, 12, 13], "person": [1, 2, 11, 12, 13], "last": 1, "analogi": [1, 2], "order": [1, 2, 11], "simplifi": [1, 2], "convolut": 1, "180": [1, 14], "degre": 1, "slide": [1, 13], "45": 1, "block": 1, "separ": [1, 12], "embrac": [1, 3], "interact": [1, 7, 12, 13, 14], "demo": [1, 2, 5, 12], "typo": 1, "goal": [1, 11], "spark": 1, "curios": 1, "novic": 1, "look": [1, 2, 9, 12], "experienc": [1, 8], "aha": 1, "did": [1, 2, 14], "could": [1, 2], "wonder": 1, "whether": [1, 2, 11], "becaus": [1, 2, 3, 8, 9, 14], "up": [1, 2, 3, 5, 7, 8, 11, 12, 13, 14], "browser": 1, "keep": [1, 2, 3, 12, 14], "expert": [1, 7, 14], "sign": [1, 2], "encourag": [1, 2, 4, 9, 13], "But": [1, 2, 12, 13], "rabbit": 1, "hole": 1, "onli": [1, 2, 3, 5, 7, 9, 11, 12, 14], "jargon": 1, "war": 1, "stori": 1, "profession": [1, 7], "perspect": 1, "busi": 1, "world": [1, 2], "relat": [1, 2, 5, 7, 13], "context": [1, 2, 8], "product": 1, "agil": 1, "hard": [1, 2], "clear": [1, 8, 12, 14], "than": [1, 2, 7, 8, 9, 12, 14], "unclear": 1, "simpl": [1, 2, 8, 14], "complic": 1, "almost": [1, 5, 12], "felt": 1, "got": 1, "repeat": [1, 2], "head": 1, "word": [1, 2, 8], "simpli": [1, 2], "easi": [1, 9, 12, 14], "home": 1, "": [1, 7, 8, 9, 11, 12, 13, 14], "success": [1, 4, 8], "issu": [1, 5, 8, 9], "pull": [1, 5, 9], "request": [1, 2, 4, 5, 9], "solv": [1, 2, 3, 8], "surpris": 1, "known": [1, 3, 4, 14], "precis": [1, 12], "next": [1, 3, 12, 14], "allow": [1, 2, 8, 12, 14], "skip": [1, 2], "distil": 1, "essenc": 1, "bullet": 1, "deviat": 1, "explicit": 1, "great": [1, 12, 13], "recommend": [1, 14], "tutori": [1, 13], "program": [1, 2, 3, 7, 8], "languag": [1, 3, 8], "feel": [1, 2, 9, 11], "overwhelm": [1, 14], "fast": [1, 2, 14], "thrown": 1, "somebodi": [1, 5, 9], "els": [1, 14], "who": [1, 3, 5, 8, 14], "detect": 1, "complement": 1, "interrupt": [1, 12], "flow": [1, 12], "mistak": 1, "mind": [1, 2, 8, 12], "forc": 1, "fun": [1, 14], "demystifi": 1, "onc": [1, 8, 14], "mysteri": 1, "anymor": [1, 14], "mean": 1, "futur": [1, 2, 3, 4, 7, 13], "real": [1, 2], "life": 1, "twist": 1, "humour": 1, "whenev": [1, 3], "possibl": [1, 2, 3, 4, 9, 12, 14], "outcom": [1, 2, 8, 13], "certain": [1, 14], "offens": 1, "diagram": 1, "spent": 1, "week": [1, 14], "creat": [1, 2, 5, 8], "three": [1, 2, 14], "four": 1, "sentenc": 1, "effort": [1, 2, 7, 13], "consid": [1, 8], "worthwhil": 1, "intent": 1, "achiev": [1, 2], "nitti": 1, "gritti": 1, "confid": [1, 2, 3], "case": [1, 2, 8], "gradual": [1, 7], "realis": 1, "hint": [1, 12], "perhap": [1, 13], "assum": [1, 2, 3, 7, 12], "commun": [1, 3, 8, 13, 14], "class": [1, 2, 12], "now": [1, 4, 5, 8, 9, 12], "rememb": [1, 2, 8], "observ": 1, "peopl": [1, 2, 3, 4, 5, 9, 12, 13, 14], "puzzl": 1, "while": [1, 2, 7, 12, 14], "obviou": [1, 12, 14], "believ": [1, 2], "helper": [1, 3, 4, 5, 7, 12, 13], "faster": [1, 12, 14], "sure": [1, 2, 12, 14], "sit": 1, "alon": [1, 7], "ve": [1, 7, 9, 14], "been": [1, 2, 7, 8, 14], "rare": 1, "teacher": [1, 2, 13], "tend": [1, 4], "mentorship": 1, "long": [1, 2, 12, 14], "ago": [1, 3, 8], "weren": 1, "combin": [1, 14], "done": [1, 2], "friend": 1, "independ": [1, 3, 7, 8, 13], "studi": [1, 2, 5], "correct": [1, 2], "job": [1, 2, 8], "support": [1, 3, 5, 8, 13], "comput": [1, 2, 3, 8, 13, 14], "infrastructur": [1, 3, 7], "ground": 1, "problem": [1, 2, 3, 8, 13, 14], "basic": [1, 5, 8, 12], "miss": [1, 2, 12, 14], "off": 1, "even": [1, 2, 8, 9], "should": [1, 2, 3, 5, 8, 9, 11, 12, 13, 14], "minim": [1, 12], "suffici": [1, 2, 3], "everyth": [1, 2, 12, 13, 14], "perfectli": 1, "technic": [1, 7, 8, 9], "twenti": 1, "year": [1, 2, 3, 8], "henc": 1, "toward": [1, 9], "hand": [1, 3, 7, 13, 14], "capabl": [1, 8], "team": [1, 4, 8, 12], "essenti": [1, 2, 9], "domain": [1, 2], "willing": [1, 3], "stuck": [1, 8, 12], "call": [1, 2, 5, 12], "ksa": 1, "attitud": 1, "impart": 1, "And": [1, 12, 13], "challeng": [1, 2], "student": [1, 3, 8, 12, 13, 14], "overcom": 1, "perceiv": 1, "limit": [1, 8, 12, 14], "humanist": 1, "python": [1, 5, 14], "virtualenv": 1, "cognit": 1, "return": 1, "There": [1, 2, 4, 5, 12], "compon": 1, "storytel": 1, "human": [1, 2], "neurolog": 1, "made": [1, 9, 14], "pai": 1, "attent": 1, "put": [1, 2, 8, 14], "account": [1, 11], "relev": [1, 2, 8], "narr": 1, "draw": 1, "creativ": 1, "handwrit": 1, "reckon": 1, "architectur": 1, "big": 1, "pictur": [1, 12], "invest": 1, "semant": 1, "tree": 1, "negoti": 2, "minimum": [2, 8, 14], "breakout": [2, 11, 13], "expect": [2, 8, 12, 14], "intro": [2, 5, 7, 14], "speed": [2, 3, 8], "Not": 2, "accomplish": [2, 12], "stuff": [2, 3], "wrong": 2, "depend": 2, "ok": 2, "cut": 2, "reserv": 2, "readi": [2, 8, 14], "run": [2, 4, 7, 8, 12], "environ": [2, 13], "match": [2, 12], "screen": [2, 8, 11, 13], "termin": 2, "histori": [2, 12], "portion": 2, "remot": [2, 8], "alreadi": [2, 3, 7, 8], "prerequisit": 2, "Or": 2, "instal": [2, 8], "configur": 2, "manag": [2, 14], "sad": 2, "special": [2, 14], "deliv": 2, "onlin": [2, 5, 7, 13], "organ": [2, 7, 9, 11], "deriv": [2, 3], "further": 2, "later": [2, 8, 11, 12, 14], "intructor": 2, "respect": 2, "inclus": [2, 13], "reli": 2, "conduct": 2, "improv": [2, 3, 8, 9, 11, 13, 14], "reinforc": 2, "daili": 2, "within": [2, 3], "15": [2, 3, 7, 8], "method": [2, 8], "bi": [2, 5], "direct": [2, 3], "To": [2, 14], "clarif": 2, "instanc": 2, "add": 2, "contrast": [2, 14], "judg": 2, "reach": [2, 4, 5], "accept": [2, 3, 14], "level": [2, 3, 8], "either": [2, 5, 7, 8], "pass": 2, "fail": [2, 14], "One": [2, 3, 12], "drive": 2, "exam": 2, "tell": 2, "rest": 2, "societi": 2, "someon": [2, 7, 12, 13], "safe": 2, "road": 2, "univers": [2, 3, 14], "assign": [2, 14], "grade": 2, "fanci": 2, "term": [2, 9], "activ": [2, 3], "refocu": 2, "respond": 2, "continu": [2, 14], "mechan": [2, 13, 14], "music": 2, "plai": 2, "scale": [2, 7, 8, 12], "breath": 2, "correctli": 2, "happen": 2, "frequent": 2, "ll": 2, "talk": [2, 9], "interpret": 2, "instrument": 2, "pre": [2, 7, 14], "post": [2, 3, 5], "poll": 2, "necessarili": 2, "multipl": [2, 12, 14], "initi": 2, "build": [2, 3, 8, 13], "exist": [2, 8], "uniqu": 2, "choos": [2, 8], "suitabl": 2, "accommod": 2, "everyon": [2, 5, 9], "posit": 2, "v": 2, "neg": 2, "content": [2, 5, 14], "rubric": [2, 11], "aim": [2, 3], "As": 2, "ax": 2, "2x2": 2, "grid": 2, "whiteboard": 2, "hackmd": [2, 13], "etherpad": 2, "googl": 2, "doc": 2, "without": [2, 4], "duplic": [2, 7, 9], "event": [2, 5], "4": [2, 11], "per": [2, 14], "facilit": 2, "Then": [2, 8, 14], "report": 2, "strongli": 2, "agre": 2, "disagre": 2, "first": [2, 8, 9, 14], "task": [2, 8, 11], "figur": [2, 8, 14], "patricia": 2, "benner": 2, "dreyfu": 2, "acquisit": [2, 8], "her": [2, 8], "nurs": 2, "book": [2, 7], "indic": 2, "formal": [2, 5], "acquir": 2, "distinct": [2, 8], "stage": 2, "doesn": [2, 12, 14], "yet": [2, 3, 4, 8], "idea": [2, 3, 5, 8, 9, 12], "aren": [2, 8], "heard": 2, "bash": 2, "shell": [2, 8, 11], "therefor": 2, "file": [2, 8], "system": [2, 8, 12, 14], "execut": 2, "headless": 2, "mode": [2, 14], "queue": 2, "directli": [2, 14], "login": [2, 8], "enough": [2, 12, 13, 14], "everydai": 2, "purpos": [2, 12], "won": [2, 8], "detail": 2, "accur": 2, "normal": [2, 14], "under": [2, 4, 9, 13, 14], "circumst": 2, "move": [2, 8], "around": [2, 14], "directori": 2, "fit": 2, "togeth": [2, 5, 7, 8, 12, 14], "autom": 2, "he": [2, 8], "she": [2, 8], "benefit": [2, 12, 14], "doe": [2, 3, 8, 14], "fulli": [2, 9], "project": [2, 5, 7, 8, 13], "cluster": [2, 8], "submit": [2, 3, 8], "optim": 2, "amount": [2, 7, 8], "resourc": [2, 8, 13], "setup": [2, 11, 12], "parallel": [2, 8], "handl": [2, 14], "ordinari": 2, "immedi": [2, 14], "process": [2, 5, 9], "goe": 2, "creation": 2, "found": 2, "collect": [2, 3, 8, 9, 12, 13], "relationship": 2, "resid": 2, "unit": 2, "state": [2, 12], "locat": 2, "major": [2, 3, 9, 13], "citi": 2, "landmark": 2, "weather": 2, "pattern": 2, "region": 2, "economi": 2, "demograph": 2, "among": 2, "compar": [2, 8, 12, 14], "countri": [2, 3, 14], "complex": [2, 8], "distinguish": 2, "built": 2, "guesswork": 2, "borrow": 2, "piec": 2, "superfici": 2, "averag": 2, "driver": 2, "car": 2, "probabl": [2, 3, 8, 9, 11], "engin": [2, 3], "concern": 2, "mixtur": 2, "hardli": 2, "ever": 2, "scratch": 2, "everi": [2, 9, 14], "opinion": 2, "true": 2, "articul": [2, 3], "prior": [2, 3], "belief": 2, "incomplet": 2, "inaccur": 2, "misconcept": 2, "imped": 2, "incorpor": 2, "broadli": 2, "speak": 2, "fall": [2, 11], "categori": 2, "factual": 2, "vancouv": 2, "capit": 2, "british": 2, "columbia": 2, "These": [2, 3], "easiest": 2, "broken": 2, "motion": 2, "acceler": 2, "must": [2, 8, 12], "address": [2, 3], "contradict": 2, "fundament": 2, "thousand": 2, "old": [2, 12, 14], "beings": 2, "cannot": [2, 8], "affect": [2, 13], "planet": 2, "climat": [2, 8], "deepli": 2, "social": 2, "ident": [2, 13], "hardest": 2, "current": [2, 7, 8], "procedur": 2, "inherit": 2, "lack": [2, 8], "depth": 2, "leaner": 2, "leasson": 2, "wiggin": 2, "mctigh": 2, "firmli": 2, "determin": 2, "decid": 2, "constitut": 2, "met": 2, "sort": 2, "increas": [2, 8, 14], "capentri": 2, "framework": 2, "discret": 2, "hierarch": 2, "gone": 2, "educ": [2, 8], "remain": 2, "particular": [2, 8], "hierarchi": 2, "valid": [2, 9], "masteri": 2, "bottom": 2, "meet": [2, 5, 14], "grow": 2, "recogn": 2, "growth": 2, "ahead": 2, "imag": 2, "credit": [2, 5, 9], "vanderbilt": 2, "center": 2, "review": [2, 9, 13], "carefulli": 2, "scan": 2, "promis": 2, "verifi": [2, 14], "anticip": 2, "nordic": [3, 7], "collabor": [3, 7, 8, 11, 12, 13], "neic": 3, "octob": 3, "2016": 3, "fund": [3, 5], "until": [3, 12], "2021": [3, 5], "hope": 3, "beyond": 3, "network": [3, 5, 7, 8, 13, 14], "contributor": [3, 5, 9], "grew": 3, "sese": 3, "kth": 3, "stockholm": 3, "2014": 3, "nu": 3, "scientif": [3, 13, 14], "toolbox": 3, "propos": 3, "2015": 3, "port": 3, "format": [3, 5, 11, 13], "iter": 3, "maintain": [3, 9, 14], "disciplin": 3, "tri": [3, 8], "repositori": [3, 14], "host": [3, 4, 13, 14], "servic": [3, 5], "free": 3, "institut": [3, 4, 5, 8, 14], "implement": [3, 9], "sustain": [3, 5], "measur": 3, "3": [3, 8, 14], "6": [3, 8, 14], "month": [3, 8], "overal": 3, "qualiti": [3, 8], "reusabl": 3, "modular": 3, "reproduc": [3, 5], "easier": [3, 12], "colleagu": [3, 8, 14], "usag": 3, "adopt": [3, 7], "suggest": [3, 8, 9], "effect": [3, 8, 12], "common": [3, 9], "theme": 3, "wish": 3, "grad": 3, "10": [3, 5, 7, 14], "quantifi": 3, "convinc": 3, "partner": [3, 5], "novemb": 3, "2018": 3, "platinum": 3, "intern": 3, "compris": 3, "data": [3, 8], "mission": 3, "foundat": 3, "worldwid": 3, "complementari": 3, "access": [3, 8, 9, 14], "fee": 3, "cover": 3, "travel": [3, 4], "seat": 3, "partnership": 3, "lead": [3, 13], "transfer": 3, "local": [3, 8, 14], "theoret": 3, "gener": [3, 7, 13], "favor": 3, "awar": 3, "By": 3, "qualifi": 3, "typic": [3, 5, 8, 11, 14], "version": [3, 5, 7, 9], "control": [3, 5, 7, 9, 13], "git": [3, 7, 9], "high": [3, 8], "conceptu": 3, "jupyt": 3, "etc": [3, 8, 14], "difficulti": [3, 9, 12], "workflow": 3, "defin": [3, 8, 13, 14], "produc": [3, 12], "ship": 3, "histor": 4, "were": [4, 14], "transit": 4, "advertis": [4, 14], "licens": 4, "cc": 4, "BY": 4, "staff": 4, "low": [4, 13], "pretti": 4, "site": 4, "core": [4, 8], "exactli": 4, "modern": 5, "30": [5, 7, 8], "1000": 5, "github": [5, 9, 13, 14], "io": 5, "2020": [5, 14], "20": [5, 7, 14], "schedul": [5, 8], "org": 5, "membership": 5, "hpc": [5, 8], "nov": 5, "dec": 5, "confer": 5, "weekli": 5, "aaltoscicomp": 5, "scicomp": 5, "contribut": [5, 7, 13], "constel": 5, "reus": 5, "hub": 5, "chat": [5, 12, 14], "shape": 5, "zulipchat": 5, "visibl": 5, "promot": 5, "member": 5, "non": [5, 8], "profit": 5, "sell": 5, "scalabl": 5, "market": 5, "hour": 5, "twitch": [5, 14], "stream": 5, "soon": [5, 13], "via": [5, 8, 14], "debrief": 5, "manual": [5, 7, 8, 12, 13], "focus": [7, 9, 12, 14], "serv": [7, 14], "kickstart": 7, "pathwai": 7, "strict": 7, "necessari": 7, "design": [7, 9, 11, 13, 14], "applic": 7, "60": 7, "min": 7, "welcom": 7, "introduct": [7, 8, 9, 12, 14], "25": 7, "100": [7, 14], "quick": [7, 8, 9, 14], "comprehens": 7, "join": [7, 8, 14], "specialist": 7, "frustrat": 7, "thu": 7, "reduc": [7, 8, 12, 14], "full": 7, "taken": 7, "advantag": [7, 9, 12, 14], "itself": 7, "intens": 7, "curriculum": [7, 8], "handbook": [7, 8], "tech": [7, 8, 12], "involv": 7, "organiz": [7, 9], "summari": 8, "ten": 8, "tip": [8, 12], "ye": 8, "number": [8, 12, 13, 14], "cool": 8, "press": 8, "90": [8, 14], "instead": [8, 9, 12, 13, 14], "expos": 8, "technologi": 8, "prefer": [8, 11], "divers": [8, 13, 14], "bias": 8, "clarifi": 8, "concret": 8, "potenti": 8, "analyz": 8, "evalu": [8, 11], "sequenc": 8, "test": 8, "increment": 8, "gap": 8, "whole": [8, 9, 12, 14], "briefli": 8, "semi": 8, "rigid": 8, "save": [8, 12], "draft": [8, 9], "perfect": [8, 9], "strive": 8, "ad": 8, "hoc": 8, "twofold": 8, "assess": 8, "nice": 8, "cost": 8, "n": [8, 14], "let": [8, 12, 13], "phd": 8, "postdoc": 8, "young": 8, "proper": 8, "definit": 8, "avail": [8, 12, 13, 14], "paradigm": 8, "multi": [8, 14], "thread": [8, 12], "box": [8, 13], "multiprocess": 8, "gpu": 8, "dataset": 8, "larger": [8, 9], "memori": 8, "strategi": [8, 12], "sonya": 8, "1st": 8, "oslo": 8, "neurosci": 8, "nest": 8, "simul": 8, "spike": 8, "neural": 8, "model": [8, 13], "thesi": 8, "small": [8, 12], "excit": 8, "robert": 8, "field": [8, 14], "ecologist": 8, "obtain": 8, "hi": 8, "scientist": 8, "consequ": 8, "global": 8, "command": 8, "line": 8, "terrifi": 8, "extens": [8, 9], "rather": 8, "jessica": 8, "investig": 8, "numer": 8, "aris": 8, "fluid": 8, "driven": 8, "ruptur": 8, "finit": 8, "element": 8, "compress": 8, "navier": 8, "stoke": 8, "equat": 8, "mesh": 8, "librari": 8, "mostli": [8, 14], "ran": 8, "desktop": 8, "due": 8, "keen": 8, "machin": 8, "notion": 8, "node": 8, "distribut": [8, 11], "optimis": 8, "o": 8, "filesystem": 8, "oper": 8, "meant": 8, "cpu": 8, "laptop": 8, "output": 8, "gromac": 8, "segment": [8, 11], "logic": 8, "pick": [8, 11], "regular": 8, "express": 8, "latex": 8, "favorit": 8, "linux": 8, "paint": 8, "perform": [8, 11], "therein": 8, "unix": 8, "jekyl": 9, "submodul": 9, "sphinx": 9, "freeli": [9, 13], "decentr": 9, "namespac": 9, "forkabl": 9, "anybodi": 9, "longer": 9, "backward": 9, "comment": [9, 12, 13], "afraid": 9, "noth": 9, "imperfect": 9, "earli": 9, "solidifi": 9, "isol": 9, "unfinish": 9, "wip": 9, "merg": 9, "gitlab": 9, "singl": 9, "fix": 9, "thorough": 9, "hackathon": 9, "revis": 9, "checklist": 9, "convert": 9, "lost": 9, "citabl": 9, "doi": 9, "commit": 9, "accompani": 9, "again": 9, "branch": 9, "substanti": 9, "rewrit": 9, "demonstr": [11, 14], "second": 11, "bad": [11, 12, 14], "50": 11, "listen": [11, 12], "verbal": 11, "conclus": 11, "round": 11, "receiv": 11, "trial": [11, 12], "came": 11, "art": 11, "pitfal": 11, "sooner": 11, "close": [11, 12], "disadvantag": [12, 14], "mainli": 12, "distract": 12, "unnecessari": 12, "weird": 12, "possibli": [12, 14], "harder": [12, 14], "rewind": 12, "catch": 12, "orient": 12, "properti": 12, "font": [12, 13], "window": 12, "instruct": [12, 14], "whatev": 12, "layout": 12, "wors": 12, "s1": 12, "s2": 12, "s3": 12, "s4": 12, "smaller": [12, 13], "anyth": 12, "constrict": 12, "vertic": 12, "half": 12, "displai": 12, "side": 12, "zoom": [12, 13], "option": 12, "commentari": 12, "pressur": 12, "forget": 12, "coordin": [12, 14], "unfamiliar": 12, "repli": [12, 14], "anonym": [12, 14], "overload": 12, "warn": 12, "turn": 12, "quiet": [12, 14], "tomorrow": 12, "manula": 12, "five": [12, 14], "prep": [12, 14], "sai": 13, "remix": 13, "catalyz": 13, "luci": 13, "whallei": 13, "gave": 13, "stack": 13, "overflow": 13, "bank": 13, "impress": 13, "signpost": 13, "link": 13, "impost": 13, "syndrom": 13, "disproportion": 13, "repres": 13, "manifest": 13, "Be": [13, 14], "kind": [13, 14], "suffer": 13, "silent": 13, "littl": [13, 14], "volum": 13, "size": [13, 14], "plane": 13, "pdf": 13, "role": 13, "board": 13, "recruit": [13, 14], "registr": [13, 14], "outro": 13, "templat": [13, 14], "protect": 13, "primari": 14, "condens": 14, "total": 14, "250": 14, "regist": 14, "max": 14, "didn": 14, "select": 14, "webpag": 14, "march": 14, "went": 14, "toler": 14, "ethic": 14, "featur": 14, "static": 14, "across": 14, "contain": 14, "greatli": 14, "updat": 14, "power": 14, "email": 14, "name": 14, "themselv": 14, "firstnam": 14, "lastnam": 14, "h": 14, "guarante": 14, "former": 14, "stress": 14, "overlap": 14, "actual": 14, "dedic": 14, "quickli": 14, "spare": 14, "rotat": 14, "shouldn": 14, "abov": 14, "wen": 14, "written": 14, "view": 14, "edit": 14, "voic": 14, "anywai": 14, "lose": 14, "privaci": 14, "loss": 14, "tv": 14, "40": 14, "viewer": 14, "extra": 14, "archiv": 14, "14": 14, "instant": 14, "hundr": 14, "streamer": 14, "spotlight": 14, "galleri": 14, "dual": 14, "monitor": 14, "emphas": 14, "verif": 14, "haven": 14, "stai": 14, "log": 14, "whelm": 14, "ourselv": 14, "techniquess": 14, "aalto": 14, "announc": 14, "rapid": 14, "shortli": 14, "physic": 14, "pure": 14}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"pre": 0, "workshop": [0, 4, 5, 13, 14], "prepar": [0, 14], "you": [0, 8], "don": 0, "t": 0, "have": [0, 8], "carpentri": [0, 2, 3], "instructor": [0, 2, 5, 6, 7, 11, 13], "befor": 0, "take": 0, "ca": 0, "1": [0, 11], "hour": 0, "remark": 0, "coderefineri": [1, 2, 3, 4, 5, 7, 14], "teach": [1, 2, 9, 11, 12, 14], "philosophi": 1, "ic": 1, "breaker": 1, "group": 1, "20": 1, "minut": 1, "video": 1, "record": [1, 14], "ann": 1, "fouilloux": 1, "bj\u00f8rn": 1, "lindi": 1, "thor": 1, "wikfeldt": 1, "stefan": 1, "negru": 1, "radovan": 1, "bast": 1, "sabri": 1, "razick": 1, "juho": 1, "lehtonen": 1, "richard": 1, "darst": 1, "jo\u00e3o": 1, "m": 1, "da": 1, "silva": 1, "interact": 2, "style": 2, "what": [2, 5, 12, 13], "ar": 2, "top": 2, "issu": 2, "new": [2, 9], "face": 2, "solut": 2, "The": [2, 7, 8], "approach": [2, 8], "thi": [2, 5, 13], "materi": [2, 9], "kei": 2, "principl": 2, "On": 2, "import": 2, "feedback": [2, 11], "get": [2, 5, 13], "give": [2, 13], "learner": 2, "progress": 2, "summ": 2, "assess": 2, "form": 2, "option": [2, 11], "10": 2, "mn": 2, "who": [2, 7], "novic": [2, 3], "compet": [2, 3], "practition": [2, 3], "expert": 2, "cognit": 2, "develop": [2, 9], "mental": 2, "model": 2, "how": [2, 5, 8, 12], "knowledg": 2, "wai": 2, "exercis": [2, 8, 11], "identifi": 2, "profil": 2, "curriculum": 2, "revers": 2, "instruct": 2, "design": [2, 8], "recommend": [2, 8, 9], "hpc": [2, 14], "work": 2, "learn": [2, 9], "object": [2, 12], "us": 2, "bloom": 2, "": [2, 6], "taxonomi": 2, "write": 2, "effect": 2, "revisit": 2, "about": [3, 7], "project": 3, "histori": 3, "main": [3, 11], "goal": [3, 8, 13], "impact": 3, "membership": 3, "target": 3, "audienc": 3, "best": 3, "softwar": [3, 5], "practic": [3, 8, 11, 12], "whom": 3, "organ": 4, "central": 4, "local": 4, "invit": 4, "independ": 4, "futur": 5, "activ": 5, "i": [5, 7, 8], "nordic": 5, "rse": 5, "research": 5, "engin": 5, "collabor": [5, 9, 14], "involv": 5, "biggest": 5, "open": 5, "problem": 5, "certif": 5, "guid": 6, "train": [7, 13, 14], "prerequisit": 7, "lesson": [7, 8, 9, 13], "refer": [7, 10], "cours": 7, "see": [7, 12], "also": [7, 12], "read": 8, "do": [8, 13], "discuss": [8, 9, 11, 12, 14], "backward": 8, "process": 8, "why": [8, 12], "good": [8, 12], "here": 8, "provid": 8, "exampl": [8, 11], "demo": [8, 11], "templat": 9, "static": 9, "site": 9, "creat": 9, "contribut": 9, "exist": 9, "quick": 10, "part": 11, "2": 11, "room": [11, 14], "two": 11, "live": 11, "code": [11, 13], "onlin": [12, 14], "mechan": 12, "matter": 12, "shell": 12, "share": 12, "goe": 12, "demonstr": 12, "screen": 12, "hackmd": [12, 14], "prototyp": 12, "meta": 12, "talk": 12, "question": 12, "welcom": 13, "introduct": 13, "we": 13, "want": 13, "out": 13, "confid": 13, "tool": 13, "conduct": 13, "overview": 13, "typic": 13, "differ": 13, "manual": 14, "run": 14, "v": 14, "person": 14, "case": 14, "studi": 14, "mega": 14, "finland": 14, "kickstart": 14, "gener": 14, "arrang": 14, "link": 14, "scale": 14, "strategi": 14, "basic": 14, "platform": 14, "zoom": 14, "breakout": 14, "bring": 14, "your": 14, "own": 14, "team": 14, "helper": 14, "staff": 14, "role": 14, "stream": 14, "instal": 14, "time": 14, "other": 14, "note": 14}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 8, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 57}, "alltitles": {"Pre-workshop preparation": [[0, "pre-workshop-preparation"]], "You don\u2019t have to be a Carpentries instructor": [[0, "you-don-t-have-to-be-a-carpentries-instructor"]], "Preparation before the workshop (takes ca. 1 hour)": [[0, "prerequisites-0"]], "Remark": [[0, "callout-0"]], "CodeRefinery teaching philosophies": [[1, "coderefinery-teaching-philosophies"]], "Ice-breaker in groups (20 minutes)": [[1, "exercise-0"]], "Video recordings": [[1, "prerequisites-0"]], "Anne Fouilloux": [[1, "exercise-1"]], "Bj\u00f8rn Lindi": [[1, "exercise-2"]], "Thor Wikfeldt": [[1, "exercise-3"]], "Stefan Negru": [[1, "exercise-4"]], "Radovan Bast": [[1, "exercise-5"]], "Sabry Razick": [[1, "exercise-6"]], "Juho Lehtonen": [[1, "exercise-7"]], "Richard Darst": [[1, "exercise-8"]], "Jo\u00e3o M. da Silva": [[1, "exercise-9"]], "Interactive teaching style": [[2, "interactive-teaching-style"]], "What are the top issues new instructors face?": [[2, "what-are-the-top-issues-new-instructors-face"]], "Solution": [[2, "solution-0"]], "The Carpentries and CodeRefinery approaches to teaching": [[2, "the-carpentries-and-coderefinery-approaches-to-teaching"]], "This material": [[2, "callout-0"]], "Key principles": [[2, "key-principles"]], "Carpentries teaching principles": [[2, "carpentries-teaching-principles"]], "On the importance of feedback": [[2, "on-the-importance-of-feedback"]], "Getting/giving feedback on learners\u2019 progress": [[2, "getting-giving-feedback-on-learners-progress"]], "Summative Assessment": [[2, "callout-1"]], "Formative assessment": [[2, "callout-2"]], "Getting/giving feedback on teaching": [[2, "getting-giving-feedback-on-teaching"]], "Give feedback on teaching (optional, 10 mn)": [[2, "exercise-0"]], "Who are the learners": [[2, "who-are-the-learners"]], "Novices, competent practitioners and experts": [[2, "novices-competent-practitioners-and-experts"]], "Cognitive Development and Mental Models": [[2, "cognitive-development-and-mental-models"]], "How \u201cknowledge\u201d gets in the way": [[2, "how-knowledge-gets-in-the-way"]], "Exercise: How to identify learner profiles?": [[2, "exercise-1"]], "CodeRefinery Curriculum and Reverse Instructional Design (with recommendations for HPC carpentries)": [[2, "coderefinery-curriculum-and-reverse-instructional-design-with-recommendations-for-hpc-carpentries"]], "Working with learning objectives": [[2, "working-with-learning-objectives"]], "Using Bloom\u2019s Taxonomy to write effective learning objectives": [[2, "using-bloom-s-taxonomy-to-write-effective-learning-objectives"]], "Revisiting Learning objectives": [[2, "revisiting-learning-objectives"]], "About the CodeRefinery project": [[3, "about-the-coderefinery-project"]], "History": [[3, "discussion-0"]], "Main goals": [[3, "main-goals"]], "Impact": [[3, "impact"]], "Carpentries membership": [[3, "carpentries-membership"]], "Target audience": [[3, "target-audience"]], "Carpentries audience": [[3, "carpentries-audience"]], "Novices": [[3, "callout-0"]], "CodeRefinery audience": [[3, "coderefinery-audience"]], "Competent practitioners": [[3, "callout-1"]], "Best software practices for whom?": [[3, "callout-2"]], "Organize a CodeRefinery workshop": [[4, "organize-a-coderefinery-workshop"]], "Centrally organized workshops": [[4, "centrally-organized-workshops"]], "Locally invited workshops": [[4, "locally-invited-workshops"]], "Independently organized workshops": [[4, "independently-organized-workshops"]], "Future": [[5, "future"]], "Activities": [[5, "activities"]], "What is CodeRefinery?": [[5, "what-is-coderefinery"]], "This workshop": [[5, "this-workshop"]], "Nordic-RSE (research software engineers)": [[5, "nordic-rse-research-software-engineers"]], "Collaborative workshops": [[5, "collaborative-workshops"]], "How to get involved in CodeRefinery": [[5, "how-to-get-involved-in-coderefinery"]], "Biggest open problems": [[5, "biggest-open-problems"]], "Certification for CodeRefinery instructors": [[5, "certification-for-coderefinery-instructors"]], "Instructor\u2019s guide": [[6, "instructor-s-guide"]], "CodeRefinery instructor training": [[7, "coderefinery-instructor-training"]], "Prerequisites": [[7, "prerequisites-0"]], "The lesson": [[7, null]], "Reference": [[7, null]], "Who is the course for?": [[7, "who-is-the-course-for"]], "About the course": [[7, "about-the-course"]], "See also": [[7, "see-also"], [12, "see-also"]], "Lesson design": [[8, "lesson-design"]], "Recommended reading": [[8, "prerequisites-0"]], "How do you design?": [[8, "how-do-you-design"]], "Discussion": [[8, "discussion-0"], [9, "discussion-0"], [9, "discussion-1"], [9, "discussion-2"], [11, "discussion"], [12, "discussion-1"], [12, "discussion-2"]], "Backwards lesson design": [[8, "backwards-lesson-design"]], "The approach": [[8, "the-approach"]], "The process": [[8, "the-process"]], "Why is it good to have a process?:": [[8, "why-is-it-good-to-have-a-process"]], "Designing exercises": [[8, "designing-exercises"]], "Practice backwards design": [[8, "practice-backwards-design"]], "The goal here is to discuss and provide examples on backwards-design of a lesson.": [[8, "discussion-1"]], "Demo": [[8, "exercise-0"]], "Exercise": [[8, "exercise-1"], [11, "exercise-0"], [11, "exercise-1"], [11, "exercise-2"]], "Collaborative lesson development": [[9, "collaborative-lesson-development"]], "Lesson templates for static sites": [[9, "lesson-templates-for-static-sites"]], "Creating new teaching material": [[9, "creating-new-teaching-material"]], "Contributing to existing lessons": [[9, "contributing-to-existing-lessons"]], "Recommendations and lessons learned": [[9, "recommendations-and-lessons-learned"]], "Quick Reference": [[10, "quick-reference"]], "Teaching practice and feedback": [[11, "teaching-practice-and-feedback"]], "Instructor demo": [[11, "instructor-demo"]], "Teaching demos part 1": [[11, "teaching-demos-part-1"]], "Teaching demos, part 2": [[11, "teaching-demos-part-2"]], "Main room discussion": [[11, "discussion-0"]], "Optional: feedback for two live-coding examples": [[11, "optional-feedback-for-two-live-coding-examples"]], "How to teach online": [[12, "how-to-teach-online"]], "Objectives": [[12, "objectives-0"]], "Why teaching mechanics matter": [[12, "why-teaching-mechanics-matter"]], "Shell sharing": [[12, "shell-sharing"]], "Discussion: what goes into a good shell share or demonstration?": [[12, "discussion-0"]], "Screen sharing": [[12, "screen-sharing"]], "HackMD prototype": [[12, "output-0"]], "Meta-talk": [[12, "meta-talk"]], "Teach teaching": [[12, "teach-teaching"]], "Questions": [[12, "questions"]], "Teaching practice": [[12, "teaching-practice"]], "Welcome and introduction": [[13, "welcome-and-introduction"]], "What do we want to get out of this workshop": [[13, "discussion-0"]], "Goals for this workshop": [[13, "goals-for-this-workshop"]], "Goals for this instructor training": [[13, "discussion-1"]], "Giving confidence": [[13, "giving-confidence"]], "Tools for this workshop": [[13, "tools-for-this-workshop"]], "Code of Conduct": [[13, "code-of-conduct"]], "Overview of the lessons and a typical workshop": [[13, "overview-of-the-lessons-and-a-typical-workshop"]], "What we do differently?": [[13, "discussion-2"]], "Workshop manuals": [[14, "callout-0"]], "Running a workshop: online": [[14, "running-a-workshop-online"]], "Online teaching discussion": [[14, "online-teaching-discussion"]], "Discussion: Online vs in-person": [[14, "discussion-0"]], "Case study: Mega-CodeRefinery and Finland HPC Kickstart": [[14, "case-study-mega-coderefinery-and-finland-hpc-kickstart"]], "General workshop arrangements": [[14, "general-workshop-arrangements"]], "Manuals link": [[14, "callout-1"]], "CodeRefinery online scaling strategy": [[14, "coderefinery-online-scaling-strategy"]], "Basic preparation": [[14, "basic-preparation"]], "Basic platform: Zoom": [[14, "basic-platform-zoom"]], "Breakout rooms, bring your own team": [[14, "breakout-rooms-bring-your-own-team"]], "Helper training": [[14, "helper-training"]], "Staff roles": [[14, "staff-roles"]], "HackMD": [[14, "hackmd"]], "Recording and streaming": [[14, "recording-and-streaming"]], "Installation time": [[14, "installation-time"]], "Other notes": [[14, "other-notes"]], "Workshop collaborations": [[14, "workshop-collaborations"]]}, "indexentries": {}}) \ No newline at end of file diff --git a/branch/instructor-training/teaching-practice/index.html b/branch/instructor-training/teaching-practice/index.html new file mode 100644 index 0000000..544838d --- /dev/null +++ b/branch/instructor-training/teaching-practice/index.html @@ -0,0 +1,235 @@ + + + + + + + Teaching practice and feedback — CodeRefinery instructor training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Teaching practice and feedback

+

Goals of the teaching practice:

+
    +
  • In groups of 4-5 persons we will practice teaching a 5-minute segment +of a lesson of your choice.

  • +
  • The section you pick should require screen sharing and be of some +demonstration or follow-along task (preferably using a shell) to also +practice having a good screen-sharing setup.

  • +
  • We will practice giving constructive feedback.

  • +
  • We will practice improving our 5-minute segment by taking the feedback into account.

  • +
  • In both session you can teach the same topic/segment but if you prefer you can also +change the topic/aspect for the second session.

  • +
+
+
+

Instructor demo

+
    +
  • In order to demonstrate the goals of this section, the instructor +will make a 5-minute demo for your evaluation.

  • +
  • It is designed to include some good and bad practices for you to +notice.

  • +
+
+
+
+

Teaching demos part 1

+

In group rooms, 50 minutes.

+
+

Exercise

+
    +
  • We organize the breakout rooms to not only discuss one lesson/topic so that it is more interesting +to listen and also probably we will all get more useful feedback.

  • +
  • Give each other constructive verbal feedback on the teaching demos, for example +using this demo rubric.

  • +
  • Write down questions (in the collaborative document) that you would like to +discuss in the main room or interesting conclusions which you would like to +share with others.

  • +
+
+
+
+

Teaching demos, part 2

+

In group rooms, 50 minutes.

+
+

Exercise

+
    +
  • In the second round we distribute the rooms differently so that you can +present it to a new group of workshop participants and can receive new +feedback.

  • +
  • Ask for feedback and one/few point(s) you want to improve.

  • +
  • In your second trial check whether you feel the demonstration improved.

  • +
  • Share your lessons learned in the collaborative document.

  • +
  • Give us also feedback on this exercise format. Was it useful? What can we improve?

  • +
+
+
+
+
+

Discussion

+
+

Main room discussion

+
    +
  • We discuss questions and conclusions which came up during the group work session.

  • +
+
+
+
+
+

Optional: feedback for two live-coding examples

+
+

Exercise

+

Teaching by live coding is a +performance art which requires practice. +This exercise highlights some typical pitfalls that most instructors +fall into sooner or later, and also shows how to avoid them. +Watch closely since we will be giving feedback!

+
    +
  • Watch these two videos: video 1 and +video 2

  • +
  • What was better in video 1 and what was better in video 2?

  • +
  • Please give feedback in the shared workshop document.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/instructor-training/teaching-strategies/index.html b/branch/instructor-training/teaching-strategies/index.html new file mode 100644 index 0000000..c939470 --- /dev/null +++ b/branch/instructor-training/teaching-strategies/index.html @@ -0,0 +1,383 @@ + + + + + + + How to teach online — CodeRefinery instructor training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

How to teach online

+
+

Objectives

+
    +
  • Understand the benefits and disadvantage of online teaching, +compared to in-person

  • +
  • Set up a good screen share

  • +
  • Understand the benefits and disadvantages of team teaching

  • +
  • Prepare for the teaching practice

  • +
+
+
+

Why teaching mechanics matter

+
    +
  • When you teach, you are mainly showing a basic example for the +learner to follow along

  • +
  • The learner has a lot more to think about than you do, so you need +to minimize the possible distractions and unnecessary weirdness.

  • +
  • A learner will often only one small screen, limiting the number of +things that they can think about.

  • +
  • You are must faster than learners (5 times possibly?) You have to +do things to slow yourself down.

  • +
  • It’s easy to save these mechanics until the end, and then you run +out of time.

  • +
+
+
+

Shell sharing

+ +

When doing any demonstration, there are difficulties:

+
    +
  • If one misses something, you can’t rewind to see it - is there any +way to catch up?

  • +
  • The learner must get oriented with the whole picture, while +instructor knows precisely where to focus.

  • +
+

A good shell share has some of the following properties:

+
    +
  • Large font

  • +
  • Shell history, available separately from the main shell window

  • +
  • Closely matches the type-along instructions

  • +
+

We have a collection of shell sharing systems:

+ +
+

Discussion

+

The instructor will demonstrate several shell-sharing systems. You +will use this in the teaching practice.

+
+
+
+

Screen sharing

+
+

Discussion

+

Look at the various screen layouts in the CodeRefinery +manuals. +Use the HackMD to comment about what which are better or worse.

+ +
+
    +
  • Many learners will have a smaller screen than you.

  • +
  • You should plan for learners with only one small screen.

  • +
  • A learner will need to focus on both your screen share and their +work.

  • +
  • Sharing your a whole screen is almost always a bad idea, if you want +the learners to do anything at the same time.

  • +
  • If you constrict yourself, then your experience is more similar to +that of a learner.

  • +
+

Vertical sharing:

+
    +
  • CodeRefinery has recently started trialing a vertical share +system, where you share a vertical half of your screen.

  • +
  • This allows learners with one screen to display your screen +side-by-side with their learn

  • +
  • Zoom provides a “Share a part of screen” that is good for this.

  • +
+
+
+

Meta-talk

+

Don’t just teach, also make sure you guide the learners through the +course.

+
    +
  • You know what you just discussed, and what is coming next, but +learners are often stuck thinking about now.

  • +
  • Give a lot of “meta-talk” that is not just about the topic you are +teaching, but how you are teaching it.

  • +
  • Examples

    +
      +
    • Why you are doing each episode

    • +
    • What is the purpose of each exercise

    • +
    • Clearly state what someone should accomplish in each exercise and +how long it will take - don’t assume this is obvious.

    • +
    • What is the point of each lesson. How much should people expect +to get from it? Should you follow everything, or are some things +advanced and optional? Make that clear.

    • +
    +
  • +
+
+
+

Teach teaching

+
    +
  • Demonstration-based teaching require two different types of focus:

    +
      +
    • Doing the mechanical steps as a demonstration

    • +
    • Explaining why you are doing it

    • +
    +
  • +
  • This is a lot for one person to keep in mind, so can multiple people +work together for this?

  • +
  • Team teaching idea:

    +
      +
    • One person is doing the demonstrations

    • +
    • One person is giving the commentary about what they are doing

    • +
    • The lecture becomes a discussion between two people instead.

    • +
    +
  • +
+

Advantages:

+
    +
  • This reduces the pressure on each person (reduces demo effect)

  • +
  • You are less likely to forget things

  • +
  • It slows you down in teaching

  • +
  • It makes the lesson more interesting to listen to

  • +
  • One person can follow questions

  • +
  • Great for introducing new instructors (which half is easier to start +with?)

  • +
+

Disadvantage:

+
    +
  • Requires two people’s time

  • +
  • Requires coordination when preparing (slows you down in preparation)

  • +
  • Unfamiliar concept to most people

  • +
+
+
+

Questions

+
    +
  • Questions are great, and important for any practical and interactive +class

  • +
  • But questions in main room doesn’t scale to very large rooms.

  • +
  • CodeRefinery strategy: HackMD for questions

    +
      +
    • Chat is not good enough, you can’t reply to old things

    • +
    • HackMD allows threaded replies and follow up later

    • +
    • You need some other helpers to watch HackMD and answer, and bring +things up to you. And let you know how things are going.

    • +
    • Learners can ask anonymously

    • +
    • Learners don’t have to worry about interrupting the flow.

    • +
    • Disadvantage: can produce information overload, warn people to not +follow too closely

    • +
    • With too few people, it can turn out to be very quiet.

    • +
    +
  • +
  • We will learn more about HackMD questions tomorrow in +Running a workshop: online.

  • +
+
+

See also

+ +
+
+
+

Teaching practice

+

In Teaching practice and feedback, you will break into groups and try to +apply these strategies to a five-minute example session.

+
+
+

See also

+

In this lesson:

+ +

CodeRefinery manuals:

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/instructor-training/welcome/index.html b/branch/instructor-training/welcome/index.html new file mode 100644 index 0000000..aebb38a --- /dev/null +++ b/branch/instructor-training/welcome/index.html @@ -0,0 +1,258 @@ + + + + + + + Welcome and introduction — CodeRefinery instructor training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Welcome and introduction

+
+

What do we want to get out of this workshop

+
    +
  • Introduction of instructors and helpers

  • +
  • Each instructor can say what we want to get out of the instructor training

  • +
  • But we want to know from everybody and collect these in the live notes

  • +
+
+
+
+

Goals for this workshop

+
+

Goals for this instructor training

+
    +
  • Give future instructors the tools and confidence to teach best software practices and tools.

  • +
  • Motivate new instructors to take up lessons, remix them, and to contribute.

  • +
  • Get feedback to improve the material as well as our collaboration model.

  • +
  • For us to learn how we can support related efforts and collaborate.

  • +
  • Catalyze and form new networks and collaborations of teachers and trainers of +practical scientific computing.

  • +
+
+
+

Giving confidence

+
+

Goal number one should be that we give participants the confidence to +independently apply the tools or knowledge learnt. This is more important +that giving a “complete” overview. [Lucy Whalley gave this great comment at one of our workshops]

+
+
    +
  • You don’t have to know everything to use (or teach) something.

  • +
  • For the large majority of topics we teach, there are many resources online +which provide how-to guides or tutorials. And the Stack Overflow answer bank +isn’t getting any smaller. So we need to ask why do people attend in-person +sessions if there is information freely available? Our impression is that +it is for confidence building, identity formation, perhaps signposting to +resources.

  • +
  • This also links with building a welcoming/inclusive environment: for example, +imposter syndrome, which disproportionately affects under-represented groups +(link), +can manifest as low self-confidence –> building the confidence of +students in the classroom may lead to a more diverse community.

  • +
+
+
+
+
+

Tools for this workshop

+

We always start workshops with these:

+ +
+
+
+

Code of Conduct

+
    +
  • We follow The Carpentries Code of Conduct.

  • +
  • This is a hands-on, interactive workshop.

    +
      +
    • Be kind to each other and help each other as best you can.

    • +
    • If you can’t help someone or there is some problem, let someone know.

    • +
    • If you notice something that prevents you from learning as well as you can, let us know and don’t suffer silently.

    • +
    +
  • +
  • It’s also about the little things:

    +
      +
    • volume

    • +
    • font size

    • +
    • generally confusing instructor

    • +
    • not enough breaks

    • +
    +
  • +
+
+
+
+

Overview of the lessons and a typical workshop

+

Here the instructor gives an overview of the lessons and a typical workshop.

+
+
+

What we do differently?

+
    +
  • Planing, teaching material available in advance and not PDF slides

  • +
  • Different roles (instructor, host, hackmd, …)

  • +
  • GitHub projects board so all boxes are checked

  • +
  • Helper recruitment and breakout room planning

    +
      +
    • Designing for this as soon as you open registration

    • +
    +
  • +
  • Less is more

  • +
  • Welcome session and “outro” session

  • +
  • Clearly defining learning outcomes

  • +
  • Asking for feedback, encouraging feedback

  • +
  • Manual

  • +
  • Screen-sharing

  • +
  • Using lesson templates

  • +
  • Lesson review on GitHub

  • +
  • Sharing material instead of being protective

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/instructor-training/workshops-online/index.html b/branch/instructor-training/workshops-online/index.html new file mode 100644 index 0000000..965cdd3 --- /dev/null +++ b/branch/instructor-training/workshops-online/index.html @@ -0,0 +1,461 @@ + + + + + + + Running a workshop: online — CodeRefinery instructor training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Workshop manuals

+

CodeRefinery maintains a number of workshop manuals +with most of the “primary” information. This episode condenses this +into a quick overview.

+
+
+

Running a workshop: online

+
+

Online teaching discussion

+
+

Discussion: Online vs in-person

+

In notes:

+
    +
  • Compare and contrast the benefits of online teaching with +in-person: {advantage, disadvantage} × {content, presentation}

  • +
  • How do you have to prepare differently?

  • +
  • What are your own experiences?

  • +
+
+
+
+

Case study: Mega-CodeRefinery and Finland HPC Kickstart

+
    +
  • Mega-CodeRefinery

    +
      +
    • Audience of around 90-100

    • +
    • “bring your own breakout room” (see below)

    • +
    • 3 days/week, 6 days total

    • +
    • Lessons as normal in CodeRefinery

    • +
    +
  • +
  • HPC Kickstart

    +
      +
    • 250 registered, ~180 max participants

    • +
    • Multi-university: local differences made this much harder to manage.

    • +
    • Breakout rooms not pre-planned.

    • +
    +
  • +
+

Mega-CodeRefinery worked very well, HPC kickstart didn’t - but not +because of the size.

+
+
+

General workshop arrangements

+ +
    +
  • Select a coordinator, recruit instructors (at least 3 is important), +find helpers

  • +
  • Find a good lecture room: +requirements

  • +
  • Set up workshop webpage using the [Github, template +repository](https://github.com/coderefinery/template-workshop-webpage]: +see +manuals

  • +
  • Advertising the workshop

  • +
  • Communication with registered participants

  • +
+
+
+

CodeRefinery online scaling strategy

+
    +
  • We started online workshops in 2020 March, for the obvious reasons.

  • +
  • First, we started with two “normal size” (20 people) practice +workshops

  • +
  • Then we did a 100 person workshop. It went well, but there is less +tolerance for problems.

  • +
+
+

Basic preparation

+
    +
  • You need more breaks are needed

  • +
  • People have a way of doing too many things and not focusing.

  • +
  • How to attend an online +workshop” +guide to prepare learners

  • +
+
+
+

Basic platform: Zoom

+
    +
  • Zoom (not the most ethical, but worked well and was available)

  • +
  • Zoom mechanics: instructions for +students.

    +
      +
    • Mostly things that are known

    • +
    • We don’t use Zoom interaction features much anymore +(faster/slower/etc), but breakout rooms and HackMD instead

    • +
    +
  • +
  • See also: Online training +manual +(which is getting a bit old compared to what is below).

  • +
+
+
+

Breakout rooms, bring your own team

+
    +
  • Breakout rooms are

    +
      +
    • Static: same people across whole workshop

    • +
    • Contain one helper per room (see below)

    • +
    +
  • +
  • Team registration: accept a “team” field when registering, people on the +same team are put together.

    +
      +
    • Gives motivations for learners to bring their colleagues and +learn together.

    • +
    • More than one person learning together greatly increases update

    • +
    +
  • +
  • You need a powerful enough registration system to assign rooms and +email them to people!

  • +
  • We ask people to name themselves “(N) Firstname Lastname” or “(N,H) +Firstname Lastname” for helpers. Then it is fast to assign them to +their designated breakout rooms.

  • +
  • See also: Breakout room +mechanics

  • +
+
+
+

Helper training

+
    +
  • Each breakout room has a helper

  • +
  • Helper should be a little bit familiar, but not expected to be able +to answer all questions.

  • +
  • Special, custom helper +training +since helpers make or break the workshop

  • +
  • Helper recruitment:

    +
      +
    • Our networks

    • +
    • Team registration: if a team registers with their own helper, then +they are guaranteed to get in together. “bring your own breakout +room”

    • +
    • Former learners, ask them to come back.

    • +
    +
  • +
  • Two helper trainings the week before the workshop.

  • +
+
+
+

Staff roles

+

To reduce stress on any one person, we clearly define the different +roles and try to avoid overlap. We actually have enough people for +all of these, so it works well.

+
    +
  • Workshop coordinator

    +
      +
    • Registration, etc.

    • +
    +
  • +
  • Zoom host

    +
      +
    • Handles registration, breakout rooms, recording, Zoom chat.

    • +
    +
  • +
  • HackMD helper

    +
      +
    • Dedicated to watching HackMD and answering questions quickly.

    • +
    • Host on manuals

    • +
    +
  • +
  • Expert helpers

    +
      +
    • “Spare hands” who rotate between breakout rooms and make sure +helpers are doing well.

    • +
    • Give feedback to instructor about how breakout rooms are going.

    • +
    • Take the place of missing helpers.

    • +
    • Easy way for any people with a bit of spare time to help out.

    • +
    • Expert helpers in workshop

    • +
    +
  • +
  • Instructors

    +
      +
    • Teach, they shouldn’t overlap with the above roles (but serve as +expert helpers other times).

    • +
    • Usually also improve the lesson a bit before teaching

    • +
    • General staff intro in manuals

    • +
    +
  • +
  • Workshop preparation meeting

    + +
  • +
+
+
+

HackMD

+
    +
  • We’ve been using it here

  • +
  • Chat doesn’t work wen large, written +document does.

  • +
  • HackMD can just about scale to ~100 person workshop. Recommend +learners keep it in view mode while not editing.

  • +
  • Voice questions are still allowed, but will be recorded. Staff +raise important questions from HackMD to the instructor immediately.

  • +
  • HackMD also allows communication when in breakout rooms.

  • +
  • You can get multiple answers, and answers can be improved over +time.

  • +
  • HackMD +mechanics +and HackMD +helpers.

  • +
+
+
+

Recording and streaming

+
    +
  • When you have 100 people, main room is quiet anyway: you don’t lose +much by recording.

    +
      +
    • Questions anonymously in HackMD, privacy loss is not so bad

    • +
    +
  • +
  • Breakout rooms are never recorded

  • +
  • Streaming

    +
      +
    • We streamed via Twitch: https://twitch.tv/coderefinery

    • +
    • We typically get 5-40 viewers.

    • +
    • Zoom can directly send the stream to Twitch: no extra software +needed.

    • +
    • Twitch archives videos for 14 days, which allows learners to get +an instant reply (we get hundreds of views in the next days).

    • +
    • So while possibly not useful for new people to learn, the instant +reply is very useful. Instructor can also work on problems in +main stream during breakout rooms, which learners can watch +later.

    • +
    • Streamers also have access to HackMD to ask questions.

    • +
    +
  • +
  • Certain tricks needed to keep learners from appearing in recording +or stream

    +
      +
    • “Spotlight video”, host does not go to gallery view, uses dual +monitor mode. We are still figuring this out.

    • +
    +
  • +
+
+
+

Installation time

+
    +
  • People have to be ready once we start, or else everything fails.

  • +
  • Two installation help times the week before.

  • +
  • Every email emphasizes that you have to be prepared, and “requires” +you to attend workshops (but really it’s only)

  • +
  • Installation instructions include steps to verify

  • +
  • Installation instructions also include video demonstrations of +installation and verification.

  • +
  • We haven’t had that many installation problems, but also we keep the +requirements simple.

  • +
  • Helper introduction is right before software install time, so +helpers can stay and help with install if they want.

  • +
  • Design to be easy to install and get set up.

  • +
+
+
+

Other notes

+
    +
  • Make breakout sessions as long as possible: 10 minutes is really too +short. 20 minutes is a good minimum time.

  • +
  • Be very clear about exercise expectations

  • +
  • Keep HackMD updated as a log.

  • +
  • Don’t combine breaks and breakout times.

  • +
  • The more people you have, the more diverse audience you have and the +more people overwhelmed and under whelmed.

  • +
+
+
+
+

Workshop collaborations

+

Why limit ourselves to CodeRefinery workshop? Why not use our network +and techniquess for more

+
    +
  • Case study: Python for Scientific +Computing

    +
      +
    • Started by Aalto

    • +
    • Announced to CodeRefinery, five more instructors from three +countries joined.

    • +
    • Rapid collaboration, taught course shortly later.

    • +
    • Announced to all institutions. Some places had physical rooms, +some were pure online

    • +
    • Also streamed

    • +
    • It was much more fun and less stressful to work together

    • +
    +
  • +
  • We want to continue this kind of collaboration in other workshops.

  • +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/_images/BYOC.png b/branch/main/_images/BYOC.png new file mode 100644 index 0000000..94702a1 Binary files /dev/null and b/branch/main/_images/BYOC.png differ diff --git a/branch/main/_images/CR_workshop_setup.png b/branch/main/_images/CR_workshop_setup.png new file mode 100644 index 0000000..47b4502 Binary files /dev/null and b/branch/main/_images/CR_workshop_setup.png differ diff --git a/branch/main/_images/community.png b/branch/main/_images/community.png new file mode 100644 index 0000000..ddd9a62 Binary files /dev/null and b/branch/main/_images/community.png differ diff --git a/branch/main/_images/hackmd--controls.png b/branch/main/_images/hackmd--controls.png new file mode 100644 index 0000000..46a74c7 Binary files /dev/null and b/branch/main/_images/hackmd--controls.png differ diff --git a/branch/main/_images/hackmd--full-demo.png b/branch/main/_images/hackmd--full-demo.png new file mode 100644 index 0000000..0988b6f Binary files /dev/null and b/branch/main/_images/hackmd--full-demo.png differ diff --git a/branch/main/_images/hackmd--questions2.png b/branch/main/_images/hackmd--questions2.png new file mode 100644 index 0000000..a609199 Binary files /dev/null and b/branch/main/_images/hackmd--questions2.png differ diff --git a/branch/main/_images/history-landscape-dark.png b/branch/main/_images/history-landscape-dark.png new file mode 100644 index 0000000..a1aef3c Binary files /dev/null and b/branch/main/_images/history-landscape-dark.png differ diff --git a/branch/main/_images/history-portrait-dark.png b/branch/main/_images/history-portrait-dark.png new file mode 100644 index 0000000..2fc1fa6 Binary files /dev/null and b/branch/main/_images/history-portrait-dark.png differ diff --git a/branch/main/_images/history-portrait-light.png b/branch/main/_images/history-portrait-light.png new file mode 100644 index 0000000..5f4361c Binary files /dev/null and b/branch/main/_images/history-portrait-light.png differ diff --git a/branch/main/_images/history-portrait.png b/branch/main/_images/history-portrait.png new file mode 100644 index 0000000..28e18b0 Binary files /dev/null and b/branch/main/_images/history-portrait.png differ diff --git a/branch/main/_images/history-rsh.png b/branch/main/_images/history-rsh.png new file mode 100644 index 0000000..1bbb1cc Binary files /dev/null and b/branch/main/_images/history-rsh.png differ diff --git a/branch/main/_images/instructor.png b/branch/main/_images/instructor.png new file mode 100644 index 0000000..718f2a8 Binary files /dev/null and b/branch/main/_images/instructor.png differ diff --git a/branch/main/_images/landscape.png b/branch/main/_images/landscape.png new file mode 100644 index 0000000..eda9d42 Binary files /dev/null and b/branch/main/_images/landscape.png differ diff --git a/branch/main/_images/learner-large.png b/branch/main/_images/learner-large.png new file mode 100644 index 0000000..3b6d2cd Binary files /dev/null and b/branch/main/_images/learner-large.png differ diff --git a/branch/main/_images/learner-normal.png b/branch/main/_images/learner-normal.png new file mode 100644 index 0000000..590135e Binary files /dev/null and b/branch/main/_images/learner-normal.png differ diff --git a/branch/main/_images/learner-small.png b/branch/main/_images/learner-small.png new file mode 100644 index 0000000..5d5f421 Binary files /dev/null and b/branch/main/_images/learner-small.png differ diff --git a/branch/main/_images/portrait.png b/branch/main/_images/portrait.png new file mode 100644 index 0000000..415799f Binary files /dev/null and b/branch/main/_images/portrait.png differ diff --git a/branch/main/_images/steps.png b/branch/main/_images/steps.png new file mode 100644 index 0000000..6c978b5 Binary files /dev/null and b/branch/main/_images/steps.png differ diff --git a/branch/main/_images/survey-impact1.png b/branch/main/_images/survey-impact1.png new file mode 100644 index 0000000..7dd0ddc Binary files /dev/null and b/branch/main/_images/survey-impact1.png differ diff --git a/branch/main/_images/survey-impact2.png b/branch/main/_images/survey-impact2.png new file mode 100644 index 0000000..8771bff Binary files /dev/null and b/branch/main/_images/survey-impact2.png differ diff --git a/branch/main/_images/welcome.png b/branch/main/_images/welcome.png new file mode 100644 index 0000000..302082c Binary files /dev/null and b/branch/main/_images/welcome.png differ diff --git a/branch/main/_sources/co-teaching.md.txt b/branch/main/_sources/co-teaching.md.txt new file mode 100644 index 0000000..c197f10 --- /dev/null +++ b/branch/main/_sources/co-teaching.md.txt @@ -0,0 +1,110 @@ +(co-teaching)= + +# Co-teaching + +:::{objectives} +- Get to know the principle of co-teaching: How we do it and how you can too. +- Learn the team teaching concept and how to tailor it to your situation. +::: + +:::{instructor-note} +- Teaching: 15 min +- Exercises: 10 min +- Discussion: 5 min +::: + + +## Overview + +CodeRefinery lessons benefit from the application of the concepts of **co-teaching**. + +:::{admonition} Co-teaching +[Co-teaching](https://en.wikipedia.org/wiki/Co-teaching) can be defined as "the division of labor between educators to plan, organize, instruct and make assessments on the same group of students, generally in a common classroom, and often with a strong focus on those teaching as a team complementing one another's particular skills or other strengths". +::: + +Co-teaching can be used in various forms, some of which are present in our workshops: +- **Teaching + support**, e.g. one of the teachers leading instruction while the other watches over and maintains the collaborative document (HackMD/HedgeDoc/...). +- Another similar example is **remote learning groups** that watch the streamed CodeRefinery lessons guided by the local instructors. +- Having open-source material and planning jointly allows **multiple instances** of a lesson to be held by multiple teachers: + - *parallel teaching*, to different audiences at the same time, + - *alternative teaching*, to different audiences at the same or different time, with potential content adjustments (for example, different installation procedures). +- **Team teaching**, where the lesson is presented by multiple (in most cases, two) teachers who actively engage in conversation with each other. The team-teaching concept is explained in more detail in the [CodeRefinery manual](https://coderefinery.github.io/manuals/team-teaching/). + +In reality, different forms are very often mixed or fused together, even within a single lesson. + +Co-teaching is not an online-only concept. However, it is very practical in online teaching due to larger number of instructors and learners potentially available to join a teaching session. + + +## Co-teaching and team teaching benefits + +- It **saves preparation time**. Co-teachers can rely on each other's strengths while creating/ revising the material as well as in unexpected situations during the lesson. +- It **helps with onboarding new instructors**. One of the co-teachers can be learning at the same time, either the subtleties of the material taught (in this case literally being the "voice of the audience") or the teaching process itself. +- Team teaching **looks more interactive and engaging** to the audience in many cases, without forcing the learners to speak up if they can't or don't want to do so. +- It also **ensures responsive feedback and less workload** by having more active minds. + + +### Are there any downsides? + +Not every learner and not every instructor might like the team-teaching approach. +- It might seem **less structured**, unprepared, and chaotic, even with preparation. + - It might create situations where instructors accidentally talk over each other or "interrupt" and change the flow of the lesson. + - For some instructors it can be stressful to not know in advance what questions they get asked from the co-instructor. + - Sometimes when an unexpected question is asked that throws the other instructor off, it can add to the feeling of chaos and unpreparedness. +- It can be interactive and engaging but it can also end up awkward if the co-teachers don't have a good synergy. + - Can sound awkward: Main instructor talking all the time and at the end asking co-instructor whether everything is clear and co-instructor only saying "yes". + - Possibly more engaging: Co-instructor asking questions which help with the flow and a common understanding of the material. + + +## Team teaching specifics + +- For successful team teaching, additional **coordination** is needed, first of all to agree on the teaching model (see below) and the person in control (the **director**) for the lesson or its parts. +- It's useful to keep track of the **lecture plan**. The discussion is a good way to make lesson more interactive and adjust to the audience, but deviating too much will become disorienting (for example, if someone dropped their attention for a minute and now is trying to catch-up by reading lecture notes). +- Experienced solo teacher might have a habit to keep talking (lecturing), while the co-teacher might not want to "interrupt". Therefore, it is important for the leading presenter to anticipate and **allow for remarks/ questions**, and this can be different from one's previous teaching style at first. + + +## Team teaching models + +We propose two basic models, but of course there is a constant continuum. + + +### Guide and demo-giver + +One person serves the role of **guide**, explaining the big picture and context of the examples. + +Another, the **demo-giver**, +- shows the typing and does the examples, +- might take the role of a learner who is asking about what is going on, to actually explain the details, or to comment occasionally. + +Hands-on demos and exercises work especially well like this. + + +### Presenter and interviewer + +In this case, one is the **presenter** who is mostly explaining (including demos or examples), and trying to move the forward through the material. + +Another, the **interviewer**, +- serves as a learner or spotter, +- fills in gaps by asking relevant questions, +- tries to comment to the presenter when things are going off track. + +This can be seen as closer to classical teaching, but with a dedicated and prepared "voice of the audience". + + +### Exercise + +:::{exercise} Discuss the models of team teaching (10 min) +While in breakout rooms, discuss one of the basic team-teaching models presented here: +- Have you already tried this or similar model in your teaching? +- Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best? + +Write your comments in the collaborative document. +::: + + +## Summary + +:::{keypoints} +- Co-teaching focuses on complementing individual skills and strengths in teaching process. +- Co-teaching may save time, reduce teachers' workload and make lessons more interactive/ engaging. +- Team teaching requires some adjustments in lesson preparation and delivery. +::: diff --git a/branch/main/_sources/coderefinery-intro.md.txt b/branch/main/_sources/coderefinery-intro.md.txt new file mode 100644 index 0000000..50d108c --- /dev/null +++ b/branch/main/_sources/coderefinery-intro.md.txt @@ -0,0 +1,116 @@ +# About the CodeRefinery project and CodeRefinery workshops in general + +:::{objectives} +- Discuss what CodeRefinery is and how we got here +- Understand about the challenges to define our target audience +::: + +CodeRefinery is a +[Nordic e-Infrastructure Collaboration (NeIC)](https://neic.no/) +project that has started in October 2016 and is currently +funded until February 2025. We are working on the continuation plans. + +The funding from 2022-2025 is designed to keep this project active +beyond 2025 by forming a support network and building a community of +instructors and contributors. + + +:::{discussion} History +The CodeRefinery project idea grew out of two [SeSE](http://sese.nu) courses given at KTH Stockholm in 2014 and 2016. +The project proposal itself was submitted to NeIC in 2015, accepted in 2015, and started in 2016. + +We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form. +::: + + +## Goals + +- Develop and maintain **training material on good enough software development practices** for researchers that write code/scripts/notebooks. +- Our material addresses all academic disciplines and tries to be as programming language-independent as possible. +- Provide a [code repository hosting service](https://coderefinery.org/repository/) that is open and free + for all researchers based in universities and research institutes from Nordic countries. +- Provide **training opportunities** in the Nordics using (Carpentries and) CodeRefinery training materials. +- Evolve the project towards a **community-driven project** with a network of instructors and contributors. + + +## Community + +```{figure} img/community.png +Image showing the key areas of the CodeRefinery community: Workshops, chat inlcuding help channel, online meetings and co-working, +other collaborative training, eg on High Performance Computing topics. +``` + +CodeRefinery is not just workshops, we are community and want you to be part of it! + +There are many different levels of involvement, from the occasional commenter in chat, +CodeRefinery ambassador (people who like the project and workshops and help us spreading the word) or lesson issue creators and lesson contributors to +local host, co-instructor or co-organizer. + +Best **first step** in any case is to join the [CodeRefinery Zulip chat](https://coderefinery.zulipchat.com) +or let us know about your interest at support@coderefinery.org. + + +## Target audience + +One common question we get is how do we relate to [the Carpentries](https://carpentries.org). +This section describes how we see it: + + +### Carpentries audience + +The Carpentries aims to teach computational **competence** to learners through an applied approach, +avoiding the theoretical and general in favor of the practical and specific. + +**Mostly, learners do not need to have any prior experience in programming.** +One major goal of a Carpentries workshop is to raise awareness on the tools researchers can learn/use to speed up their research. + +By showing learners how to solve specific problems with specific tools and providing hands-on practice, +learners develops confidence for future learning. + +:::{admonition} Novices +We often qualify Carpentries learners as **novices**: they do not know what they need to learn yet. +A typical example is the usage of version control: the Carpentries lesson +[Version Control with Git](https://swcarpentry.github.io/git-novice/) +aims to give a +very high level conceptual overview of Git but it does not explain how it can be used in research projects. +::: + + +### CodeRefinery audience + +In that sense, CodeRefinery workshops differ from Carpentries workshops as we assume +our audience already writes code and scripts and we aim at teaching them **best software practices**. + +Our learners usually do not have a good overview of **best software practices** but are aware of the need to learn them. +Very often, they know of the tools (Git, Jupyter, etc.) we are teaching +but have difficulties to make the best use of them in their software development workflow. + +Whenever we can, we direct learners that do not have sufficient coding experience to Carpentries workshops. + +:::{admonition} Competent practitioners +We often qualify CodeRefinery learners as **competent practitioners** because they already have an understanding of their needs. +::: + +:::{discussion} Challenges related to defining our target audience +We often get the feedback "I wish I would have known X earlier!" +*Competent practitioners* have run into issues with **not** caring (or not fully understanding) +about version control, documentation, modularity, reproducibility before, so they are easily motivated to learn more. + +For a *novice* these topics may seem unnecessary and "too much" and the workshop may feel too difficult to follow. +However, the materials are designed so that one can always revisit a topic, when needed. +The important part is that you know that "X" exists, and where to find more information, which is also beneficial for novices. +::: + +--- + +:::{keypoints} Keypoints: CodeRefinery +- Teaches intermediate-level software development tool lessons +- It is difficult to define "best practices", we try to teach **"good enough" practices** +- Training network for other lessons +- Publicly-funded discrete projects (3 projects actually) transitioning towards an open community project +- We have online material, teaching, and exercise sessions +- Our main target audience are competent practitioners, but also novices and experts can get something out of the workshops +- We want more people to work with us, and to work with more people +::: diff --git a/branch/main/_sources/collaborative-notes.md.txt b/branch/main/_sources/collaborative-notes.md.txt new file mode 100644 index 0000000..15f84b3 --- /dev/null +++ b/branch/main/_sources/collaborative-notes.md.txt @@ -0,0 +1,333 @@ +(collaborative-notes)= + +# Collaborative notes + +:::{objectives} +- Be able to provide a highly interactive online workshop environment with collaborative documents +::: + +:::{instructor-note} +- Teaching: 10 min +- Exercise: 15 min +- Questions & Answers: 5 min +::: + +## Introduction + +The Collaborative document is how you interact with the participants. +The participants can ask questions and give feedback through the collaborative +document. During a CodeRefinery session there can be a large a volume of questions. +A dedicated person, a Collaborative document-manager, is needed to answer and edit the collaborative document. +Let us see how the collaborative document is used, then discuss the role of +the editor or collaborative document-manager. + +## Collaborative document mechanics and controls +Technologies that can be used as a collaborative document are [Hackmd](https://hackmd.io), [HedgeDoc](https://hedgedoc.org), +or [Google Docs](https://www.google.com/docs/about/) + +[Hackmd](https://hackmd.io) or [HedgeDoc](https://hedgedoc.org/) are real-time text editor online. We use it to: +* As a threaded chat, to **answer questions and provide other information** without + interrupting the main flow of the room. +* provide everyone with a **more equal opportunity to ask questions**. +* **create notes** which will be archived, for your later reference. + +You do not need to login/create an account to be able to edit the document. + +### Basic controls + +```{figure} img/hackmd--controls.png + +This may look slightly different on mobile devices and small windows. +``` + +- At the top (left or right), you can switch between **view**, + **edit**, and **split view and edit** modes. + +- You write in [markdown](https://commonmark.org/help/) here. Don't + worry about the syntax, just see what others do and try to be like + that! Someone will come and fix any problems there may be. + +- Please go back to view mode if you think you won't edit for a + while - it will still live update. + + +### Asking questions + +**Always ask questions and add new sections at the very bottom**. +You can also answer and comment on older questions, too. + +```{figure} img/hackmd--questions2.png + +Questions and answers in bullet points +``` + +Since we plan to publish the questions and answers later as part +of the workshop page, we recommend to not use any names. You can indicate +your own name to make it easier to discuss more during the workshop but +then always use this form: `[name=Myname]`. This makes it easier for +us to automatically remove all names before publishing the notes. + +Other hints: + +- Use `+1` to agree with a statement or question (we are more likely + to comment on it). + +- Please leave some blank lines at the bottom + +- NOTE: Please don't "select all", it highlights for everyone and adds a + risk of losing data (there are periodic backups, but not instant). + +- It can be quite demanding to follow the collaborative document closely. Keep an eye + on it, but consider how distracted you may get from the course. For + things beyond the scope of the course, we may come back and answer + later. + + +### Don't get overwhelmed + +There can be a flood of information on the collaborative document. Scan for what is +important, then if you would like come back later. But it is +important to keep checking it. + + +### Privacy + +- Assume the collaborative document is **public and published: you never + need to put your name there**. + +- The collaborative document will be **published on the website afterwards**. We will + remove all non-instructors names, but it's easier if you don't add + it there in the first place. + +- Please keep the link private during the workshop, since since + security is "editable by those who have the link". + +- You can use `[name=YOURNAME]`, to name yourself. We *will* remove + all names (but not the comments) before archiving the notes (use + this format to make it easy for us). + +## Exercise + +:::{exercise} Discuss how to collaborate and handle questions (15 min) +Write down your conclusions in the shared document. Items to discuss are: +- What is your experience with questions and discussions while teaching? +- How do you deal with them? +- What kind of technologies do you prefer: chat, shared document, or voices + and discussion raised during instruction? And why? +::: + +## Collaborative Document Manager + +We have one person who is a "Collaborative Document helper". This isn't the only +person that should edit and answer, but one person shouldn't have too +much else on their mind so can focus on it. They also make sure that +the collaborative document is updated with exercise, break, and other meta-information to +keep people on track. + +Below, (*) = important. + +### Before the workshop + +* Create a new collaborative document for the workshop +* make sure that **editing is enabled for anyone without login** +* Add workshop information, links to the workshop page and material +and an example question and answer to the top of the collaborative document(see below) + +### Most things to edit (everyone) + +Make it easy to post after the course and consistent to follow: + +* Tag all names with `[name=XXX]` (so they can be removed later), + remove other personal data or make it obvious. +* Add in information on exercises (new section for them, link, end + time, what to accomplish) +* Make a logical section structure (`#` for title, `##` for sections, + `###` for episodes, etc. - or what makes sense) + + + +### General Collaborative Document practices + +```{figure} img/hackmd--full-demo.png +:align: right + +A live demo of a Collaborative Document during a Q&A time. The two instructors are +discussing some of the import answers. Multiple learners have asked +questions, multiple answers, and some remaining to be answered +``` + + + +Keep it formatted well: + +- (*) Tag names you see with `[name=XXX]` so that we can remove it + later. +- Heading level `#` is only the page title +- Add a new `##` heading when a new *lesson* or similar thing is + started (introduction, icebreaker, break between lessons, etc) +- Add a new `###` heading when a new *episode*, *exercise*, *break* + (within exercise session) +- Ensure people are asking questions at the bottom, direct them there + if they aren't. +- (*) Ensure each question is a bullet point. Each answer or follow-up + should be a bullet point below. + - Should you use more deeply nested bullet points, or have only one + level below the initial question? It depends on the context, but + if a conversation goes on too long, try not to let it go too + deep. + + +Update with meta-talk, so that learners can follow along easily: + +- Add Icebreaker and introductory material of the day. Try to talk to + people as they joined to get them to open the collaborative document and answer. +- Anything important for following along should not be only said via + voice. It needs to be in the collaborative document, too. +- New lessons or episodes, with links to them. +- For exercises, link to exercise and add the duration, end time, + goals. If these are unclear, bring it up to the instructor by voice. +- Add a status display about breaks. + + +Screenshare it when necessary: + +- During breaks and other times, share the collaborative document(including the + notification about break, and when it ends). +- It is nice if the arrangement allows some of the latest questions to + be seen, so people are reminded to ask there. +- Someone else may do this, but should make sure it happens. + +Answer questions + +- If there is an question that should be answered by the instructor by + voice, bring it up (by voice) to the instructor immediately. +- How soon do you answer questions? Two points of view: + - Answer questions right away: can be really intense to follow. + - Wait some so that we don't overload learners: reduces the info + flow. But then do people need to check back more often. + - You need to find your own balance. Maybe a quick answer right + away, and more detailed later. Or delay answers during the most + important parts of the lecture. +- Avoid wall-of-text answers. If reading an answer takes too long, it + puts the person (and other people who even try to read it) behind + even more by taking up valuable mental energy. If an answer needs a + wall of text, consider these alternatives: + - Progressive bullet points getting more detailed (first ones + useful alone for basic cases) + - Don't be worried to say "don't worry about this now, let's talk + later." + - Figure out the root problem instead of answering every possible + interpretation + - Declare it advanced and that you will come back later. + +Ensure it can be posted quickly: + +- The collaborative document gets posted to the workshop webpage. For this, it needs some + minimal amount of formatting (it doesn't need to be perfect, just + not horrible). +- All names and private information needs to be stripped. This is why + you should rigorously tag all names with `[name=XXX]` so they can be + removed (see above). + - Learner names can be completely removed. CR staff names can be + `[name=CR]` or something similar. + - There may be other private URLs at the top or bottom. + +- If possible, send the PR adding the collaborative document to the workshop webpage + (though others can do this, too). + + + +### Collaborative document format example + +``` +# Workshop, day 1 + + +## Lesson name +https://coderefinery.github.io/lesson/ + +### Episode name +https://coderefinery.github.io/01-episode/ + +- This is a question + - Anwser + - More detailed answer +- question + - answer + +### Exercises: +https://link-to-exercise/.../.../#section +20 minutes, until xx:45 +Try to accomplish all of points 1-3. Parts 4-5 are optional. + +Breakout room status: +- room 2, need help with Linux permissions +- room 5, done + +### Break +:::danger +We are on a 10 minute break until xx:10 +::: + + +## Lesson 2 +https://coderefinery.github.io/lesson-2/ + +``` + +### Posting the collaborative document to the website + +The collaborative document should be posted sooner rather than later, and hopefully the +steps above will make it easy to do so quickly. You could wait a few +hours, to allow any remaining questions to be asked an answered. + +- Download as markdown +- Remove any private links at the top +- Adjust headings so that they are reasonable +- Look for private info and remove it + - Search document for `[name=???]` (change to `[name=staff]` or + `[name=learner]`) + - Any names not tagged with `[name=]` + - usernames in URLs + - private links + +### Feedback template + +`````` +## Feedback, day N + +:::info +### News for day N+1 +- . +- . +::: + +### Today was (multi-answer): +- too fast: +- just right: +- too slow: +- too easy: +- right level: +- too advanced: +- I would recommend this course to others: +- Exercises were good: +- I would recommend today to others: +- I wouldn't recommend today: + +### One good thing about today: +- ... +- ... + +### One thing to be improved for next time: +- ... +- ... + +### Any other comments: +- ... +- ... +`````` +:::{keypoints} +- Having a collaborative document improves communication and interaction. +- Answering questions requires a dedicated person - A Collaborative Document Manager. +- The collaborative document should be posted on the web site as soon as possible. +::: diff --git a/branch/main/_sources/computational-thinking.md.txt b/branch/main/_sources/computational-thinking.md.txt new file mode 100644 index 0000000..943d9c8 --- /dev/null +++ b/branch/main/_sources/computational-thinking.md.txt @@ -0,0 +1,25 @@ +(computational-thinking)= + +# Computational thinking + + +:::{objectives} +- Explain what is computational thinking +- Get to know how the theory of computational thinking can be used in teaching +- Short exercise +::: + +:::{instructor-note} +- Teaching: 20 min +- Exercises: 10 min +::: + + +Materials available as [slides](https://github.com/coderefinery/train-the-trainer/blob/main/content/computational_thinking.pdf). + + +:::{keypoints} +- Computational Thinking consists of 4 main parts: decomposition, pattern recognition, abstraction and algorithmic design. +- How can this be a useful framework for solving problems? +- How can this be used practically? +::: diff --git a/branch/main/_sources/cool-gems.md.txt b/branch/main/_sources/cool-gems.md.txt new file mode 100644 index 0000000..a4a6f5c --- /dev/null +++ b/branch/main/_sources/cool-gems.md.txt @@ -0,0 +1,16 @@ +(cool-gems)= + +# Sharing teaching gems + +:::{objectives} +- Our goal is to share our teaching tricks and tools and demonstrate them in + very short presentations/discussions. +::: + +:::{instructor-note} +- Demonstrations: 35 min +::: + +Here we encourage participants to take the screen share for 3 minutes and +demonstrate either some tool or trick they found useful for their teaching or +something from a course you liked. diff --git a/branch/main/_sources/feedback-and-impact.md.txt b/branch/main/_sources/feedback-and-impact.md.txt new file mode 100644 index 0000000..698de4a --- /dev/null +++ b/branch/main/_sources/feedback-and-impact.md.txt @@ -0,0 +1,200 @@ +# How we collect feedback and measure impact + +:::{objectives} +- Discuss how one can collect feedback from learners ("what can we improve?"). +- Discuss how we convert feedback into actionable items. +- Discuss how we measure the impact of teaching ("did we achieve our goals?"). +- Discuss the "why". +- Get to know the reasons and sources of inspiration behind major lesson and workshop updates. +::: + +:::{instructor-note} +- Discussion: 20 min +- Exercises: 10 min +::: + + +## Asking questions before the workshop + +- Motivation: Know your audience. +- Until 2021 we had a pre-workshop survey: + - Data, questions, and notebook: + - Zenodo/DOI: +- After 2021 we incorporated some of the questions into the registration form. + - Easier registration experience for participants. + - After 5 years of running workshops, we had a good idea of what to expect. + + +## Collecting feedback as we teach + +- Each day we ask for feedback in the collaborative notes. + - One good thing about today. + - One thing to improve for next time. + - Any other comments? +- During the workshop we sometimes check in and ask about the pace, example: + ``` + How is the speed so far? (add an "o") + - Too fast: oooooo + - Too slow: ooo + - Just right: ooooooooooooooooooo + ``` +- We publish all questions, answers, and feedback. Example: +- How we follow up: + - Some problems we can fix already before the next workshop day. + - We convert feedback/problems into GitHub issues and track these close to the lesson material. + + +## Trying to measure impact with longer-term surveys + +- Motivation: Understand the long-term impact of our workshops. Have something to show to funders. +- 2024 post-workshop survey: + - Blog post: + - Questions, notebook, and figures: + - Zenodo/DOI: +- 2021 version: + - Data, questions, notebook, and figures: + - Zenodo/DOI: +- How we use the results: + - When reporting to funders. + - When planning future workshops and bigger picture changes. + + +## Lessons learned + +- Think about how to measure impact/success from the beginning. +- **Make the feedback and survey results public**. +- Make the results persistent and citable. +- Have a mechanism to follow-up on feedback. +- Anonymization is more than just removing or dissociating names. +- Take time designing your survey and collect feedback on the survey itself. + + +## Take time designing your survey + +We are not experts in survey design but we reached out to RISE Research +Institutes of Sweden to get feedback on our survey questions. They provided us +with a lot of valuable feedback and suggestions for improvements. +Below are few examples. + + +### Example 1 + +First version of our survey question about impact: +- "Do our workshops help to save time in future?" Please quantify in hours saved: ... + +Feedback: +- Difficult to answer. +- Since when? Until all eternity? + +```{figure} feedback-and-impact/survey-impact1.png +:width: 80% +:class: with-border +:alt: Screenshot of earlier version of the survey question about impact. + +Earlier version of the survey question about impact. +``` + +Feedback: +- The question "Do our workshops help to save time in future?" is unspecified, + unnecessary, and leading. +- "No time saving" does not match the wording "save time" in the question. + +```{figure} feedback-and-impact/survey-impact2.png +:width: 80% +:class: with-border +:alt: Screenshot of later version of the survey question about impact. + +Later version of the survey question about impact. +``` + +- The wording "have you saved" now matches "No time saved". + + +### Example 2 + +- Earlier version: + ``` + Would you judge your code to be better reusable/reproducible/modular/documented + as a result of attending the workshop? + + - More reusable + - More reproducible + - More modular + - Better documented + - None of the above + ``` +- Feedback: The question is not neutrally formulated and risks leading to + over-reporting of yes answers. Consider balancing so that the questions are + formulated more neutrally. +- Reformulated to: + ``` + After attending the workshop, would you judge your code to be + more reusable or not more reusable? + + - My code is more reusable + - My code is not more reusable + - Not sure + ``` + + +### Example 3 + +- Early version: + ``` + What else has changed in how you write code since attending the workshop? + + [free-form text field] + ``` +- Feedback: Leading and assumes that something has changed. +- Reformulated to: + ``` + Has anything else changed in how you write code for your research after + attending the workshop? + + [free-form text field] + ``` + + +### Example 4 + +- Earlier version: + ``` + Has it become easier for you to collaborate on software development with your + colleagues and collaborators? + + - Yes + - Not sure + - No + ``` +- Feedback: + - Leading question. + - Avoid "Yes" and "No" response options because respondents tend to answer + "Yes" if that option is available, leading to a risk of measurement error + (acquiescence bias). + - Do not place "Not sure" in the middle of the scale because it captures + participants who actually don't know and should therefore be placed at the + bottom instead of in the middle of the scale. +- Reformulated to: + ``` + After attending the workshop, has it become easier or not for you to + collaborate on software development with your colleagues and collaborators? + + - Collaboration is easier + - Collaboration is not easier + - Not sure + ``` + + +## Exercise: Group discussion (10 min) + +:::{exercise} Group discussion using the collaborative notes +- What tricks/techniques have you tried in your teaching or seen in someone + else's teaching that you think have been particularly effective in collecting + feedback from learners? +- Can you give tips or share your experiences about how to convert feedback + into actionable items? +- How do you measure the impact of your teaching? Any tips or experiences about + what you have tried or seen other courses do? +- Anybody knows of good resources on survey design? Please link them in + the collaborative notes. +::: diff --git a/branch/main/_sources/guide.md.txt b/branch/main/_sources/guide.md.txt new file mode 100644 index 0000000..3c956d8 --- /dev/null +++ b/branch/main/_sources/guide.md.txt @@ -0,0 +1,91 @@ +# Instructor guide + + +## Target audience + +- Everyone teaching online workshops about computational topics or interested in teaching. +- Previous and future instructors and helpers of CodeRefinery workshops. + + +## Timing + +**Session 1** +- 15 min: Intro +- 45 min: Lesson design and development +- 15 min: Break +- 45 min: Lesson template +- 15 min: Break +- 30 min: How we collect feedback and measure impact +- 10 min: Outro and feedback + +**Session 2** +- 15 min: Intro +- 10 min: About the CodeRefinery project and CodeRefinery workshops in general +- 30 min: Collaborative notes and interaction +- 15 min: Break +- 35 min: Workshop overview, roles, onboarding/installation, helpers +- 20 min: Sound +- 15 min: Break +- 30 min: Screenshare +- 10 min: Outro and feedback + +**Session 3** +- 15 min: Intro +- 30 min: Computational thinking +- 15 min: Break +- 30 min: Teaching philosohies +- 30 min: Co-teaching +- 15 min: Break +- 35 min: Sharing teaching tips, tricks, tools etc +- 10 min: Outro and feedback + +**Session 4** +- 15 min: Intro +- 10 min: Why we stream +- 20 min: Behind the stream +- 15 min: Video editing (part 1) +- 15 min: Break +- 25 min: Video editing (part 2, exercise) +- 20 min: OBS introduction +- 15 min: Break +- 30 min: OBS setup +- 15 min: What's next? + +## Talking points for each sessions intro + +- Brief CodeRefinery intro +- Instructors intros +- Notes intro + - Check-in + - Icebreaker + - Participant intros in breakoutrooms (Random assign first, then same for whole session) +- Daily schedule, learning objectives +- Code of conduct +- Chat (please use collaborative notes) + +## Participant preparations for each session +Copied from e-mail communication with participants before each session. + +**Session 1:** +In general you will only need your brain for the exercises and discussions, but some will have the option to go deeper, which may require some accounts or tools to be set-up. We will inform about these things the week before each session. + +For Session 1 we recommend to have a GitHub account (https://coderefinery.github.io/installation/github/#github). There will be an optional exercise where you can build a lesson locally. This requires a basic Python environment (https://github.com/coderefinery/sphinx-lesson-template/blob/main/requirements.txt), but do not worry if you cannot or do not want to set up these, there will be plenty of other exercises. + +**Session 2:** +In general you will only need your brain for the exercises and discussions. To get the most out of this workshop day we recommend that you join the session with the same computer, display and microphone setup as you would usually use for teaching/ presenting. It may also help to get familar with the different options your computer and Zoom setup provides for screenshare and audio adjustments. +But it is not a must. + +**Session 3:** +In general you will only need your brain for the exercises and discussions. If you want to share some "cool gem" in the last episode of this workshop day, please update your registration (link to edit can be found in the registration confirmation e-mail sent by support@coderefinery.org or noreply@neic.org). This is very low barrier, you do not have to be the developer of a tool or technique to share with the group what makes it useful for you; and it does not even have to be cool, sometimes the small "normal" things are the best. You can check out some topics that have been proposed so far in this GitHub issue (#90), you can also comment there if you want to add or change your topic. These will be lightning talk length, so something between 2-5 min depending on how many are interested to share something, but we can collect them all in the collaborative notes for further exploration/reading. +But it is not a must. + +**Session 4:** +This upcoming session (session number 4) will cover the technical aspects of CodeRefinery-style online teaching. These topics have never before been covered in this much detail, so if it's interesting to you, don't miss it. (You might also want to pass this on to others who are interested in technical production of online events; registration is still open!). + +First, we talk about why we stream (how we got here, advantages, disadvantages, how to be an instructor in a livestreamed workshop, and what it looks like from a broad level from the production side) + +Then, we show how we are able to release videos so quickly. This is useful far beyond CodeRefinery, and there are also some hands-on exercises. Come prepared to set up a Python environment and the ffmpeg command line tool if you want to try these. + +Finally, we see details about how to set up Zoom→Livestream environment for yourself. There isn't time to do this as a proper exercise, but it's the starting point and the instructor will offer help after the course for those interested. If you want to try this out during the session, install OBS Studio in advance. + + diff --git a/branch/main/_sources/index.md.txt b/branch/main/_sources/index.md.txt new file mode 100644 index 0000000..6adb709 --- /dev/null +++ b/branch/main/_sources/index.md.txt @@ -0,0 +1,122 @@ +# Train the trainer workshop + +::::{admonition} August/September 2024 CodeRefinery train the trainer workshop + +Do you teach the use of computers and computational tools? Are you curious about scaling your training and learn about tested and proven practices from CodeRefinery workshops and other trainers? Join us for the CodeRefinery train the trainer workshop: four self-contained sessions on tools and techniques for computational training offer a great chance to enhance your teaching skills and learn about new tools and practices. What you will learn is also used a lot outside CodeRefinery, whenever good beginner friendly training is needed. + +**Learning objectives:** +- Learn about tools and techniques and practice to create engaging online teaching experiences (screenshare, audio, etc.). +- Become mentally ready to be an instructor in a collaborative interactive online workshop (not only large workshops but in general). +- Learn how to design and develop lesson material collaboratively. + +**Target audience:** +- Everyone teaching online workshops about computational topics or interested in teaching. +- Previous and future instructors and helpers of CodeRefinery workshops. + +**Prerequisites:** +An interest in teaching. + +**Workshop structure:** +We aim for a mix of modular presentations and work in small groups. The latter will be done in breakoutrooms - +be prepared to switch on your camera and have a fruitful exchange with fellow participants! + +**Organizers and instructors:** + +The workshop is organized by [partner organizations of the CodeRefinery project](https://coderefinery.org/about/partners/). + +Facilitators and instructors: + +- Radovan Bast +- Richard Darst +- Bjørn Lindi +- Dhanya Pushpadas +- Jarno Rantaharju +- Stephan Smuts +- Stepas Toliautas +- Samantha Wittke + + +**Content and timing:** + +The workshop consists of four sessions every Tuesday between August +13th and September 3rd 2024, +{localtime}`09:00 13 August 2024 +02:00 (HH:mm)` to +{localtime}`12:00 13 August 2024 +02:00 (HH:mm z/zzz)`: + +- Session 1: About lesson design, deployment and iterative improvement (Aug 13) +- Session 2: Tools and techniques adopted in CodeRefinery workshops (Aug 20) +- Session 3: About teaching & cool things we all would like to share (Aug 27) +- Session 4: Workshop streaming practices and post-workshop tasks (Sep 3) + +You can join all sessions, or the just the ones that interest you. More details on each session will be shared later. + +The workshop is **free of charge for everyone**, please register below to get the Zoom link and other useful information for the workshop. + +The workshop is over and registration is closed now. + +If you have any questions, please write to . +:::: + +```{admonition} +You can find materials of previous similar trainings using the links below: + +- First version of the course in 2019 and then in 2020: + +- Reworked material for our summer workshop 2022 and +for the CarpentryCon 2022 workshop: + +``` + +```{toctree} +:maxdepth: 1 +:caption: Session 1 + +lesson-development +lessons-with-git +feedback-and-impact +``` + +```{toctree} +:maxdepth: 1 +:caption: Session 2 + +coderefinery-intro +collaborative-notes +overview +sound +screenshare +``` + +```{toctree} +:maxdepth: 1 +:caption: Session 3 + +computational-thinking +teaching-philosophies +co-teaching +cool-gems +``` + +```{toctree} +:maxdepth: 1 +:caption: Session 4 + +session-4-intro +why-we-stream +streaming +video-editing +obs +obs-config +streaming-whats-next +``` + +```{toctree} +:maxdepth: 1 +:caption: Resources + +notes-archive +guide +All lessons +CodeRefinery +Reusing +``` diff --git a/branch/main/_sources/lesson-development.md.txt b/branch/main/_sources/lesson-development.md.txt new file mode 100644 index 0000000..76e79bf --- /dev/null +++ b/branch/main/_sources/lesson-development.md.txt @@ -0,0 +1,204 @@ +(lesson-design)= + +# Lesson design and development + +:::{objectives} +- We share our design processes for teaching material and presentations. +- Learn how to design lessons "backwards", starting from learning objectives + and learner personas. +- Learn good practices for improving existing material based on feedback. +::: + +:::{instructor-note} +- Discussion: 20 min +- Exercises: 35 min +::: + + +## Exercise: How do you design your teaching material? + +:::{exercise} We collect notes using a shared document (5 min) +- When you start preparing a new lesson or training material, where do you start? +- What tricks help you with "writer's block" or the empty page problem? +- Maybe you haven't designed training material yet. But how do you start when creating a new presentation? +- If your design process has changed over time, please describe what you used to do and what you do now instead. +- What do you know now about preparing lessons/training/presentations that you wish you knew earlier? +::: + + +## Creating new teaching material + + +### Typical problems + +- Someone creates a lesson, but they think about what is interesting to them, + not what is important for the learners. +- "I want to show a number of things which I think are cool about + tool X - how do I press these into 90 minutes?" +- Write down material you want to cover and then sprinkle in some exercises. +- Thinking about how I work, not how the learners work. +- Trying to bring learners to their level/setup, not trying to meet the learners + where they are. +- Not really knowing the learning objectives or the learner personas. + + +### Better approach + +Good questions to ask and discuss with a group of colleagues **from diverse backgrounds**: +- What is the expected educational level of my audience? +- Have they been already exposed to the technologies I am planning to teach? +- What tools do they already use? +- What are the main issues they are currently experiencing? +- What do they need to remember/understand/apply/analyze/evaluate/create + ([Bloom's taxonomy](https://en.wikipedia.org/wiki/Bloom%27s_taxonomy))? +- Define learner personas. +- It may be an advantage to share an imperfect lesson with others early to + collect feedback and suggestions before the lesson “solidifies” too much. + Draft it and collect feedback. The result will probably be better than + working in isolation towards a "perfect" lesson. + + +### The process of designing a lesson "backwards" + +As described in ["A lesson design process" in the book Teaching Tech +Together](https://teachtogether.tech/en/index.html#s:process): + +1. Understand your learners. +1. Brainstorm rough ideas. +1. Create an summative assessment to know your overall goal. + > [Think of the things your learners will be able to do at the end of the lesson] +1. Create formative assessments to go from the starting point to this. + > [Think of some engaging and active exercises] +1. Order the formative assessments (exercises) into a reasonable order. +1. Write just enough material to get from one assessment (exercise) to + another. +1. Describe the course so the learners know if it is relevant to them. + + +## Improving existing lessons + +:::{discussion} All CodeRefinery lessons are on GitHub +- Overview: +- All are shared under CC-BY license and we encourage [reuse and modification](https://coderefinery.org/lessons/reusing/). +- Sources are all on GitHub: +- Web pages are generated from Markdown using [Sphinx](https://www.sphinx-doc.org/) + (more about that in the episode {ref}`lessons-with-git`). +- We track ideas and problems in GitHub issues. +::: + +Collect feedback during the workshop: +- Collect feedback from learners and instructors ([Example from a past + workshop](https://coderefinery.github.io/2024-03-12-workshop/questions/)). +- Convert feedback about lessons and suggestions for improvements into issues + so that these don't get lost and stay close to the lesson material. + +Collect feedback before you start a big rewrite: +- First open an issue and describe your idea and collect feedback before you + start with an extensive rewrite. +- For things still under construction, open a draft pull/merge request to collect + feedback and to signal to others what you are working on. + +Small picture changes vs. big picture changes: +- Lesson changes should be accompanied with instructor guide changes (it’s like + a documentation for the lesson material). +- Instructor guide is essential for new instructors. +- Before making larger changes, talk with somebody and discuss these changes. + + +## Use case: our lessons + +As an example to demonstrate the process of designing and improving lessons, we +will have a look at one of our own lessons: [Introduction to version control +with Git](https://coderefinery.github.io/git-intro/). + +- Initial 2014-2016 version + - and + - Amazingly they are still findable! + - Format: Slides and live coding. + - Exercises were separate, during afternoon sessions. +- Some time in 2014-2015 attended Carpentries instructor training. +- 2016: CodeRefinery started. +- 2017: Started a new repository based on the Carpentries lesson template (at the time using Jekyll). + - Exercises become part of the lesson. + - We start in the **command line** and only later move to GitHub. +- 2019: A lot more thought about learning objectives and personas. + - Also license change to CC-BY. +- 2022: Convert lesson from Jekyll to Sphinx. + - Using the tools that we teach/advocate. + - We can have tabs and better code highlighting/emphasis. + - Easier local preview (Python environment instead of Ruby environment which we were not used to in our daily work). +- 2024: Big redesign. We move the lesson closer to where learners are. + - Start from GitHub instead of on the command line. + - Start from an existing repository instead of with an empty one. + - Offer several tracks to participate in the lesson (GitHub, VS Code, and command line) and learners can choose which one they want to follow. + - Blog post: [We have completely changed our Git lessons. Hopefully to the better.](https://coderefinery.org/blog/2024/04/19/git-lesson-rewrite/) +- Next steps? + - Making the lesson citable following + [our blog post](https://coderefinery.org/blog/2024/07/30/lesson-cffs/). + - Improvements based on what we learn from this workshop. + +The overarching trend was to make the lesson simpler and more accessible - to +meet the learners where they are instead of pulling them to the tool choices of +the instructors. Looking back, we learned a lot and the learning process is +not over yet. + + +## Exercise: Discussion about learning objectives and exercise design + +:::{exercise} We work in groups but use the shared document as result (20 min) +1. As a group **pick a lesson topic**. It can be one of the topics listed here but + you can also choose something else that your group is interested in, or a topic + that you have taught before or would like to teach. Some suggestions: + - Git: Creating a repository and porting your project to Git and GitHub + - Git: Basic commands + - Git: Branching and merging + - Git: Recovering from typical mistakes + - Code documentation + - Jupyter Notebooks + - Collaboration using Git and GitHub/GitLab + - Using GitHub without the command line + - Project organization + - Automated testing + - Data transfer + - Data management and versioning + - Code quality and good practices + - Modular code development + - How to release and publish your code + - How to document and track code dependencies + - Recording environments in containers + - Profiling memory and CPU usage + - Strategies for parallelization + - Conda environments + - Data processing using workflow managers + - Regular expressions + - Making papers in LaTeX + - Making figures in your favorite programming language + - Linux shell basics + - Something non-technical, such as painting a room + - Introduction to high-performance computing + - A lesson you always wanted to teach + - ... +1. Try to define 2-3 learning objectives for the lesson and write them down. + You can think of these as "three simple enough messages that someone will + remember the next day" - **they need to be pretty simple**. +1. Can you come up with one or two engaging exercises that could be used to + demonstrate one of those objectives? + **They should be simple** enough people can actually do them. Creating simple exercises is not easy. + Some standard exercise types: + - Multiple choice (easy to get feedback via a classroom tool - try to design each wrong answer so that it identifies a specific misconception). + - Code yourself (traditional programming) + - Code yourself + multiple choice to see what the answer is (allows you to get feedback) + - Inverted coding (given code, have to debug) + - Parsons problems (working solution but lines in random order, learner must only put in proper order) + - Fill in the blank + - Discussions, self directed learning exercises +::: + + +## Great resources + +- [Teaching Tech Together](http://teachtogether.tech/) +- [Our summary of Teaching Tech Together](https://coderefinery.github.io/manuals/teaching-tech-together/) +- [Ten quick tips for creating an effective lesson](https://doi.org/10.1371/journal.pcbi.1006915) +- [Carpentries Curriculum Development Handbook](https://cdh.carpentries.org/) +- [Our manual on lesson design](https://coderefinery.github.io/manuals/lesson-design/) diff --git a/branch/main/_sources/lessons-with-git.md.txt b/branch/main/_sources/lessons-with-git.md.txt new file mode 100644 index 0000000..f91a0e9 --- /dev/null +++ b/branch/main/_sources/lessons-with-git.md.txt @@ -0,0 +1,217 @@ +(lessons-with-git)= + +# Lessons with version control + +:::{objectives} +- Understand why version control is useful even for teaching material +- Understand how version control managed lessons can be modified. +- Understand how the CodeRefinery lesson template is used to create new lessons +::: + +:::{instructor-note} +- Discussion: 25 min +- Exercises or demos: 20 min +::: + + +## Why version control? + +- If you are in CodeRefinery TTT, you probably know what version + control is and why it is important. +- The benefits of version control also extend to lessons: + - Change history + - Others can submit contributions + - Others can make derived versions and sync up later + - Same workflow as everything else + - Write it like documentation: probably more reading after than + watching it as a presentation. +- Disadvantages + - "What you see is what you get" editing is hard + - Requires knowing version control + +:::{discussion} Accepting the smallest contribution + +Question: if someone wants to make a tiny fix to your material, can they? +::: + +## Tour of lesson templates options + +There are different ways to make lessons with git. Some dedicated to +teaching: + +- CodeRefinery + - Example: This lesson itself + - Based on the Sphinx documentation generator + - [sphinx-lesson](https://github.com/coderefinery/sphinx-lesson) is + *very* minimal extra functionality +- Carpentries + - Example: + - Based on R and Rmarkdown + +Our philosophy is that anything works: it doesn't have to be just +designed for lessons + +- Jupyter Book + - Example: https://jupyterbook.org/ + - Note: is based on sphinx, many extensions here are used in CR lessons +- Various ways to make slides out of Markdown +- Cicero: GitHub-hosted Markdown to slides easily + - [Demo: Asking for Help with + Supercomputers](https://cicero.xyz/v3/remark/0.14.0/github.com/bast/help-with-supercomputers/main/talk.md/#1) + [The source](https://github.com/bast/help-with-supercomputers/blob/main/talk.md) +- Whatever your existing documentation is. + +**We like the CodeRefinery format, but think that you should use +whatever fits your needs the most.** + + +## [Sphinx](https://www.sphinx-doc.org) + +- We build all our lesson material with Sphinx +- Generate HTML/PDF/LaTeX from RST and Markdown. +- Many Python projects use Sphinx for documentation but **Sphinx is not limited to Python**. +- [Read the docs](https://readthedocs.org) hosts public Sphinx documentation for free! +- Also hostable anywhere else, like Github pages, like our lesson material +- For code a selling point for Sphinx is that also API documentation + is possible. + +Sphinx is a doc generator, not HTML generator. It can: + +- Markdown, Jupyter, and ReST (and more...) inputs. Executable inputs. + - jupyter-book is Sphinx, so anything it can do we can do. This was one of the + inspirations for using Sphinx +- Good support for inline code. Much more than static code display, if + you want to look at extensions. +- Generate different output formats (html, single-page html, pdf, epub, etc.) +- Strong cross-referencing within and between projects + + +## [CodeRefinery lesson template](https://github.com/coderefinery/sphinx-lesson-template) + +It is "just a normal Sphinx project" - with extensions: +- [Sphinx lesson extension](https://github.com/coderefinery/sphinx-lesson) + - adds is various directives (boxes) tuned to lesson purposes + - provides a sample organization and template repo you can use so that lessons look consistent +- Sphinx gives us other nice features for free + - Tabs: they are very important for us and allow us to customize in-place instead of copying everything and fragmenting lessons + - Emphasize lines: they make it easier to spot what has changed in longer code snippets + - Various input formats + - Markdown (via the MyST-parser), ReStructured text, Jupyter + Notebooks. + - Many other features designed for presenting and interacting with code +- It's fine if you use some other static site generator or git-based lesson method. + +:::{demo} Instructors go through the building and contributing process + +Depending on the course, instructors will demo what is roughly +exercise 4 below. Or a course might go straight to exercises. + +- Instructors decide what change they would want to make +- Instructors clone the repository +- **Instructors make the change** +- **Instructors set up the build environment** +- **Instructors build and preview** +- Instructors command and send upstream +::: + + +## Exercises + +Some exercises have prerequisites (Git or Github accounts). Most +instances of this course will have you do **1 and 2** below. + +:::{exercise} Lesson-VCS-1: Present and discuss your own lesson formats + +We don't want to push everyone towards one format, but as long as you +use Git, it's easy to share and reuse. + +- Discuss what formats you do use +- Within your team, show examples of the lessons formats you use + now. Discuss what is good and to-be-improved about them. +- Look at how they source is managed and how easy it might be to edit. +::: + + +:::{exercise} Lesson-VCS-2: Tour a CodeRefinery or Carpentries lesson on Github +- Look at either a CodeRefinery or Carpentries lesson + - CodeRefinery Git-Intro: [Lesson](https://coderefinery.github.io/git-intro/), [Github repo](https://github.com/coderefinery/git-intro) + - Carpentries Linux shell: [Lesson](https://swcarpentry.github.io/shell-novice/), [Github repo](https://github.com/swcarpentry/shell-novice/) +- Can you find + - Where is the content of the lessons? + - What recent change propsals (pull requests) have been made? + - What are the open issues? + - How you would contribute something? + - How would you use this yourself? +::: + + +:::{exercise} Lesson-VCS-3: Modify a CodeRefinery example lesson on Github +In this, you will make a change to a lesson on Github, using only the +Github interface. (Github account required, and we assume some +knowledge of Github. Ask for help in your team if it is new to you!) + +- Navigate to the example lesson we have set up: + [repo](https://github.com/coderefinery/sphinx-lesson-scratch-space), [web](https://coderefinery.github.io/sphinx-lesson-scratch-space/) +- Go to some page and follow the link to go to the respective page on + Github. (Alternatively, you can find the page from the Github repo directly). +- Follow the Github flow to make a change, and open a Pull Request + with the change proposal: + - Click on the pencil icon + - Make a change + - Follow the flow to make a commit and change. You'll fork the + repository to make your own copy, add a message, and open a pull + request. + +We will look at these together and accept some changes. +::: + + +:::{exercise} Lesson-VCS-4: Clone and build a CodeRefinery lesson locally +In this exercise, you will use Git to clone one a CodeRefinery lesson +and try to preview it locally. It assumes installation and knowledge +of Git. + +- Use this sample repository: + [git-intro](https://github.com/coderefinery/git-intro) (or whatever + else you would like) +- Clone the repository to your own computer +- Create a virtual environment using the ``requirements.txt`` + contained within the repository. +- Build the lesson. + - Most people will probably run: `sphinx-build content/ _build/` + - If you have `make` installed you can `make html` + - Look in the `_build` directory for the built HTML files. + +Overall, this is pretty easy and straightforward, if you have a Python +environment set up. The [CodeRefinery documentation +lesson](https://coderefinery.github.io/documentation/sphinx/) teaches +this for every operating system. + +This same tool can be used to build documentation for other software +projects and is pretty standard. +::: + + +:::{exercise} Lesson-VCS-5: (advanced) Create your own lesson using the CodeRefinery format +In this lesson, you'll copy the CodeRefinery template and do basic +modifications for your own lesson. + +- Clone the lesson template: + https://github.com/coderefinery/sphinx-lesson-template +- Attempt to build it as it is (see the previous exercise) +- How can you do tabs? +- How can you highlight lines in code boxes? +- How can you change color, logo and fonts? +- What directives are available? + +::: + + +## Summary + +:::{keypoints} +- Version control takes teaching materials to the next level: + shareable and easy to contribute +- There are different formats that use version control, but we like + Sphinx with a sphinx-lesson extension. +::: diff --git a/branch/main/_sources/notes-archive.md.txt b/branch/main/_sources/notes-archive.md.txt new file mode 100644 index 0000000..178256f --- /dev/null +++ b/branch/main/_sources/notes-archive.md.txt @@ -0,0 +1,1605 @@ +# Collaborative notes archives from workshops + +## August/September 2024 + +### Day1: Session 1 (13.08.24) - About lesson design, deployment and iterative improvement + +#### :calendar: Schedule + +| Time (CEST) | Title | EEST (UTC+3) | BST (UTC+1) | +|---------------|--------------------------------------------|---------------|---------------| +| 8.45 - 9.00 | Connecting time | 9.45 - 10.00 | 7.45 - 8.00 | +| 9.00 - 9.15 | Intro and Icebreaker | 10.00 - 10.15 | 8.00 - 8.15 | +| 9.15 - 10.00 | Lesson design and development | 10.15 - 11.00 | 8.15 - 9.00 | +| 10.00 - 10.15 | Break | 11.00 - 11.15 | 9.00 - 9.15 | +| 10.15 - 11.00 | Lessons with version control | 11.15 - 12.00 | 9.15 - 10.00 | +| 11.00 - 11.15 | Break | 12.00 - 12.15 | 10.00 - 10.15 | +| 11.15 - 12.00 | How we collect feedback and measure impact | 12.15 - 13.00 | 10.15 - 11.00 | + +#### :icecream: Icebreaker + +##### Check-in + +Which emoji best describes your current state of mind? [Emoji cheat sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) +- :Decaffed ... and going strong ... +- :coffee: 🤔 +- :100: (ironically!) :coffee: intake happening +- :smile: +- :tired_face: +- :coffee: :party: +- :coffee: :happy: +- 😪 +- just got zoom installed / before my coffee +- :smil- +- :sweat_smile: (+) +- :yawning_face: +- :is it morning already? +- :smile: +- :yawning_face: +- :nerded_face: +- 🥵 +- :smile: +- :sleeping: +- :sleepy: :coffee: :smiley_cat: +- 🥳 +- :coffee: +- :coffee: + +##### Introduction in breakoutrooms. + +- Name / Affiliation / Location + +##### About teaching + +What is the hardest thing about teaching for you? +- Knowing how "it's going", whether learners are happy or not (especially when teaching online) :+1: +- The preparation the night before. It is always much more that I would hope, no matter how prepared I want it to be :+1: :+1: +- Managing groups with vastly different academic backgrounds +- Teaching wide spectrum of skill level at the same time. :+1: :+1: :+1: :+1: +- Time management! (Knowing how much can fit in a sessions) :+1: :+1: +- General preparation time, how to fit it into the regular work schedule, and estimate how much time is needed for prep. +- How to reduce too much text into just the right amount +- Preparation of the session material and estimating the right amount of time for each section +- Getting learners to take the first step: sign up for and attend a workshop, when they don't think programming is a skill they can learn +- Getting learners to take the _second_ step: translating what they've learned in a workshop into something they can apply +- preparation and time management +- Engaging with the students which was much easier for me when I used to coach +- Finding the right depth for an unknown audience for "my topic" +- education background of participants and their learning objectives + +What is the best thing about teaching for you? +- Seeing when learner gets interested/curious about something and takes inspiration from the course. :+1: +- Seeing it works and someone can do something new. +- Motivated students grasping new stuff +- Students picking up and running with the matertial and skills I give them and using it for their own work. :+1: +- The "ah-ha!" moment when a student gets it! :+1::100: :+1: +- Learning from students who know about some topic more than you do. :+1: +- Being able to help people reach their goals, by showing them something new. +- Teaching is optimism acted out in the hope of making a difference both ways I suppose. +- The feeling of accomplishment when you see learning grow and implement the learnings :book: +- mutual learning and impact on learners :+1: +- Results and feedbacks / Mutual interests and interesting discussions +- mutual learning and I can also learn lots of things and new ideas from participants + + +#### :question: Questions + +##### General / Practicalities + +- Will the material be made available? + - Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/ + - Can I share them with a colleague + - Yes please :) + - Can I resuse them in my own teaching? + - Yes please :) +- Will these sessions be recorded? + - No, but the materials (see above) should include everything needed for self-learning. +- Can I get a certificate for this workshop? + - You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended. +- How often will we be talking in breakout rooms? I'm not in a place where I can talk, so if we're going to talk a lot I'll need to move offices + - We'll have about one breakoutroom session per episode +- +##### Episode 1: Lesson design and development + +Materials: https://coderefinery.github.io/train-the-trainer/lesson-development/ +**Discussion:** + +- When you start preparing a new lesson or training material, where do you start? + - I look at existing materials on the same topic, but chose/refine topics based on the perceived needs/interests of the presumed audience + - Outline of structure and Material collection for a new lesson :+1: + - What material I have already? (what other material is already out there?) + - Start by looking for related resources (documents, videos, courses, etc) to have a base data and better understanding of what have been done around the topic + - Know your audience + - Review existing material + - Think about learning objectives (to keep focus on essential things) + - Think of three things simple enough that they will be remembered the next day. Design around that. + - I write down the thoughts that I have and then go back and structure it. + +- What tricks help you with “writer’s block” or the empty page problem? + - Write anything down that comes to mind, sometimes draw something, looking out the window :) + - Do a mind map - what concepts do I want to get across? + - Starting small, for example a list of headings and then building around it. :+1: + - What does one know about the target audience and why should they be spending longer than 1 minute listening to what they will eventually get to hear? + - Get some inspiration from another source. + - Start with the three things above + - Start with the plan and the overview design + - Some kind of outline / main message(s) + - Start with three things. Three supporting points for each of these. +- Maybe you haven’t designed training material yet. But how do you start when creating a new presentation? + - Think about the learning objectives and try to break them down into steps + - Title, Objectives, target audience and Plan + - Some kind of outline / main message(s). Get as many images as I can, instead of words + - Draft an outline and use chatgpt to fill in details + - Example of how the teaching content is applied in a real-world context +- If your design process has changed over time, please describe what you used to do and what you do now instead. + - I look more at existing materials and try to get more information about the audience. Unfortunately getting information about the audience before the event is hard + - I used to start from the begginning and get from there but that often meant a very polished start and a rushed end. Now I try an overview first, then fil out sparsed details at every section + - Updating the data and tweak the presentation + - If I am teaching a small group (or one to one) talk to them before hand - find out what they know already, what they want to learn. +- What do you know now about preparing lessons/training/presentations that you wish you knew earlier? + - less is more. It's better to have 2-3 main messages rather than trying to show everything in one go :+1: :+1: :+1: :+1: + - how much practice time the learners need to master what's taught + - Don't worry about something going wrong. It often makes the lesson (and thus the material) more presistent in memory. :+1: + - Try and remove everything except what you want the person to learn + - That's a very tough part for me in the sense that I never know how much of an underlying "black box" is still ok.... + - Designing intermediate materials is hard, and requires putting some "gatekeeping" making sure that learners are directed to appropriate courses + - When I see a cool graphic, concept, slide, etc., download it and save it in my 'new-materials' folder to use later on! + - I have come to the conclusion that perhaps a more "agile" approach to developing materials (try to do design/teaching iterations quickly) might be the best way to go, but there are risks with this approach too + +**Questions** + +- From zoom chat: Can you expand on what a learner persona is? + - A defined example person described in terms of the materials you are preparing, making up a story about the background and interest of t + - Answer from chat: A learner persona is a blackbox which has a very simple algorithm inside: GIGO. + - Answer from chat: I think it's the same as ICP (Ideal customer persona) where you describe the learner as a customer + - Answer from chat: I'm a big fan of "How Learning Works" by Ambrose et al https://bookshop.org/p/books/how-learning-works-eight-research-based-principles-for-smart-teaching-michele-dipietro/18640868?ean=9781119861690 + - See also book: [Teaching tech together](http://teachtogether.tech/) +> CodeRefinery lessons: https://coderefinery.org/lessons/ +- From chat: Do you have an example of an instructor guide? + - One example from our [reproducible research lesson](https://coderefinery.github.io/reproducible-research/guide/) + - Another from git intro: https://coderefinery.github.io/git-intro/guide/ +- From zoom chat: Do you have a "measure" of how better are the new lesson compared to the old ones? Does it make sense to talk about measurements here? + - So far we only have daily feedback that we collect at the end of the day and we can compare that to earlier daily feedbacks. More about that in the last episode of today. But measuring this is indeed not easy and it also takes time to capture the effect during longer-term surveys. Some of the changes were more leap-of-faith than based on data. + - I guess that sometimes one can use "compelling arguments" instead of data to justify a decision +- Software Carpentry does teach using the command line, and gives a session on the command line before. What do you think about this approach? Are you stating that a 3-hour lesson about CLI is not sufficient to make people comfortable enough to use that for version control? + - Yes, good question. For CR we consider it a more advanced step: we do think people should learn command line, but it's for a different course. We accept some people might not know it or want to know it so adapt to that. + - In general, we've found the "you need X, but have to learn A, B, and C first" approach should be avoided if possible: people are busy, try to reach people where they are. + +:::danger +[Exercise](https://coderefinery.github.io/train-the-trainer/lesson-development/#exercise-discussion-about-learning-objectives-and-exercise-design) in breakoutrooms +::: + +- Room 1 + - Research data management + - Objectives + - Research life cycle + - FAIR principles (Findable, Accessible, Interoperable, Reusable) + - Exercise + - develop a data management plan (DMP) that outlines how their research data will be handled throughout its lifecycle. + +- Room 2: What is the difference between eating breakfast and sitting through a lecture? (Tip: Start by listing the similarities ...) +- Room2 : Making papers in LaTeX + - What is LaTex and how is it different from editors like Word + - Basic Structures + - How to find and use a template + - Including figure & table + - How to use references and labels + - Exercise: to create a new LaTeX document & edit it + - Excercise: common error messages: can you find the error in this code? + - Exce +- Room 3 + - GPU Programming (1 hour intro) + - Learning objectives: + - What is GPU programming. + - When is it usable, beneficial to use GPU programming? + - What are technologies to do GPU programming? + - [What are and how to manage typical issues] + +- Room 4 + - Git / Figures / Project management / data cleaning + - Chose data cleaning + - Three learning objectives: + 1. What do we mean by "clean"? How to identify it? + 2. Identify some common problems in a dataset + 3. Identifying and handling missing values/fields + - Exercise + 1. Discuss problems, find the most common ones + - In small groups + - What problems have you run into with datasets you've worked with? + - What problems can you imagine, or have you heard about from colleagues/news/social media? + - Report back, instructor collects all problems into a list + 2. Have a dataset to clean; a clean and a messy example + - (identifying) Using a visualisation or overviewing tool? + +- Room 5 + - Jupyter Notebooks + - Learning Objectives + - Can setup an enviroment you can reuse / can share with others / a project. + - The order you run the commands in needs to match the order of the code in the Notebook - otherwise you end up in a pickle. + - Why use a Jupyter Notebook? What are the advantages? Easy to use environment. + - Exercise + - Print variable assignments from different cells - show that the order you run the code is important. + - hand out a domain specific notebook that does some calculations and visualization to run and modify, to show that you can share easily + - show !pip install to add dependencies/features +- Room 6 + - Using GitHub without the command line + - Learning Outcomes: + - Be able to discuss changes before merging changes into the main repository. + - Publish a personal repository page ( I think its called intro repository) + - Share their script/notebook/code/small data on GitHub + - Homepage using GitHub pages or the README that becomes the "index page" of the GitHub user account page + - Learner personas: + - Check the Personas of the learners + - Somebody who has seen/heard of GitHub but hasn't used it yet + - Someone using it for their own work but struggling with collaboration + - Exercises: + - Upload/share an example dataset or script + - Review another collaborators pull request. + - Take part in the discussion on a pull request. +- Room 7 + Linux shell basics: why do we want to teach them? + (this took most of the time for the discussion) + - Learning objectives: + 1. Filesystem: Directory (CLI) - Folder (GUI) analogy + 1. Basic commands (which commands are basic? make a survey of shell histories and get the most common ones) + 1. Basic constructs (e.g., for loops, pipes, while loops... which ones are basic? See above) + +> Note from chat: Zoom timer: https://support.zoom.com/hc/en/article?id=zm_kb&sysparm_article=KB0068677 + +##### Episode 2: Lessons with version control + +Materials: https://coderefinery.github.io/train-the-trainer/lessons-with-git/ + +Poll options: I want to hear about: +- A: Why use version control for teaching materials +- B: Different template options +- C: How CodeRefinery does it; CodeRefinerys lesson template + +Poll vote (multi-select): add a `o` to your answer + - A: ooo + - B: oooooo + - C: oooooooo :ghost: + +Question to audience: if someone wants to make a tiny fix to your material, how hard is it? +- If my material is only in pdf format which is not online, then it is hard. +- I hope it is easy - my material is in GitHub. Nobody has ever done that though! +- Slides: hard to find, easy to edit; Git repos somewhat easy, unless they have to be built locally or with an action; HackMD easiest to edit. + - if you use something like google slides they are not that difficult to find + - known permanent address. Google docs et al fail on that/same for many pads. +- For this material today - very easy! e.g. https://github.com/coderefinery/train-the-trainer/pull/128 +- Template with an edit button in the HTML pointing to the source-code in the repo. + +**Questions/Discussion topics** +> Upcoming CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/ +> Please share with your networks, and let us know if you would like to co-teach a lesson (to support@coderefinery.org or in our [Zulip chat](https://coderefinery.zulipchat.com/)) + +- Changes to the material are sometimes not just tiny fixes. For example, one wants to present a slightly different selection of topics, but maybe some topics are "coupled" (perhaps naturally or perhaps just because of how they are presented), or change the general "theme" (e.g., life sciences vs theoretical physics) while keeping the actual topics the same. How could a lesson be developed to avoid having to do a huge rewrite? + - You can try to modularize your material and keep non topic specific parts non themed. E.g. where you explain the functionality, don't make reference to the example (not simple), so the example can be changed depending on the audience. +- What are the pros/cons of renaming a course / changing a repo name in GitHub? + - It should be relatively unproblematic since GitHub will forward to the new name. + - How long does Github keep the "old" name linked? Is there a max time it's blocked, or changed as soon as a new one appears with the name? + - in my experience it forwards "forever" until I create a new repo with the old name which will break the forward +- what should be in the readme for the git repo? (canonical address? contact points? license!) + - https://coderefinery.github.io/mini-workshop/2/documentation/#often-a-readme-is-enough-checklist + - I miss the url to the (main) repo in the readme + - Do you mean the link to the rendered (lesson) page? + - Link to rendered page: We often have this in the "about" section of the readme (see up right: https://github.com/coderefinery/train-the-trainer) + - this gets lost in a fork, doesn't it? so 20 folks forking and or reuploading the repo somewhere means the url gets lost? + - True, but they might want to have their own version rendered? + - yes, I have had issues finding and contributing to the "master" repo so all benefit. Else it gets cluttered. Both is valid + - Good point though, the link to rendered page should probably also be included in the readme for completeness; ah and the link to the repository too, yes + - so realistically we need a content folder and some more next to the readme as a best practice. sounds good! +- Is myst (markdown renderer) enabled by default in sphinx now? + - to my knowledge no. we add the "myst_parser" extension to conf.py. + +> Cicero: https://cicero.readthedocs.io/ +> Sphinx documentation: https://www.sphinx-doc.org/en/master/ +> Carpentries workbench for creating Carpentries lessons: https://carpentries.github.io/workbench/ +> This is the testing lesson Richard showed: https://coderefinery.github.io/testing/ +> And the corresponding repository: https://github.com/coderefinery/testing +> You can lean back and watch, exercise coming in a bit :) +> Richard will now edit our train the trainer material repository: https://github.com/coderefinery/train-the-trainer +> The Sphinx extension for CodeRefinery lessons: https://github.com/coderefinery/sphinx-lesson +> Empty lesson template to build your own lesson: https://github.com/coderefinery/sphinx-lesson-template + +**More questions** +- Does the coderefinery.org page built on sphinx? + - It's built also from markdown but it uses https://www.getzola.org/ (which is more optimized to render websites, but we could do teaching also with Zola or create the project page using Sphinx) + +- Is there a way to build and preview CR lessons without the command line? + - The GitHub workflow we use creates HTML from all branches. This means that one can push a branch to GitHub, preview it there, and then open a pull request. One thing that would be nice but we don't have yet is if a bot automatically posts the link to the preview to a pull request. + +- For VCS-2, for the Carpentries Linux shell example, Lesson, Github repo, to me it seemed as though the Sandpaper setup they have makes a very nice interface, complicates the relationship between source and output. E.g on the soucre page https://github.com/swcarpentry/shell-novice/blob/main/index.md I could only see to 'Prerequisits' and not 'Download files' on the page https://swcarpentry.github.io/shell-novice/. Perhaps I have missed something? + - I am sorry I don't know the new Sandpaper setup well enough to answer this question. + +- Do we have the instructions to build the lessons available somewhere to try out later? + - https://github.com/coderefinery/sphinx-lesson + +:::danger +Exercise VCS-1 (and VCS-2 (if time)) (https://coderefinery.github.io/train-the-trainer/lessons-with-git/#exercises) in breakoutrooms until xx:05 + +then short summary in main room and then break. + +Use the notes below. Collect a list of lesson formats and discuss what you like about each of them. +::: + +- PDF slides by a presentation program +- pdf slides with beamer in latex under source control. +- Markdown slides via Github +- CodeRefinery template +- Carpentries template +- Google Slides +- git-book +- [Jupyter Book](https://jupyterbook.org/) - allows creating a structured reference website using RST/Markdown, including Jupyter Notebooks to show result of running code +- [mdbook](https://rust-lang.github.io/mdBook/) - create simple/minimal website using Markdown +- [Binder](https://mybinder.org) - allows learners to run their own live version of a github repository with Jupyter Notebooks, with only a web browser +- Jupyter notebooks and jupyterhub platform +- Jupyter + Nbviewer and custom css (read only) + Binder link (hands on) +- RMarkdown +- Quarto Slides +- [Reveal.js](https://revealjs.com/) - write slides in HTML (also supports markdown) + - Example: https://bl-presentations.erambler.co.uk/2024-02-21-idcc24/ +- [Remark.js](https://remarkjs.com/) - write slides in markdown + - Example: https://bl-presentations.erambler.co.uk/2024-02-19-idcc-pids-workshop/ + + +Room discussions: +- Room 1 + - (https://smc-aau-cph.github.io/SPIS/README.html) + - CodeRefinery template + - Shared notes & blogs + +- Room 2 + - demo the exercise + +- Room 3 + - Mix of JupyterLab, Terminal within that, and traditional slides + - Jupyter + RISE (benefit: slides that are editable and executable live) + - Challenges + - present code in an interactive way + - handle lots of images/ figures without too much additional overhead when setting up the material + +- Room 4 + - Material and tools depend on instructors + - Some slide building tools + - https://revealjs.com/ + - https://remarkjs.com/ + - https://github.com/rust-lang/mdBook + - Using flat git repos without fancy styling to make it easier to edit but still version controlled + +- Room 5 + - Using R as a GIS: https://github.com/nickbearman/intro-r-spatial-analysis + - Workbook: RMarkdown, Slides: Quarto + - No continuous intergration + - Having a jupyter nbinder link to test the notebook + - repo lives on codeberg in this example + +- Room 7 + - Ex 1: + - Sphinx, similar to CR + - Sometimes pdfs generated with beamer package (or from pptx and odt), but blows up repository size if in version control + - Ex 2: + - Content + - CR: Content commonly found int the content folder + - SC: Mostly under episodes + - Question that came up: + - is CR/Sphinx approach mostly for technical topics? What about language. + - I guess by our nature it's focused there. But probably could be used for others (I guess it it's much easier to use git in a technical audience.) + + +##### Episode 3: How we collect feedback and measure impact + +Materials: https://coderefinery.github.io/train-the-trainer/feedback-and-impact/ + +**Questions to audience** + +- What tricks/techniques have you tried in your teaching or seen in someone else's teaching that you think have been particularly effective in collecting feedback from learners? + - preparing a survey and emailing it to participants as soon as the event ends (usually get <50% of answers but it's a representative enough sample) + - do engage with the audience, give them the time to get the courage to speak up + - Be the audience yourself + - yes! some problems/issues I don't notice as instructor, only as listener + - Have time (e.g. 5 min) in the session to fill out the feedback form + - If the course/workshop has several days/sections do a couple questions every change, then a full one afterwards + - "Traffic light" feedback (e.g. for pacing or progress on exercises): give each learner two different coloured post-it notes for in-person, or use emoji for online, to indicate a current status +- Can you give tips or share your experiences about how to convert feedback into changes or actionable items? + - ask questions about things you know you don't know + - “Don’t let the noise of others’ opinions drown out your own inner voice.” — Steve Jobs +- When people ask questions / get stuck with a specific step. Is there a typo I can change there and then in the workbook? + - Being able to fix small things on the fly helps sometimes, otherwise open issues if working on github + - If multiple people have the same question, then this is an indication that I should look at this in more detail +- How do you measure the impact of your teaching? Any tips or experiences about what you have tried or seen other courses do? + - "How likely are you to recommend this workshop to others? (0/5)" + - Check the 'Garbage Out' bin, what you find there will be what went across. The rest will be history... +- Anybody knows of good resources on survey design? Please link them here. + - "Our job is to figure out what they're going to want before they do... Our task is to read things that are not yet on the page." - Steve Jobs + +**Questions/Discussion points** + +- Feedback is necessary to design good lessons. Improvement can only be done iteratively. So the faster the iteration (design/teach), the better. But on the other hand, I cannot constantly bomb our community with training event emails. So I would like to try proposing a course many times a year, but I don't want to spam everybody many times a year. + - :+1: + - With CR we also have a calendar that can be imported to different calendar applications, where we add all workshops: https://github.com/coderefinery/calendar/ +- Does an even split of too fast / too slow mean speed is about right?! + - I take it to mean "it's roughly where it should be". Would be better to accomdate the sides better though... (we do try to design for a broad audience: some easy stuff, some advanced stuff, so people can make their own path) + - It could also indicate that the prerequisites/scope are not well defined :+1: + - Based on long term surveys we also know though that even though the workshop might have been to fast, people appreciate having "heard things before and know where to find them later" + - perhaps the even split between too fast/too slow is ok only if the majority of votes goes for "just right" :+1: +- One of the most important disciplines in journalism is to challenge your working premises. (Bill Keller) This applies equally to learning as well. + - Participants can be encouraged to write some posts on LinkedIn. If it is helpful some blurbs can be created for pre and post-workshop to generate more traction for Code Refinery and future participation. + - Ask participants if they use Dev.to, hashnode etc to blog their work or use twitter etc to have a memory of their work. +- Do you have any suggestions for prerequisites? I try to make them clear, but occasionally people attend who clearly do not meet them. :+1: + - I guess it depends how much it matters for the workshop itself. If you have group exercises etc, it probably matters? , lecture style maybe not so much?; important is that the participants themselves know that prerequisites exist and if they meet them + - Sometimese people that do not meet the prerequisites join to get to "know what they don't know", find out where to find information on topics they might get interested in future etc + - Other suggestions? Viewpoints? :) + - Thank you - things for me to think about there :-) + - With CR's latest ideas, we try to make the prerequisites clear, but there is no capicity limit: it's OK if people drop by and are less than prepared: it's livestream, anyone can come. We try to have something for these people, too: learn what you are missing, why you might want to study more in the future. + - Any thoughts on applying this to a more practical focused course, with a total capacity limit (i.e. not like CodeRefinery). +- Everytime you do a course on CodeRefinery, think of it as trying to bake a new cake with an old recipe with no idea about the individual taste preferences of the one you bake the cake for. Then, you will not experience too many surprises. Fine-tuning the recipe for one cohort still remains the 'old recipe' as far as the next 'new cohort' will be concerned. C'est la vie. + - nice analogy! +- Question from chat: For examples 2 & 4, would you also consider using something like a Likert scale? E.g. Rate how well you agree with the statement "My code is more reusable as a result of attending a CodeRefinery workshop" (from 1 Strongly disagree to 5 Strongly agree) + - Thanks! I am new to Likert scale and will read up on it. In my experience numbered answers can be useful for reporting. But I also like questions where we ask for what actually to change. +- Comment from chat: Richard, your point crowns the point of having CodeRefinery, With Radovan's and Samantha's acquiescence assured, I would like to suggest you wear a crown going forward, especially for the CodeRefinery session. Do we have a deal ? + - I don't quite understand this + - I *think* it's a tongue-in-cheek-comment (joke) but I am not sure..... +- What is the ideal way to allow people to interact while course is going on in the main online session, i.e. without a breakout room? Taking a pause or discussion in the background? + - I've had some success with WhatsApp groups for a course - particually ones that run over 4 (or 2) sessions. + - A quick survey/quiz + - Question to the audience that we take time to answer but it helps to show the answers +--- + +### Wrapup + +- Thank you for active participation :) + - We'll continue answering questions after the workshop and make the cleaned up (no names etc) available from the materials +- Next session **Tuesday August 20, 9 CEST: Tools and techniques adopted in CodeRefinery workshops** + - we will talk about on-boarding, install help, roles, screensharing, sound, collaborative notes +- All workshop materials will stay available (after the full workshop also on Zenodo :tools:) +- CodeRefinery community: https://coderefinery.zulipchat.com/ +- If you want to co-teach with us in the upcoming (or next) CodeRefinery workshop (https://coderefinery.github.io/2024-09-10-workshop/); or just want to learn more about this opportunity: Send your name and e-mail address to support@coderefinery.org; we will contact you! + +### Feedback about todays session + +What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session: +- Lesson design approach +- I liked the backwards lesson design, gives a name to a practice I've already been doing :+1: :+1: +- Lessons from code refinery on lesson design. Learning about Sphinx. +- Collaborative notes and anonymized archive of notes. +- it's nice to have a community to discuss these kinds of problems +- Hearing the variety of tools people use for slides (PDF, Quarto, Beamer etc.) +- Good intro of the tools, the jargon and the pedagogical philosophy of teaching tech. +- The absolute openess in having everything publicly available - materials ofc but also questions, discussions, feedback, ... +- Thinking about all content being available publicly and as a git repo +- Thanks for explaining the HedgeDoc interface, with view and edit options + - Is there anyway to come back to this document later (e.g. tomorrow) and see what has changed since now? So I can see if any other questions have been asked/answered? + - There is a "revision" point under "Menu" up right, which shows you different versions of this document +- Modesty: the gentle art of enhancing your charm by pretending not to be aware of it. - Oliver Herford +- + + + +What one thing would you improve about this session? +- Perhaps some more interactivity but can be hard to plan and time + - We'll see what we can do. +- _Maybe_ mix the breakout groups up for each breakout session (although there are advantages to consistency too) :+1: + - yes, pros and cons! For me, having consistency worked well this time. + - Likely we will have different participants next week, and a bit of mixing will happen naturally. +- The pace of the presentations could be a little tighter (the pace is good for a discussion though) +- Richard's voice was only 80% audible + - Sorry to hear that. It seemed fine on my end. Will check better for next session. +- Hands on simulation and collaborative notes +- I found it difficult to follow the presentation and the collaborative notes at the same time + - We will highlight the collaborative notes more in the next session. Our strategy usually is to say to focus on the "teaching part" and use the notes only when needed. Since you can go back and also check the notes later. + - My problem is that I want to follow both since I don't want to miss out on anything. As such, I have both windows (zoom and the notes) open side-by-side. Since there is near-constant real-time typing in the editor, and as such visible movement on screen, I get constantly distracted. This makes following the event quite exhausting. +- Heads up to participants on using the break out rooms on voice interaction and screen sharing. + - Do you mean that we should have mentioned it more clearly in the pre workshop email? +- I found it hard to follow with so many things going on at once... + - A collaborative document being changed at the same time as... + - Someone speaking and explaining content at the same time as... + - Chat in a different application at the same time as... + - Content changing in a termin application. + - Thank you for the feedback. We will remove the Zoom chat out for the next session and explain the use of the collaborative notes more. +- Make more use of defining and then making sure the learning objectives are met + - True we did not talk about them much, will pick that up better for next session. +- UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. - Dennis Ritchie. You need to do a lot to prove that to be wrong, simply put. +- Allocate some time for learners to type in the answers so that we don't have to listen and type at the same time. + +Any other comments? +- It's great to hear other people's experience + - Good to hear :) +- Looking to meet you onsite if there are any events and get more emails from you :) + - We will keep you informed :) +- Thanks for putting this together, I got a lot of inspiration for my own courses + - Good to hear :) +- I didn't know where to ask questions. It would work best *for me* to do it in zoom chat as that's the application that I'm watching in.. + - Sorry for that, just to figure out why: Did you join a bit late? + - No. Perhaps I just missed that or it was too quick for me or something? + - Ok, sorry. Will try to make this more clear in next session. + - Perhaps also because there were so many things going on and jumping around. For me, the zoom chat is the constant (and obvious) place to ask questions while watching a shared screen, trying to find the right place in a moving collaborative document is difficult. It tears my attention into too many pieces. :+1: +- Had a lot of content that assumed extant knowledge that I didn’t have. This wasn’t in the pre-requisites. + - Do you have examples? + - Yes! The code refinery templates and even just the way of doing that. I was expecting more on "when designing a lesson you should think about these steps" rather than this is how we do it and this is our tool for doing it. I guess I should have read the pre-workshop content better? + - Ok, thank you for your feedback. You are right that we actually had some content that for sure would have been easier to follow for people with background knowledge about a certain topic. + - "If you are in CodeRefinery TTT, you probably know what version control is and why it is important." - extant knowledge, why not just add a sentence or two? + - Please can you update in preparation for the next workshops so that I can decide whether or not they will be right for me? + - Yes, we will think more thoroughly about this and send the info in the next email going out Wed/Thu + - Thank you! +- Lots of the content was relevant to code refinery but not the wider topic (e.g. it was how to design a code refinery lesson and not how to design a lesson as stated in the session title) + - We thought of the content of showing one way of doing things, ie "what we have learned", if you have suggestions on how we could make that more clear on the event page, please let us know :) + - "in a code refinery lesson" in the lesson/workshop description? +- When you have pre-written “thank you for your active participation” it feels fake! + - He, that is true, did not think about that. Thank you for the feedback. I would not have added it if Radovan and Richard would not have provided good feedback from circling the rooms. +- I found it vague and disorganised and difficult to follow. It felt like the instructors were presenting the content for the first time and didn't know what to do next. + - Thank you for your feedback. This is not the first time we have this training, but it is the first time in this constellation/way. The way of teaching may also sometimes make it seem new to instructors. +- I really liked the active exchange with other participants, but I also would have enjoyed a bit more technical content in the presentations. In a sense it felt less like a 'training' and more like a get-together :+1:. + - Thank you for your feedback. We thought the name "workshop" would combine the training and exchange nature of this event. But maybe it didn't do so enough? Do you have suggestions on how to clarify it on the event page? + - Well, the 'train the trainer' title created the anticipation of being trained ;) don't get me wrong, I liked the exchange, but I felt that the training aspect fell a little short. imho the workshop would benefit from a little more (instructional) content that is presented in a more structured way by the instructors (as opposed to 'crowd-sourced knowledge' that is collated in a loose collection of questions, notes and links) + - Other than that, you could add another section on the main page, sth like 'Workshop structure: we aim for a mix of modular presentations and work in small groups. The latter will be done in breakout rooms - be prepared to switch on your camera and have a fruitful exchange with fellow participants!' + - Thank you for the suggestions, will add something like this :tools: + - > Added : https://github.com/coderefinery/train-the-trainer/commit/03308595436e636b3bb37ed9d1f0dee39eeccd0f +- My understanding (so far) of what (unlike the competition) CodeRefinery DOES NOT seek to exemplify - +https://images.ctfassets.net/rxqefefl3t5b/2k45BFtw4sBMlBfjr1OZ90/5c6ecd3628a43b0cdc79815f665e224a/Screenshot_2023-05-02_at_09.35.23.png?fl=progressive&q=80 +- My understanding of what (unlike the competition) today's session of CodeRefinery DID exemplify - Definition of 'Workshop' from the Oxford dictionary of the English language "a period of discussion and practical work on a particular subject, in which a group of people share their knowledge and experience" +- In my experience, even for the most seasoned Programmer coding, by its very nature, is nothing trivial, this being a simple straightforward fact just like there is no such thing as an egg which is a cube. I mean there is a reason why not just about everybody is a poet either. But, other minds have pointed this out without having to first explain why the universe is what it is in a way that could be understood without effort ... https://i.pinimg.com/originals/7b/7e/c4/7b7ec4b91d2cf9d8e1b064678d205467.jpg +- The inclusive environment feels very welcoming. Keep up the good work! + +**Thank you all for your feedback! Highly appreciated!** + +--- + +### Day 2 : Session 2 (20.08.24)- Tools and techniques adopted in CodeRefinery workshops + +#### :calendar: Schedule + +| Time (CEST) | Title | EEST (UTC+3) | BST (UTC+1) | +|---------------|---------------------------------------|---------------|---------------| +| 8.45 - 9.00 | Connecting time | 9.45 - 10.00 | 7.45 - 8.00 | +| 9.00 - 9.15 | Intro and Icebreaker | 10.00 - 10.15 | 8.00 - 8.15 | +| 9.15 - 9.25 | About CodeRefinery workshops | 10.15 - 10.25 | 8.15 - 8.25 | +| 9.25 - 9.55 | Collaborative notes and interaction | 10.25 - 10.55 | 8.25 - 8.55 | +| 9.55 - 10.10 | Break | 10.55 - 11.10 | 8.55 - 9.10 | +| 10.10 - 10.45 | Workshop overview, roles, onboarding | 11.10 - 11.45 | 9.10 - 9.45 | +| 10.45 - 11.05 | Sound | 11.45 - 12.05 | 9.45 - 10.05 | +| 11.05 - 11.20 | Break | 12.05 - 12.20 | 10.05 - 10.20 | +| 11.20 - 11.50 | How to prepare a quality screen-share | 12.20 - 12.50 | 10.20 - 10.50 | +| 11.50 - 12.00 | Outro and feedback | 12.50 - 13.00 | 10.50 - 11.00 | + + +#### :icecream: Icebreaker + +##### Check-in + +Which emoji best describes your current state of mind? [Emoji cheat sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) +- :-) +- https://media.istockphoto.com/id/148421550/vector/bored-emoticon.jpg?s=612x612&w=0&k=20&c=uo5KBTqdJZbBQb_Xldhzuovx5t08fHfGR7dw7TCk90I= +- :saluting_face: +- :sleepy: +- :coffee: +- :umbrella: +- :cocktail: :coffee: +- :seedling: +- :tired_face: +- :sun_with_face: +- 🥴 (:woozy_face: not converted?) +- :coffee: +- :sunflower: :book: +- :satisfied: +- :coffee: +- :coffee: +- 🥱:tired_face: +- :bread: - I am baking bread today so I have been kneading dough while listening! + +##### Introduction in breakoutrooms + +Name / Affiliation / Location + +##### Teaching + +- Do you teach and organize teaching alone or with others? What would you prefer and why? + - Coming together is a beginning; keeping together is progress; working together is success. – Edward Everett Hale + - These days always with others. Alone is easier to prepare but almost always is harder during it. + - Teaching with very diverse partners, it can be challenging to find a common language with people very different than you. + - I teach alone, in the future there will be more collaboration with multiple team members. Both approaches have their pros and cons. + - Both has its own distinct advantages + - Most of my teaching is on my own, as a freelancer its more expensive to work with colleagues than to deliever a course on my own. + - Teaching together, learns from each other, feedbacks to improve + - Not formally taught yet, only given presentations actually . + - collective teaching would benefit the teachers with collaborative curriculumn and experiences sharing. + + +- If applicable, have you seen any challenges when teaching together and how to overcome them? + - It actually requires preparation, + - Is it about teaching or about inspiring ? Discover the answer and get inspired ... + - It's like being in a band: you might be great at improvising and your band-partners might be great at improvising too, but a bit of rehearsing makes even the impro gig much better + - Need to plan before session, difficult if people don't 'plan' in the same way, e.g. with the same time frame. + - Heterogeneity in learners make it impossible to get the same result from everyone. + - In fact, the same applies to teachers :D + - Teaching together requires to have similar opinions on how to teach. I share vews only with ~40% of my colleagues I think. +- No Teaching experience but it is good to give the outline of the lessons beforehand and learning goals. + + +--- + +#### :question: Questions + +##### General / Practicalities + +- What is this document for? + - Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts) +- Will the material be made available? + - Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/ + - Can I share them with a colleague + - Yes please :) + - Can I resuse them in my own teaching? + - Yes please :) +- Will these sessions be recorded? + - No, but the materials (see above) should include everything needed for self-learning. +- Can I get a certificate for this workshop? + - You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended. +- How often will we be talking in breakout rooms? + - We'll have about one breakoutroom session per episode + - BR 1 : The Zoom chat does not work for the breakout room so we should take note of that. No webcam/mic = expect silence. + - Thanks for notifying! This was not intended. Turned the chat back on. + + + + +--- + +#### Episode 1: CodeRefinery + +Materials: https://coderefinery.github.io/train-the-trainer/coderefinery-intro/ + +- (questions continue here) +- Is there the plan to build capacity / be paid to deliever courses? + - We've discussed it but right now we don't have many people who could accept money to do this (and maybe shouldn't, because of their jobs). But, we would encourage others to use our materials as "independents" to deliver paid courses + - One idea we have had is that paid courses could be delivered through the DRA (link below), who we know. Basically, DRA could find instructors and handle the money transfers (If someone wanted a paid course, we could help find someone to do it through DRA or independently) + - :smile: +- Have you come across DRA, https://digital-research.academy/, Heidi Seibold, Joyce Kao who are doing similar work? I can connect you if you like. + - Yes we have been discussing about possible future collaborations and are already sending possible clients their way (we, as a project cannot take money) :+1: + - Excellent! :-D :smile: +- . + +#### Episode 2: Collaborative Notes + +Materials: https://coderefinery.github.io/train-the-trainer/collaborative-notes/ + +- So anyone can type anonymously? + - Yes, as long as you do not log in, you are Guest XXX + - And at least in our hedgedoc case you cannot log in so you will always be anonymous. You can do [name=xxx], to add your name to a comment + +- Test of +1 + - +1 :+1: :+1: + - :-1: a test + +- You are hosting your own version of HedgeDoc, and Hackmd.io is a similar (free) option. What are the limitations of the free hackmd.io? Should each center install their own HedgeDoc instance? + - It **seems** the free version of HackMD has gotten worse lately. It works still well enough with a few people editing at the same time. + +- Have there every been problems with the anonymity and CoC? + - We haven't had any issues so far. + - With a different anonymous tool in a bachelor course, we had issues with anonymous participants (participants were posting slurs and unsafe links). The course organiser decided to stop allowing anonymous tools. + +- Why not google documents? + - Google documents are actually setting a hard limit for simultaneous writing, no more than 100 concucurrent editors. I am unsure if microsoft onedrive word documents would allow more users writing at the same time. + +- What's the most people you have every had on HackMD / Hedgedoc? + - I believe about 200 active participants? + +- What are your thoughts on using the build-in Zoom Q&A? + - We haven't tried this, in part because the way we do streaming now (you'll see in session 4), participants aren't in Zoom so don't have access to that. The doc-format works pretty well though, when we keep it in this limited "write at end" format. + +- How do you see what has changed? e.g. if leave the session at the end, can I come back tomorrow and see X has been added? e.g. a diff for this maybe? + - In the menu up right there is revision, it does show the document and changes at different time step :+1: Thanks! + - We recommend people only write at the bottom (and since we answer things live), so as a first level approximation you find where you were and read below that. Think of it more like chat than a full document. (Yes, we do revise questions at the end) + +- How about flinga boards or similar tools? + - My take is that the simplicity of a simple text document wins over free-form in-person-workshop-like tools. + - There's miro, can be a bit confusing though + +- How does this work with small groups, e.g. 10-15 people? + - Good question: it can be hard if people aren't rigorous about it, people start only using chat/voice. So there seems to be some lower bound in size but we haven't tested this much + - And if the instructors never screenshare it to show what goes on it, then seems to be less used. + - And if there aren't other people to read/answer it during the session (perhaps less likely in a small course), it seems to be less used. + + +:::info +Breakoutrooms until xx:55 + +Exercise/discussion: https://coderefinery.github.io/train-the-trainer/collaborative-notes/#exercise +::: + +- Breakout room 1: + * Use of etherpad for collaborative discussion. + * Use of slido for polling and quizzing. + * Presemo as a slido alternative (https://www.aalto.fi/en/services/presemo-a-fully-web-based-classroom-participation-system) + * Use of text based approach for questions rather than live can be helpful if there is a language barrier issue. + - A good teaching session which had many questions coming spontaneously to the teacher is a non-entity of sorts. If the overall flow of feedback / questions increases it could indicate that the session will not prove to be a helpful experience. A signal that generates noise is, well, noise, if calling a spade a spade signals anything. Note that the 'overall' bit and the 'to the teacher' aspect are important. Both the best and the worst teaching session have two things in common: a teacher, and the fact that NO Materials of any kind are used, ie speech is the only channel of communication via a common language. The only difference is that it is not the same teacher, at least not in the same session at the same time. + + Another less mentioned, but perhaps more relevant indicator of a great session is the simple fact that at the end of the session EVERYONE feels empowered, NOT tired. This is not an easy to quantify thing, but screams out the quality of the experience loud. More often then not, such sessions differ little from each other, apart from in terms of the theme / topic and the participant mix. It ends up being the 'keep your cake and eat it too,' of sorts, not quite the far less amusing post-bombardment devastation scenario in the wake of a take it or leave it go at anything. + + - profanity in collaborative documents where people can add content anonymously could be a problem (happens very rarely, fortunately and somewhat surprisingly) + +- Breakout Room 2: + - Good experiences with Zoom polls + - Handling questions in hybrid setups: all participants (on-site and online) ask questions in written form + - Collaborative notes can be challenging when conducting a course alone (without teaching assistants) :+1: + - Providing a method to ask questions anonymously can make asking easier for shy participants + - Questions can give valuable feedback on how the course is going + - Online collaborative whiteboarding platforms such as Miro + - Large monitors are useful for this not to have to drag a "periscope" around + + + + +- Room 4 + - good experience with whatsapp chat for questions. since most learners have the app already and one thing less to install and set up + - reply to question is a way to handle multiple questions at the same time but it works well for smaller groups + - experience with collaborative docs in in-person workshops: voice questions might "win" over the document + - "seeding" questions may help to not have an empty document + - it can help somebody to start and create a structure which helps others to see and follow + - we discussed the Carpentries sticky notes system (red sticky note: signal tech issues and use for feedback, green sticky note: signal that exercise worked and for positive feedback) + - Nice summary of sticky notes system: https://teachtogether.tech/en/#s:classroom-sticky-notes :+1: + - What is the success rate of in-person workshops after COVID? Discussion: Teachers prefer in person and learners prefer remote or recorded to spool back and relearn. + + +- Room 5 + + - Good experience with Collaborative tools as HackMD and HedgeDoc while teaching with no bad feedback + - When used with smaller groups works best as one-way, like sharing links with students and so on + - Needs to be done as a team, quite difficult if teaching alone + - Most useful when online/hybrid + - Anonymisity is important for transparent feedback and no biasis in classrooms + - Not very collaborative but useful to share history or jupyter notebooks live https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush + - Used Flinga before that seems like Figma and also onsite teaching using sticky notes + - There's miro.com but can be a bit confusing, more for brainstorming than for teaching + - Using quizzes apps like Kahoot is beneficial while teaching to have more engaging students + - + +- Room 6 + - teaching teenagers (in presence) but using shared pad becomes quickly very chaotic, so only usable for short moments when answering very precise questions + - Yeah, I can imagine. For CR we try to keep it in this very limited format (all questions bullet points, only add to the end) and I think that helps. + - using shared notepad for small workshop (5-10 people) to explore common thematic (mainly technical) to keep a shared notes and condense aftwerward (and publish on wiki to archive) + - Difference between teaching in person and online. Some people prefer in-person and sometimes you have no option but to organise it online. + - There are sometimes cultural differences and learners feel shy to ask / question the knowledge of the Teacher, so shared notes are a good way to safely ask questions. + + +Questions continue: + +- Have we demonstrated how we do polls in HedgeDoc? Add your vote by adding an `o` + - yes: oooo *(in session 1)* + - no: + - :smile: + - not sure: o + + +#### Episode 3: One workshop, many perspectives + +Materials: https://coderefinery.github.io/train-the-trainer/overview/ +Next CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/ + + +:::info +#### Exercise until xx:39 +https://coderefinery.github.io/train-the-trainer/overview/#discussion +::: +- Room 1 + - Send pre-workshop email with pre-requisite instructions on what should be set-up beforehand. + - But, also mention that if help is needed for set-up, we will be ready before the session officially starts. + - Discussion on whether we push to work in a pre-ready environment (e.g. Binder, Colab) or in their own environment. + - Lots of help needed both before and after. + - Installations: as much as we can provide ready made environments for the learners, maybe installations will be something that the learners will face sooner or later. Maybe one should teach more about installations? + - My only cherished role in a teaching-learning session is the that of one who is living the moment as if there were no tomorrow. What cuts all ways really is that “By failing to prepare, you are preparing to fail.” ― Benjamin Franklin. A helpful motto: “When one teaches, two learn.” — Robert Heinlein. The best experience cannot be given, it can only be allowed to flow its way, so get out of its way. + + +- Room 2 + - Frequently, a single person fills all the roles for a single or multi-day workshop + - Collaboration with different centers/ universities can be challenging + - Preparing participants: it's essential for the instructor to go through the demos and be sure that they will work (no unpleasant surprises live). This can be extended to advance-prep for participants. + - Best experience is to hear (live or in feedback notes) some positive things directed at you :) + - Fully prepared environments (eg self-hosted JupyterHub) can make preparation for participants easy + + +- Room 3 + - Some students have problems with setuping the environment. Maybe having a step by step instructions could help. But some students don't want to "start" the course before hand. + - Preparing the environemnt before hand ensures everyone is onboard from day 1. The same thing happend in CSC training sessions and another session Peng attended. + + - Had experience in attending as teacher and student in previous workshops + +- Room 4 + - knowing the background of the audience is helpful + - Try and ask in advance of the background of the audience. Do a poll at the start of the workshop. In person one can do it interactive. + - among co-instructors: discuss topics and flow + - if more people are involved, it can help changing roles from time to time to see different perspectives + - preparation is key + - Circulate instructions beforehand + - Do a poll before session: Have you installed (QGIS) successfully? + - Push hard to do this in the welcome email + - communicate clearly to the participants + - +- Room 5 + - We've all taken most roles + - How to prepare in advance? + - Meet and discuss once or twice + - Make a pre-survey to check for interest and background + - Going through the materials + - Checking the toolkit (zoom) + - Agree on the reponsibilities and back-up plans (bit of scenarios planning) + - How to prepare trainings in advance? + - Collect resources and prepare the workshop plan + - Having the material readily available online ans sharing it + - Making a pre-survey + - What was the best workshop experience for you as learner, helper or instructor? What made it great? + - learner + - Engaging and practical workshop with more exercices and follow-up theoretical part explanations + - helper + - When the instructor is well prepared and as helper ther's only typos to fix and interesting questions to answer + - Assist the instructor, coordinate the collaborative notes, and make sure that the time is respected + - instructor + - I have a colleague whom I've ran the same workshop a few times already, goes quite smoothly now and we've made a few changes. Hard to reach that point with new colleagues but getting there + - Students/participants were engaging with the material and many good feedback collected even some of them asked for the next workshop + + +- Room 6 + - What has made a great experience for you as a learner/helper/instructor? + - Common ground between learners & teachers + - + - Motivation + - Teaching is much more enjoyable when the learners want to be there + - I spend a lot of time at the start of a workshop making sure learners feel that the content is possible for them to understand and master + + +Poll: I have joined a CodeRefinery workshop before: (add an `o` for your answer) +- yes (within last 2 years): ooooooo +- yes (longer time ago): oo +- no: oooooooo +- + + +(questions would continue below:) +- What is the motivation / advantages of streaming workshop versus using zoom? + - We'll cover this more in week 4, but roughly: zoom became unmanageable and essentially quiet once things got big. Streaming allowed "one to many" communication with no limit, and collab notes allowed better interaction anyway. By separating the rooms, it was more pleasant to teach. Videos could be released immediately since there was no risk of privacy of participants. There could still be in-person/online small groups who have "watching parties." +- What are the blue red and green font colors here, does it symbolify anything or just a convention HedgeDoc uses? + - Visual separation of formatting, mostly. (It helps to quickly realize you've missed/ mistyped a control Markdown symbol etc.) + - Yeah, it's bascically "code highlighting" for markdown. No special meaning but quite convenient for us. +- Is this next workshop only for team leads or also open for helpers and coordinators? + - You mean the next session of this workshop or the upcoming "CodeRefinery workshop"(this one: https://coderefinery.github.io/2024-09-10-workshop/)? + - The upcoming workshop coordinators are alredy working, but can be joined if you are interested + - As helper roles we currently only have "collaborative notes helper", which is all about helping to answer questions in the collaborative notes + - We do have some co-teaching slots open :) + - If interested: join the discussion in our chat: https://coderefinery.zulipchat.com/#narrow/stream/316508-coderefinery-tools-workshop/topic/Fall.202024.20CodeRefinery.20workshop + +- Can a person have multiple roles in a workshop as a helper and a teacher? + - Yes, many teachers also contribute to the rest of the workshop by answering questions in collaborative notes. :+1: + - Some teachers also host a local classroom in week one and do their teaching in week two of the workshop + - Roles that do not go well together are broadcaster/director/host and instructor (goes well until there is a problem; co-teaching solves that partly) + + +#### Episode 4: Sound +https://coderefinery.github.io/train-the-trainer/sound/ + +- To me, Richard is a bit quieter than the other two :+1: :+1: :+1: + - to elaborate: I think that the audio coming from him is missing some mids + - Do you have any links about this kind of evaluation and adjustment? + +- Do you suggest / recommend a specific headset(s) with mounted microphone? + - in our experience headsets with a microphone will almost always be better than a separate microphone sitting on the desk or in the monitor + - + +- Speakers have different tones of voice and speaking styles, is there a recommendation or experience from CR workshops for how this is adjusted and catered to environemnts for listeners? + - Yeah, people's voices are different and we haven't gone as far as voice training or improving. + +- How to change the volume for speakers? Tried Zoom settings and system settings and didn't help. + - From linux I can use different pulsemixers `pavucontrol`, `pulsemixer` to set the gain to above 100%. I'm not sure the equivalent on other OSs but + +--- + +:::info + +Exercise until xx:10 +https://coderefinery.github.io/train-the-trainer/sound/#exercises +::: + +- room 1 + + - Practically, no typical headset is designed or can capture the technical purity of human voice within its natural environment. But one needs to understand the polar pattern of the (specific) microphone or how much of the signal will be picked up by the microphone from different directions, a sine qua non when it comes to mitigating unwanted sound sources to bleed into the signal. + +For best results, keep the right direction & distance to your (directional) mic. Usually, that’s between 15-30 cm to get get a natural sound. A microphone records everything it can, also silence, so check the headphone output BEFORE adjusting the gain, in some specific cases aim for a dry sound, ie the influence of the room or how audible the room is on the recording ! Finally, adjust the mix between dry and room sound, or change the frequency response in tandem using a compressor to reduce the dynamic range of a signal for a more consistent listening experience = the quietest parts of your signal will appear louder by reducing the loudest parts. + +It is all about one thing and one thing only - love your voice, let people fall in love with the acoustic quality of your charm. So remember: GIGO, it matters! + +- Room 3 + - Had different headsets and we could see the difference (bluetooth low quality) + - How to change the volume? + - It's surprisingly hard to get more control than the basic slider you see in the apps! You need to look. + +- room 4 + - headset is probably better listening experience but they can be uncomfortable to wear during long meeting days :+1: + - Yeah. Luckily only instructors + - Therefore breaks are non-negotiable + - loud keyboard can be an issue + - if one has a silent room that does not echo, it can be ok to teach without headset + - on Linux I am using `pulsemixer` to adjust levels and `pavucontrol` to change outputs/sources + - mic modes on mac + - check default microphone for zoom. + + - room 5 + - Most tricks help tuning yourself but hard to do it as a group. Perhaps doing a short recording. + - Yeah. Some independent recording/playing aronud, but also asking for advice. I would do small group/one-on-one things. + - Background noises cancellation tools or wise choice of quiet environments + - Audio check with colleagues or through the app with the audience saying numbers for example + - Zoom or Teams have sound checks but work different in the app than the browser. They also work different across Operating systems + - Some sound issues might be related to network speed or stability, also to RAM available. Worthwhile to try and control those as well + - Make it welcoming for the audience to give you feedback on the audio and other settings, give reminders + + +#### Episode 5: How to prepare a quality screen-share + +Materials: https://coderefinery.github.io/train-the-trainer/screenshare/ + +- If your Zoom does not support "share portion of screen", sharing a tab and resizing it to portrait for yourself is a possible workaround (this at least works when joining the call from Chromium browser) + - Another workaround is to use an editor/IDE that displays multiple panels in one window and can show a web page, code files and terminal session +10 +- Is 'share a portion of your screen' where you draw a box in Zoom to share a section? + - yes :+1: + + +- When using zsh, one can run something like this in a terminal + ``` + tail -n $NLASTCOMMANDS -f ~/.zsh_history | sed 's/^.............../LAST COMMAND:/g' + ``` + (I place this in a window under the main terminal, I use i3) + +- I am a bit confused on what platform you are putting this code? + - Radovan is using Linux with (I think) the "i3 window manager". It can be quite involved and there is lots of personal customization here. +- When teaching with a custom prompt, is it worth starting with the default (that your learners will see) and explicitly mentioning "I change these things to make it clearer when teaching" + - One should always comment on what may be different. Thing is "default" may look different for many people :+1: + - "I am _not_ going to teach you how to customise your prompt, but here's an online tutorial, be prepared to lose several days of your life..." :laughing: + + +- Now I can't see the last line in the terminal + - Yep, that's a problem. It can be good to keep a buffer on the bottom of the screen. + - If you move your mouse outside the Zoom window, the controls should go away. But still a good note. + - My mouse was on another screen. + - Ok, thanks. + - I think one can also make the zoom bars not auto-hide (then it won't display under), but that is annoying also since it wastes space. + + +- Does anybody still use shellshare? Does it work? + - We in CR haven't used it much but we have seen it. + +- Does the stacking of the screens work on windows? + - Don't know unfortunately + + + +:::info +Exercises (done together) +https://coderefinery.github.io/train-the-trainer/screenshare/#exercises + +Write your cool tips and ideas below. +Stay after xx:00, to +::: + +- To be safe, I have created on my computer an account that I use only for teaching, so I do not need to do any manual set up +- share history or jupyter notebooks live (5-10 secs refresh rate) into a git repo. Share the link with the learners so they can catch up https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush + +--- + +### Wrapup + +- Next session Tuesday August 27 9 CEST: About teaching & cool things we all would like to share +- All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development) +- CodeRefinery community: https://coderefinery.zulipchat.com/ +- Cool gems session: If you want to share something, please edit your registration and fill it in there (link to modify in registration confirmation); or e-mail to support@coderefinery.org +- If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14:00 (Europe/Stockholm time) + + +### Feedback about todays session + +What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session: +- Sound and screen share optimization as well as relevant tools and good practices for online instruction. “While you may be unable to control your users’ mindset, you can anticipate it, and make sure that your user experience caters to it.” - Jonathan Cherki +- Nice opportunity to (re)think about my online teaching setup :+1: :+1: :+1: +- Other ways to display command history :+1: +- Did not know that bluetooth gear had so much latency! :+1: +- A good reminder about headsets with microphones +- Nice and friendly teaching. Thank you! +- Screen share with command history and terminal customisation +- Really useful tips on sound and screen sharing :+1: +- Nice experience share +- very useful and practical tips! +- Easy to follow along and filled with useful tips on sound, video etc. +- + +What one thing would you improve about this session? +- Just digging to find something: I have read some of the things you have talked about here already in some blog posts, so perhaps these sessions are not as shokingly full of new content as I imagined (but actually sharing experiences is something I can't do by reading a blog post) + - Perhaps: could you link some blog posts or other sources for what you have discussed so far? If it makes sense. Not sure. +- Talking about interface optimization approaches, which applies to sound as much as to visuals or any other aspect either for that matter, it might offer a perspective to bear in mind the concept of introducing asymptotic complexity increment. The latter would mean the goal is measuring how fast the effort of engaging, on one or more of the three parallel levels of interaction, must change to reach higher levels of partial certainty on the correctness of the implementation of the method in question, in this case the pedagogical paradigm. For the former, lower is better I guess, or in this case, in the intended sense, slower is faster. Let us consider an abstract example: People liked using the search engine Google (a Google session to put it in a fancy way) in the early days because it was as simple as it could get, a literally featureless entry point with no bells and whistles. That was the level of its visible complexity, or rather Google set a bar as low as it one could have, and then any higher point of VISIBLE complexity that was to be introduced, such a move would only be on the path of an asymptotic curve curving towards the set bar, never reaching it, as far as the entry point is concerned. We still see the same level of complexity when we fire up google and we never feel distracted to start with, except for the rather forgivable nuisance of the GDPR conformity pop-up notice which appears only AFTER the first move has been made, and thankfully it works plain and simple from there on (unless one starts feeling lucky, pun intended). Now, think about Youtube ... the user experience complexity is a totally different matter, the same company today (unfortunately) yet one now has a steadily worsening engagement experience. Good learning sessions tend to be more of the Google search engine experience and a far cry from the current Youtube trend I would opine. Or, to sum it up and keep it sweet and simple, it helps to identify the limits of human-human and human-technology interaction, within the framework of any applicable technology-technology interaction and joy is the result of respecting those limits. Wishful thinking ? +- Bring the cat back! + - I wish it came, but it's been resting all morning! I don't bother it or stage apperances... +- Maybe having a digest/ summary of previous iterations of this session might be interesting. I feel a lot of experiences have been exchanged and a lot of techniques/ tools have been mentioned. Spending some time in compiling this into a selected list and adding it as content to the course itself might be worthwhile. + - Good idea! We will write a blog post about this workshop and will include a summary of all discussions there :) +- Possibly have some command line examples from Windows rather than (just) *nix? I will look at the screenshots after the session. :+1: :+1: + - Also, a thought if you do do breakout sessions with this work, do one for Unix, one for Windows, one for Mac as an option. +- I could not follow the part Radovan showed codes (Radovan is using Linux with (I think) the "i3 window manager".) +- .. + +Any other comments? +- Looking forward to the topics of following sessions. +- Looking forward to the next sessions! +- Thank you! +- Relax, nothing else matters, live a life and have fun ! If you obey all the rules you may end up missing all the fun. 'The best way to predict your future is to create it.' - Abraham Lincoln :+1: + + +### Day 3 : sessiion 3 (27.08.24) - "About teaching and cool things we all would like to share" + +#### :calendar: Schedule + +| Time (CEST) | Title | EEST (UTC+3) | BST (UTC+1) | +|---------------|---------------------------------------|---------------|---------------| +| 8.45 - 9.00 | Connecting time | 9.45 - 10.00 | 7.45 - 8.00 | +| 9.00 - 9.15 | Intro and Icebreaker | 10.00 - 10.15 | 8.00 - 8.15 | +| 9.15 - 9.45 | Computational thinking | 10.15 - 10.45| 8.15 - 8.45 | +| 9.45 - 10.00 | Break | 10.25 - 11.00 | 8.25 - 9.00 | +| 10.00 - 10.30| Teaching philosophies | 11.00 - 11.30 | 9.00 - 9.30 | +| 10.30 - 11.00 | Co-teaching | 11.30 - 12.00 | 9.30 - 10.00 | +| 11.00 - 11.15 | Break | 12.00 - 12.15 | 10.00 - 10.15 | +| 11.15 - 11.50 | Sharing teaching gems (voluntary) | 12.15 - 12.50 | 10.15 - 10.50 | +| 11.50 - 12.00 | Outro and feedback | 12.50 - 13.00 | 10.50 - 11.00 | + + +#### :icecream: Icebreaker + +##### Check-in + +Which emoji best describes your current state of mind? [Emoji cheat sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) +- ... +- :sleeping: +- :coffee:+2 +- :robot: +- Still little sleeppy :) +- 🥴 (:woozy_face: still not converted 🤷‍♂️) +- Our planet could be a cube. It has six sides to it. It must be a cube. A cube it is, this Blue Planet ... just wondering ... +- 🦾 +- :sweat_smile: +- computer says no :-) some network trouble +- running late, and participating from a :train2: + + +##### Introduction in breakoutrooms + +Name / Affiliation / Location + +##### Best classroom experiences + +As a learner or teacher; what was the best workshop/lesson/seminar you have attended? What made the experience great? + +- Room 1 + - First summer HPC streamed workshop (as a teacher). Somehow the first felt the best + - CSC HPC summer workshop + - story telling teaching approach +- Room 2 + - NVIDIA DLI Course on Deep Learning + - very enthusiastic instructor + - intuitive and very accessible way of showing technical details and fostering deeper understanding + - a lot of hands-on material and smaller coding exercises + - Anything as long as its interactive and somehow enjoyable from both teacher and learner sides +- Room 4: + - EPCC MPI Distributed training workshop. + - Lots of hand on coding / experience gained. + - Very interactive instructor who also discussed ideas for more personalised cases of distributed computing. + - Coderefinery RSE course + - relevance of topic to my current work. + - Dynamic / friendly / positive teaching style. + - Modular Code Development; very instructive + - Some CSC courses / LinkedIn learning courses + - up to date materials and topics. + - Good way to merge theory with practicalities without making learner feel bored (Example: Jonathan Reichental) + - Challenging information to learn more and research about the topic + - Trainers are the experts in the field + + +:::success + +##### Episode on teaching gems + +If you want to share or demo something about tools and techniques you have found helpful in your teaching, please add your name/initials and rough topic below for smooth transition. + +> Note: It does not have to be your tool or your idea, this episode is meant to share experiences and discover new things. You also do not need any slides or materials, a story will do fine :) +> Length of the stories will be depending on interest, but be prepared to fit it into 3 min (shortest possible). + +- RD: teaching clock +- RB: [Containerized teaching setup](https://github.com/bast/teaching-setup) + - Isolated home dir is a good idea! +- AVM: [Screenkey for showing keyboard shortcuts](https://www.thregr.org/wavexx/software/screenkey) + +::: + +--- + +### :question: Questions + +#### General / Practicalities + +- What is this document for? + - Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts) +- Will the material be made available? + - Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/ + - Can I share them with a colleague + - Yes please :) + - Can I resuse them in my own teaching? + - Yes please :) +- Will these sessions be recorded? + - No, but the materials (see above) should include everything needed for self-learning. +- Can I get a certificate for this workshop? + - You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended. +- How often will we be talking in breakout rooms? + - We'll have about one breakoutroom session per episode + + +--- + +#### Episode 1 : Computational thinking + +Materials: https://coderefinery.github.io/train-the-trainer/computational-thinking/ (Link to slides in the middle of material) + +##### Questions to audience + +How might breaking down a complex problem into smaller parts change your approach to problem-solving in your current projects? + +- Avoids cognitive overload +- I used to give an example about this in workshops of cutting long tree into pieces from top to avoid that it falls and destroy a house bloc. +- Easier to start on something small +- Each individual part is familiar and can take existing solutions. +- Only focus on the new things +- One can lose oversight of where is supposed to be getting to due to problems with summation of biases introduced during the solving of the parts. +- . + +Can you think of a research project where identifying patterns in your data led to new insights or breakthroughs? +- Multi-targeted drug design where you need to identify both chemical and biological pathways/patterns +- Distilling complex physics problems into simpler 1D statistics is very often done. +- I used to do bioinformatics, pretty much everything in biology is about patterns in strings of charachters (DNA, proteins). Finding those patterns and using them is the way to go +- Pattern recognition DOES NOT lead to new insight, it is new insight which allows for the recognition of a 'pattern', the latter being an allocation of possible bias. +- +- .. + +What challenges do you face when trying to simplify complex concepts in your field, and how do you decide which details to focus on? + +- Absence of a terminology / jargon to describe a new idea. :+1: +- Similar to above, when teaching often students know what they want to achive, but don't have the termonology to express it, so working through what they want is helpful, after teaching them some termonology. +- Whatever is most useful to the learner first? +- I work with researchers in different fields. I don't always fully understand their domain knowledge but I can take the basiscs or generalities and get code that works for them +- A very practical problem is trying to resist going for a coffee in the midst of taking a shot at a complex concept, in the hope that the true details are to be found in the coffee. +- not all information is easy to find or a lot of conflicting information or even sometimes imformation explosion + + +How do you determine the priority of tasks when designing algorithms for your academic projects, and what criteria do you use to ensure that the most critical tasks are addressed first? + +- Working chronologically when going through a problem - start at the beginning. +- What gives the more insight with the least effort can be a nice start +- Talk to colleagues and Subject matter experts to understand various perspective to decide and prioritize. +- Logic will get you from A to B. Imagination will take you everywhere. - Albert Einstein. +- .. + +##### Questions from the audience + +- About the 4 core concepts, is this based on the model of how human brain works and perceives vision / abstract ideas? + - I don't know if it's based on how the brain works, but it's related to creating a framework for solving programming programs that has been extrapolated to solve any other problem as well. + +- Devil's advocate question: cooking (by recipe) actually employs all four principles outlined here and has done so since before the advent of computers. Why then is this concept presented as "computational"? + - Random aside, this is an interesting connection to our "cooking metaphor to HPC" +- Devil's answer to the Devil's advocate: Great question, cooking, as far as the act happens in the Devil's kitchen, does not employ numerical algorithms. The Devil introduced the computer precisely to make man lose apetite for that what is cooked in the Devil's kitchen to be served to all. Only then can the Devil eat the cake and keep it too ... + - Well, an algorithm without numbers is still an algorithm, i.e. a set of rules :) + +- Are there other names for this technique? I may have missed something crucial, but it strikes me as 'logical thinking' in a way. + - Yes, you could also just see it as problem solving. Most people know how to do it and if you've worked with programming, you've probably applied it. It can be the case that it's very obvious to some, but not to others. + +- Any chance we can ge a link to the slides? + - They are in the course material: https://coderefinery.github.io/train-the-trainer/computational-thinking/ :thumbs_up: + + +##### Exercise questions to discuss + +1. Conceptually would the strategies provided by computational thinking help you in completing tasks more efficiently? +- Room 1: + - divide and conquer technique + - We discussed what happens if you *don't* use these, since they are so natural +- Room 2: + - in some cases yes, if the task is not too small + - not sure if more efficiently but it does help at least getting strted + - Computational thinking is an extension of what others have called solutionism: the belief that any given problem can be solved by the application of computation. Whatever the practical or social problem we face, there is an app for it. - James Bridle +- Room 3: + - Helps in starting the task. + - For many it is the normal way to do problem solving. Also in Agile & Scrum methodlogies. +- Room 4: + - Yes, it helped me during my scientific research to manage multiple projects and research publications simultaneously. + - + + +2. Do you think that the effectiveness of computational thinking depends on the person’s personality type? +- Room 1: + - yes, we agree it's quite different. But good vision and motivation this can be effective +- Room 2: + - yes, laying out all the steps necessary to achieve an overall goal can be very daunting; some people are not good at/ comfortable with following fine-grained instructions + - once the problem is broken down, different personalities might choose different ways to tackle the parts + - The degree to which something, that is a result of what one means by 'Computational Thinking,' is successful in producing a desired result, that is success, cannot be a function of personality. +- Room 3: + - Yes. Different people have different ways to communicate. + - Online tools vs pen and paper +- Room 4: + - We are all agree that it depends on the personality type but it could be learned and trained + +3. Would this type of thinking be an option for you to integrate into your current workflow? +- Room 1: + - Yes; we didn't know the name explicitly; but we use it + - It's quite important for +- Room 2: + - I'm already doing it implicitly :smile: :+1: :+1: + - Writing a program is like writing a song, its all about the tune, lyrics are merely the necessary nuisance a coder needs to put up with. The latter can, if so written, result in a lot of noise. +- Room 3: + - Easy if you are working alone. But different team may have their own ways of working (inertia). One way would be then to gradually show the rest of the team its effectiveness. + - https://teamtopologies.com/key-concepts + +- Room 4: + - We are using it in our daily life so it's already an option for us, only the terminologies are a bit new. + + +#### Episode 2 : Teaching philosophies + +Materials: https://coderefinery.github.io/train-the-trainer/teaching-philosophies/ + +Questions to discuss: +- Share your approach to teaching and your teaching philosophy with your group. +- Please share your tricks and solutions in the live document for others. + +Additional ice-breaker questions: +- What is your motivation for taking this training? +- How structured or informal are your own teaching needs? +- What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching? +- What other skills need to be taught, but academic teaching isn’t the right setting? + +#### Breakout Room exercise + +- Room1 + + - Motivation + - For best practices in teaching, learning from each other, collaboration + - Learning applied tech is like an apprecentiship: there is theory, but real learning happens by co-working with others. + - Worse is better: teach what can be used more quickly and it can be improved later + - + - I think there are two bits of teaching - teach the basics and terminology so people know what they want to know, and then teaching how to find out how to do things like Richard said - how to find answers yourself. + - Using Jupyter notebooks - good for learning a technique, but not for learning the basics. + - Possibly command line usage has a branding problem - "programming other programs"? + - the skills we learn in CR training are expected to stay , it is not exam oriented + +- Room 2 + - State objectives clearly and repeat them a few times + - Try to keep it informal, interactive, flexible + - Helps when having practical tasks in mind for the materials taught + - Leave some reasoning to the learner, not always giving full answers + - How to deal with frustration though: try some personal approaches, more clues... + - The mediocre teacher tells. The good teacher explains. The superior teacher demonstrates. The great teacher inspires. — William Arthur Ward + - Teaching kids to count is fine, but teaching them what counts is best. –Bob Talbert + +- Room 4 + - Question 1: What is your motivation for taking this training? + - Currently do instruction, wanting to improve as an instructor and helper when conducting software carpentries. + - Planning to start some side hustles providing online courses and why not joining the CR in the near future + - Question 2: How structured or informal are your own teaching needs? + - More recently, follow software carpentries, but look into what aspects can be tailored to keep to different time slots. + - I used to be more informal in the past, repetetive practice sessions. Would like to be more structured given the teaching tools. + - I've done life-coaching and some teaching but I feel i'm both of them + - Question 3: What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching? + - Smaller size, and more targetted. + - Collaborative tools and targeted audience working with small groups + - Academic probably focuses on an audience with a more focused/narrow background, while this style encompasses a wider audience. + - Academic teaching keeps theory and practical lab sessions very separate, whereas carpentries combine both. + - Question 4: What other skills need to be taught, but academic teaching isn’t the right setting? + - Public speaking, collaborative meeting skills + - Industrial cases and related work skills + + +#### Episode 3: Co-teaching + +Materials: https://coderefinery.github.io/train-the-trainer/co-teaching/ + +- In general: Co-teaching is a beast with at least two personalities each of which + * demand higher preparation requirements + * face remarkable complexity in terms of coteacher coordination + * in the virtual component face shortcomings related to the technical equipment and the failure of the human factor +* Co-teaching requires the framework of co-operative learning. Team teaching does not by default translate into parallel learning, and vice versa. + +- Re: CodeRefinery in-person beginnings -- I agree with the "didn't work so well in-person", I'm not sure if it's that we weren't as ready for it, or that the different characteristics made it not work so much + +- How do the downsides compare to a single instructor monologuing? + - That's a great question! The main difference is that a single instructor can teach himself to be good (i.e. not just boring monologuing) **alone**, while for teams of 2+ to work well, **everyone** needs to be baseline-competent. So the effort to avoid downsides gets reduced if (and only if) all team members share it. + + +:::info + +Exercise/Discussion: https://coderefinery.github.io/train-the-trainer/co-teaching/#exercise + +Questions: +- Have you already tried this or similar model in your teaching? +- Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best? +- Have you tried or seen a different model for two instructors to present? Please share with us how it works. +::: + +- room 1 + - We have tendend to do presenter/interviewer more + - challenges are co-teaching with different personalities +- room 2 + - Main challenge: finding enough personell :smile: + - It's not always possible/feasible to have colleagues co-teaching + - A combination of both, but presenter and interviewer could be difficult to plan an to follow + - Guide and demo-giver with technical / non-technical roles could be nice + - How to plan the guide and demo-giver + - First guide, then demo + - Demo, then guide describes + - Alternative model: main presenter + 'technical expert' + - main presenter introduces concepts from a birdseye view and passes on to the technical expert for additional details, experiences and answers to questions from the audience + - We frequently do a classical division: on person in presenting, one or more are answering questions in the chat; there is rarely any interaction between them however + +* As has been pointed out by Paolo Freire, in general, ‘education is suffering from narration sickness’ ... ‘The outstanding characteristic of this narrative education, then, is the sonority of words, not their transforming power’. Perhaps one approach could be to rephrase the question after having the answer: It is not apriori about the model implemented, it is about whether that what was implemented was judged aposteriori to have succeeded in becoming, or at least could pretend to have done so, the intended context matched model implementation it probably was computed to be. + +- room 4 + - the co-teaching approach does not seem to be widely practiced + - it can be interesting to see "mistakes" which are less likely to happen in solo-teaching? + - co-teaching can be nicer for audience but maybe more stress/anxiety for instructors to prepare? more stress in terms of not knowing all the questions in advance. less stress worrying about forgetting something. + + + +#### Teaching gems + +(scroll up to find the green box "Episode on teaching gems") + +What's your favorite way of teaching? Any nice tools you use? + +Has anyone found a nice online tool to draw? +- I love this tool suite https://excalideck.com/ + - For drawing https://excalidraw.com/ +- I have seen Miro ... +- I think the Code Refineries use something for their graphics that looks a bit 'cartoony' - but I cannot remember what it is called! + - Drawn on remarkable and then coloured and tidied up in Inkscape. :+1: +- I am a big fan of remarkable. I think sharing option is fairly good. Unfortunately bit expensive tool. + - true, for me it was worth it already for the pdf annotation for research papers, cannot read on computer screen +- https://webwhiteboard.com/ +- https://www.youtube.com/watch?v=4-l8MY5kYGc +- Figma and Kahoot are useful as well + +Screenkey: [Screenkey for showing keyboard shortcuts](https://www.thregr.org/wavexx/software/screenkey) +- Is there a Windows version people can recommend? + - I found this list of alternative for windows users like me: https://alternativeto.net/software/screenkey/ :+1: +- I sometimes use the on-screen keyboard already provided by the OS :+1: + +### Wrapup + +- Next session Tuesday September 3rd 9 CEST: About teaching & cool things we all would like to share +- All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development) +- CodeRefinery community: https://coderefinery.zulipchat.com/ +- If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14 CEST + +- Preparations for next week will be sent out by e-mail + +### Feedback about todays session + +What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session: +- The co-teaching lesson and experiences from others +- Discussions were quite good, had a nice group +- Breakout rooms and collaborative tools +- Computational thinking and co-teaching are interesting ideas! I have seen it before, but never knew or even recognized it was a method. +- Thanks for group discussions working with my chat only interaction! :smile: +- .. + +What one thing would you improve about this session? +- Minor point - it would be useful to have the teaching gmes box at the bottom of the document rather than the top - tricky to scroll between! In the end I opened two windows which was easier. + - Thanks, yes agree. Also had that problem, but did not want to move it in between. +- The meaning of teaching "philosophy" wasn't very clear, felt more like teaching "styles" + - Thank you, we will take that into consideration +- Some prepared slides to present for an intro about the topics + - You mean in addition to the materials? To use in the beginning of each session? +- The [*instructor views*](https://coderefinery.github.io/train-the-trainer/teaching-philosophies/#instructor-views) segment could be named as additional material, if it was not meant to be discussed within the course. + - Thank you, we will take that into consideration + +Any other comments? +- Keeping it short and sweet: If at first you don't succeed in teaching, try to explain it like you're talking to a room full of cats. Caveat: In a room full of computational thinkers maybe if you tell students that the brain is a computational device that is forbidden, they might get excited and start using it. + +### Day4: Session 4 (3.09.24) - Streaming and video editing + +#### :calendar: Schedule + Time (CEST) | Title | EEST (UTC+3) | BST (UTC+1) | +|---------------|---------------------------------------|---------------|---------------| +| 8.45 - 9.00 | Connecting time | 9.45 - 10.00 | 7.45 - 8.00 | +| 9.00 - 9.15 | Intro and Icebreaker | 10.00 - 10.15 | 8.00 - 8.15 | +| 9.15 - 10.00 | Why we stream & Behind the scenes | 10.15 - 11.00| 8.15 - 9.00 | +| 10.00 - 10.15 | Break | 11.00 - 11.15 | 9.00 - 9.15 | +| 10.15 - 10.35 | Video Editing | 11.15 - 11.35 | 9.15 - 9.35 | +| 10.35 - 10.55 | Exercise: Video Editing | 11.35 - 11.55 | 9.35 - 9.55 | +| 10.55 - 11.10 | Break | 11.55 - 12.10 | 9.55 - 10.10 | +| 11.10 - 11.30 | Open Broadcaster Software(OBS) introduction | 12.10 - 12.30 | 10.10 - 10.30 | +| 11:30 - 11:50 | OBS setup & what next | 12.30 - 12.50 | 10.30 - 10.50 | +| 11.50 - 12.00 | Outro and feedback | 12.50 - 13.00 | 10.50 - 11.00 | + +#### :icecream: Icebreaker + +##### Check-in + +Which emoji best describes your current state of mind? [Emoji cheat sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) +- :coffee: + +- :runner: +- :tired_face: Tired! +- :nerd_face:![](https://) +- ![](https://notes.coderefinery.org/uploads/58bfdc31-ac86-4172-aef4-b7b4bd762533.png) +- :cloud: :tea: + +##### Introduction in breakoutrooms + +- Name / Affiliation / Location + +What's the most number of people you have taught to? +- 20 at a time, with 1 asleep, 2 fidgiting with some silly device and the rest were... well... staring at their good luck... straight ahead it was of course, right before them. +- ~35 +- ~80 in a lecture in a previous (lecturer) role, 26 in a training course setting +- ~30 +- ~50 in training spaces and more than 100 for public audience talk +- 35 (software carpentry) +- CodeRefinery answer: The biggest ones are maybe 200-300 people. "small" for a stream is ~100 people. + +What's the most number of people you have taught with? +- 5 or so +- 2 or 3 in total +- 3, as in three, none of them smiling. I wish I could figure out why... it was such fun really... +- 7 +- 2 or 3 +- 3 (helpers, not really co-teaching) +- CodeRefinery answer: our biggest workshops are something like 10-20 people helping out in many different roles. + +How can you divide teaching into separate independent tasks? +- By content blocks, having roles like main and assistant... +- Having responsibility for different sections of the course. +- Wow, now thats what we call a question... bravo... indeed, how does one separate sleeping and snoring into separate independent tasks... +- Course, exercices, resources, tools and forms. +- Different people teach different topics +- CodeRefinery answer: the big logical blocks are instructors, in-person and breakout room helpers, and Notes-questions answers. + +What’s the most interesting or useful thing you’ve learned from an online workshop, and how have you applied it/planning to apply in your life or work +- Having breaks every hour or so +- New approach to screensharing, using the 'portrait' approach +- Manage breathing: reduce stress and use silence to let the audience grasp what you're saying +- Well, the most interesting or useful thing I’ve learned from online workshops is how not to conduct a workshop, or at least some elements of the same, and I have applied this understanding by engaging in the global effort to discover more about how not to conduct a workshop, or at least some elements of the same, with the motto: That's one small step for a man, one giant leap for mankind.. + +#### :question: Questions + +#### [Why we stream](https://coderefinery.github.io/train-the-trainer/why-we-stream/) + +- If during streaming there is no interaction between the teacher and the audience, why don't we just record the lectures and stream them? So one can do a better job, perhaps? + - Streaming it making it a "thing" that's a group experience. It feels good to be a part of it, so we hope that encourages people to actually attend. All the mass Q&A is fun, and the audience helps to make it easier to present. Still, this is a good question. + - I really appriciate it being "a thing". If it was just recorded, I would say I would watch it tomorrow, and then I never would. + - But then you can just fake it, and still have all the breakout rooms and collaborative document and so on. I appreciate the value of having a proper "event". + - I think I follow you, but if you pre-recorded the talking bits, then the presentors couldn't change what they do based on the feedback in the shared document. + - true, but I assumed that the teachers were too busy to actually do that. The more (less )division of labor between the teachers and the helpers (or collaborative document editors), the more (less) sense it makes to pre-record - IMHO +- What interaction options do 'streamers' use, e.g. on Twitch/YouTube (not Code Refinary)? + - I'm besides chat and things that happen in chat, I'm not sure. The Notes-doc is definitely unique to us. +- Streaming is a kind of exercise for the movie star type. If you cannot be one, act like one, pretend, fool the listener into thinking you are one, take their brains and emotions under control. And if they don't leave the session with tears of love for learning running down their chubby cheeks you know who to kick for doing a job just that bit worse than it should have been necessary. +- Have you kept track of streming stats? like how many people logged in and stayed troughout, how many interacted? + - Yes please, it would be good to see the stats + - Here is stats [repo](https://github.com/coderefinery/workshop-stats) + - Thanks, I get a 404 error, is it private? + - No, I don't think so. https://github.com/coderefinery/workshop-stats + - Still get 404. Does it work for anyone else? + - Yeah I think it's private. We need to fix this... +- How big is small (10-15), medium (~30-40)? + - I would say below 50 is small. +- Have you considered scaling to more events instead of to a larger audience? I mean, this seems the opposite of scaling, but this kind of content would be more useful the more often is it taught ("I need to learn GIT/Python/* in December!") + - We would, but right now we simply don't have enough time and people to do more small events. But yes, "scheduling conflict" is a big problem - the best we can do right now is written material+videos to follow up on (and hope it's interesting enough) + - [Python for Scientific Computing 5-7/November/2024](https://www.aalto.fi/en/events/python-for-scientific-computing-5-7november2024) + - This was just an example. I mean, if I am a PHD student that needs to start working on a topic on Month X which happens to be inconveniently placed in the year, I will not benefit as much from having a workshop at Month X+3 + - The materials are open and the videos are publically available on YouTube channel + - What's the ratio of people watching videos afterwards vs people attending the event? That ratio can give an idea of the popularity of the two possible approaches. + - The more you scale up the less interactive the course / workshop will need to be. It then becomes a question of priorities, and if teaching is a lower priority then learning than I guess there really should be no prizes for guessing which approach should reign the airwaves. +- I guess outside Europe / Africa, time zones could be a problem? + - yes, that is true + - +- Sorry, I might have missed this: have you been rehearsing and/or doing dry runs? + - With instructors I like to try to do a dry run. I often don't do a live broadcast dry run these days since I'm confidente enough, but when you are just starting, it's a good idea. +- Do you always use Zoom for the 'presenter end' or have you tried other things? Teams? Jitsi? etc.? + - we use mostly zoom + - It was first pioneered using Jitsi. You can probably use others, too. + +- A comment: for deRSE24 we have been using the [GWDG streaming service](https://docs.gwdg.de/doku.php?id=en:services:mobile_working:live_streaming:start) and OBS, it worked quite well (with a 20s delay or so) + - Cool! Yes, there is plenty of livestreaming options. Twitch+our OBS config gives us 2-3s of latency (which is low enough for live Notes interaction). You might be able to tune this if needed. + +#### Behind the stream + +- Does OBS take a lot of RAM or CPU? what are the specs on your machine? + - Richard have a relatively powerful computer with 8 AMD CPUs. + - 4 CPUs are relatively enough for a good OBS setup, most important is a stable internet connection (ideally wired). + - An extra monitor is recommended for the setup + - See the hardware notesrecommendation [here](https://coderefinery.github.io/train-the-trainer/obs/#hardware-requirements) +- Do you do a screenshare from Zoom -> OBS or OBS -> Zoom? + - Instructors share to Zoom, OBS captures Zoom, OBS sends to the world. + - When I am using OBS sfor a single-person presentation recording, I go the other way: OBS captures my desktop/camera, OBS generates the preview window, and then Zoom captures and broadcasts the preview window. + + +#### [Video editing](https://coderefinery.github.io/train-the-trainer/video-editing/) + +##### Poll +- Have you tried video editing? Add an`o` as answer below + - yes: ooooo + - no : + - Video editing makes all the difference. I have never known a way to avoid this sacred of steps, so to speak. In short, no recording can ever be production ready by default in the books of the wiser among the streamers. In fact, during the editing one can considerably refine and improve the learning experience in great ways. But then one would need to invest both time and effort. + +- If `yes` Which are the tools you use? + - Windows Movie Maker / ClipChamp + - (raw stream from Zoom) + - I think it was shotcut - I did only basic trimming + - Kdenlive + - Clipchamp, OpenShot, Sony Vegas + - also ffmpeg from command line to cut beginning and end + +##### Questions +- What is Whisper? + - Open-source model from OpenAI that converts speech to text transcripts. + - this one? https://openai.com/index/whisper/ + - curious if anyone has tried it with languages other than english + - I heard that one of my spanish colleague try it with another software. I don't remember the tool. But with AI bloom there are many licensed tools that can do it with fifferent language + +- What do you use to crop the videos? + - I see now, ffmpeg + +- how to merge multiple parts in one? I asked because you edited only the icebreaker part? + - you can manage it in input part, see ffmpeg-editlist readme. + +- Do you generate custom thumbnails for the video? + - no, because of the time, but its good to have. If we had a volunteer to manage that, then we should! + +- Does anyone recommend any other (GUI) tools that work well? ffmpeg is very new to me! + - if you want a basic trimming and editing , you can use Quicktime player/imovies on mac + - Clipchamp as the Microsoft video editor + - Thanks :smile: + +- How do subtitles get uploaded to YouTube? + - You upload the video and subtitles as part of upload. + - :+1: + +- How does codewhisperer compare against youtube's automatically generated subtitles? + - by experience, whisper was better couple of years ago. We haven't compared it recently + - I guess and advantage is that you can edit whisper subtitles in case something is odd or whatever, probs cannot do that in YouTube + + +#### [Open Broadcaster Software (OBS) introduction](https://coderefinery.github.io/train-the-trainer/obs/) & [setup](https://coderefinery.github.io/train-the-trainer/obs-config/) + +- Are the profiles public? + - Yes, you can see it [here](https://coderefinery.github.io/train-the-trainer/obs-config/#coderefinery-obs-configs) +- Does it work in Linux+Wayland? + - I think everything we do with OBS would. + +### Wrapup +- All workshop materials will stay available (and be put on Zenodo right after the workshop) +- Upcoming Workshops + - [CodeRefinery workshop September 10-12, 17-19, 2024](https://coderefinery.github.io/2024-09-10-workshop/) + - [Build Systems Course and Hackathon](https://www.kth.se/form/build-systems-course-and-hackathon-part-i) + - [Python for Scientific Computing](https://www.aalto.fi/en/events/python-for-scientific-computing-5-7november2024) + +- CodeRefinery community: https://coderefinery.zulipchat.com/ +- If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org +- A summary email will be sent out to all participants + +### Feedback about todays session + +What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session: + +- ffmpeg seems great, will give a try for fun! +- great to see everything in practice! +- Very insightful to see what happens behind the scenes. + +What one thing would you improve about this session? + +- Some more interactivity would've been nice but since most the group preferred demo instead of exercise perhaps it's only a personal opinion +- It would have been good to share the OBS profiles repo beforehand in the setup email - so I could have had it to hand. (https://github.com/coderefinery/obs-config) + - +1 good idea, we should do this next time +- Perhaps a simpler starter OBS setup? + - Good idea... I should have, but basically ran out of time to prepare. + +Any other comments? + +- Cool to see the switch from RSE to trainer to AV guy, impressive! + + + diff --git a/branch/main/_sources/obs-config.md.txt b/branch/main/_sources/obs-config.md.txt new file mode 100644 index 0000000..df5e530 --- /dev/null +++ b/branch/main/_sources/obs-config.md.txt @@ -0,0 +1,93 @@ +(obs-config)= + +# Open Broadcaster Software (OBS) setup + +:::{objectives} +- See how to configure OBS using the pre-made CodeRefinery scene + collections +- Modify the collections to suit your needs. +::: + +:::{instructor-note} +- Teaching: ?? min +- Hands-on: ?? min +- Q&A: ?? min +::: + +:::{See also} +* The previous episode {doc}`obs` +* [OBS theory in CodeRefinery manuals](https://coderefinery.github.io/manuals/obs/) +::: + + +In this lesson, we'll see how to configure OBS from scratch for your +purposes. We'll do this by deleting the instructor's configuration +and trying to recreate it + +This section is short, since it has never been done before: we'll just +give it a short and update the lesson later. + + +## CodeRefinery OBS configs + +- CodeRefinery configs are shared in a repository: + +- These can be imported to pre-configure some things +- There are two types of configs: + - Profiles + - Servers, resolutions, audio, video, etc. + - Scene collections + - The graphical layouts. + + +## Installing the OBS config + +- Clone the git repository. +- Import the profile and scene collections under their respective + menus. + + +## Initial setup + +- Click through each menu and change anything that is needed +- Set the streaming server + +:::{demo} The instructor will go through the setup. + +- Reset configuration: `mv .config/obs-studio/ + .config/obs-studio-old/` +- Import `profiles/TeachingStreamingv3/` +- Import `scenes/TeachingStreamingZoomv3.json` +::: + + + +## Set up the remote control + +- Create a Python environment and install it: `pip install https://github.com/coderefinery/obs-cr/archive/refs/heads/master.zip` + +- Run it: `python obs_cr/control.py localhost:4445 TOKEN + --broadcaster` +- There are more options but let's not cover them yet... and leave + this for a hands-on session. + + +## Setup before each course + +- Re-confirm audio +- Re-confirm each scene +- Test everything +- rkdarst has a [rather long + checklist](https://docs.google.com/spreadsheets/d/1g8Bc_76OPcv1vYWtB54wz6HsXQcb3B1GtQFga4Oanw4/edit?gid=0#gid=0), + but each individual step is short. + + +## Q&A + +We'll answer audience questions. + + +:::{keypoints} +- Most of our configuration has been OBS may seem complicated, but it's a graphical application and most + pieces make sense once you know how it works. +::: diff --git a/branch/main/_sources/obs.md.txt b/branch/main/_sources/obs.md.txt new file mode 100644 index 0000000..8db24f4 --- /dev/null +++ b/branch/main/_sources/obs.md.txt @@ -0,0 +1,74 @@ +(obs)= + +# Open Broadcaster Software (OBS) introduction + +:::{objectives} +- Understand that OBS is a video mixer. +- Understand the basic controls and features of OBS. +::: + +:::{instructor-note} +- Teaching: 15 min +- Q&A 5 min +::: + +:::{See also} +* [OBS theory in CodeRefinery manuals](https://coderefinery.github.io/manuals/obs/) +* The next episode {doc}`obs-config` +::: + +In this episode, you'll get more familiar with the OBS portion of the +streaming setup. You'll see how it's used, but not yet how to +configure it from scratch. You'll learn how to be a "director". + + +## What is OBS? + +- Formally "OBS Studio" +- Most commonly known as a livestreaming application. +- Open source, free. +- Cross-platform, easy to use screencasting and streaming application. +- Real-time video mixer. + + +## OBS user interface + +- We'll click through each view. +- What does each view do? +- Let's click through the buttons. +- Let's see the important config options. + + +## OBS during a course + +- What management is needed. +- The control panel. +- Audio. +- Adjusting windows and so on. + + +## Hardware requirements + +- Reasonably powerful broadcast computer + - CodeRefinerys streaming computer is 8 CPU AMD, 64GB memory + - That is way overkill: a powerful laptop can probably do this. +- Large second monitor for laying out the windows you capture +- Stable internet connection (wired preferable) + - CodeRefinery's broadcast is the slowest purchasable: 100 Mbit down / + 25Mbit up + + +## Q&A + +We'll answer audience questions. + + +## See also + +- The next episode {doc}`obs-config` which is about configuring OBS. + + +:::{keypoints} +- OBS may seem complicated, but it's a graphical application and most + pieces make sense once you know how it works. +::: diff --git a/branch/main/_sources/overview.md.txt b/branch/main/_sources/overview.md.txt new file mode 100644 index 0000000..aaa3395 --- /dev/null +++ b/branch/main/_sources/overview.md.txt @@ -0,0 +1,185 @@ +(workshop-overview)= + +# A workshop seen from different perspectives + +:::{objectives} +- Understand the general structure of CodeRefinery workshops and why it is the way it is +- Get to know the different roles of a workshop and which ones are the most essential ones +- Understand the importance of installation instructions and how they contribute to learners success +- Understand the importance of onboarding and a welcoming community for volunteers in a workshop +::: + +:::{instructor-note} +- Teaching: 20 min +- Exercises: 15 min +- Roles journeys can be shortened to looking only at instructor role. +::: + +:::{note} +This episode focuses on the large scale streamed workshop setup. Some of the features can also be applied to smaller scale workshops though. +::: + +## Discussion + +:::{discussion} +In breakoutrooms: choose one or two questions to talk about your own experiences; summary in collaborative notes: +- What kind of roles have you been in yourself regarding workshops? +- How were you prepared for your role? +- What are the things you would like to know before a workshop? +- How are you preparing your participants for your trainings? +- What was the best workshop experience for you as learner, helper or instructor? What made it great? +::: + +## One workshop - many parts + +```{figure} img/CR_workshop_setup.png +Image showing the different phases of a CodeRefinery workshop described below. Also showing that while there is only two people teaching, many people work behind the scenes. +``` + +### Before the workshop + +- During winter/summer: "Someone" takes the coordinator role for the next workshop +- Coordinator fills other roles: + - Coordinator: collects necessary lesson updates, supports other coordinators + - Registration coordinator: Sets up web page, starts and manages registration + - Instructor coordinator: Finds instructors and onboards them + - Advertising coordinator: Prepares advertizement texts and finds people to distribute them + - Team coordinator: Gathers local organizers/teams + - Bring your own code session coordinator: If available, offer BYOC session after main workshop +- Instructor: Onboarding with (instructor-) coordinator and previous instructor of lesson; update of lesson materials (urgent issues and personal touches) +- Local organizer/Team lead: Group [onboarding](https://coderefinery.github.io/manuals/team-leaders/) ~ week/or two before workshop +- Learner: Gets [installation instructions](https://coderefinery.github.io/installation/), invited to installation help session, workshop info from event page and summary via e-mail +- Collaborative notes manager sets up the notes document + +:::{note} +#### [Onboarding manuals](https://coderefinery.github.io/manuals/team-leaders/) +- **Outline of what will happen during the workshop** +- Discussion of different strategies to handle the exercise sessions +- Lowering the barrier to ask for support by meeting some organizers +- Q&A +::: + +:::{note} +#### [Installation instructions](https://coderefinery.github.io/installation/) +- Instructions for all operating systems +- Goal: Learners leave the workshop and are ready to apply the learned tools and techniques to their own work +- Support session for installation challenges +::: + + + +### During the workshop + +```{figure} img/BYOC.png +Image showing the different ways learners can do the exercises. No matter which way they choose, they always watch the stream and interact with instructors and organizers via collaborative notes. Individual learners do the exercises alone, people in online or local classrooms in addition get to discuss with their peers. +``` + +- Everyone watches stream +- Co-instructors + - Present content + - Answer questions in collaborative notes +- Collaborative notes manager + - Keeps the collaborative notes clean + - Helps answering questions + - Adds sections + - Archives the document after each day +- Learners do exercises individually or in team +- Local organizer / Team lead + - Guides learners through exercises + - Facilitates discussion +- (Registration-) coordinator sends out e-mails to participants after each day (summary + preparation) +- Director/Broadcaster manages the streaming (see session 4) + +### After the workshop + +- Coordinator collects lessons learned based on experience and feedback and turns them into issues +- Coordinator organizes debriefing week after the workshop, where anyone can join to give feedback +- "Someone" sends out post-workshop survey half a year after workshop +- Coordinator organizes "Bring your own code" sessions +- Broadcaster prepares and shares recording (see session 4) + +:::{note} +#### Bring your own code sessions + +We want to support learners to apply what they have learned in the workshop to their own work by offering one/two sessions where they can drop in, and discuss challenges with CodeRefinery instructors and helpers. + +```{figure} img/welcome.png +Image showing a classroom learning about git leading to a discussion between student and teacher to start a welcoming environment for asking for help. +``` +::: + +## This sounds like a lot of people and time investment! + +- Many roles can be combined or adjusted as needed +- Some roles can be taken on by multiple people + +So how many people are needed for this kind of workshop? +- Recommended minimum: 2-3 people +- Optimum: ~ 4-5 people +The more people you involve, the more time goes into coordination work. + +## How did we get to this setup? + +- **Collaborative** in-person workshops since 2016 around the Nordics +- Moved online in 2020 +- Started with "traditional zoom" workshops, breakoutrooms, volunteer helpers +- Thought about scaling and ease of joining -> current setup (More about this in session 4) +- Continuous development + +We also still do smaller scale local workshops, if instructors are available. +**You can offer your own CodeRefinery workshop** by inviting other CodeRefinery instructors. +You can also reuse single lessons and integrate them into your own teaching. + +## Workshop roles and their journeys + +### Individual learner journey + +- Registration +- Installation +- (if appicable: Invited to local meetup) +- Workshop + - Watch stream + - Q&A in notes + - Exercises alone or in team + - Daily feedback +- Debrief/ Feedback session +- Post workshop survey + +### Instructor journey + +- Indicate interest in CodeRefinery chat +- Onboarding +- Lesson material updates +- Teaching +- (if wished: supports answering questions in notes) +- Debrief + +### Team lead / Local host journey + +- Registration +- (if applicable: run own registration) +- Onboarding +- Workshop + - Watch stream + - Facilitate exercises/discussions + - Daily feedback +- Debrief / feedback / survey + +### Other roles + +Director and broadcaster roles will be discussed in Session 4. +For more in-depth descriptions and other roles (host, instructor, registration coordinator, etc), see also our [CodeRefinery manuals](https://coderefinery.github.io/manuals/roles-overview/). + +## Different roles as stepping stones for community involvement + +```{figure} img/steps.png +Image showing a person jumping from step to step following learner, helper, expert helper, co-instructor, co-organizer. +``` +There is no "one way" to get involved. Do what feels right. +Interested in teaching with us? Let us know and we can discuss what is a suitable path **for you**! + +:::{keypoints} +- CodeRefinery workshops are a collaborative effort with many different roles +- Onboarding the different roles is one key aspect of our workshops +- Everyone has their own path +::: diff --git a/branch/main/_sources/screenshare.md.txt b/branch/main/_sources/screenshare.md.txt new file mode 100644 index 0000000..cdf552a --- /dev/null +++ b/branch/main/_sources/screenshare.md.txt @@ -0,0 +1,370 @@ +(screenshare)= + +# How to prepare a quality screen-share + +:::{objectives} +- Discuss the importance of a well planned screen-share. +- Learn how to prepare and how to test your screen-share setup. +- Know about typical pitfalls and habits to avoid. +::: + +:::{instructor-note} +- Discussion: 15 min +- Exercises: 15 min +::: + + +## Share portrait layout instead of sharing entire screen when teaching online + +- Many learners will have a smaller screen than you. +- You should plan for learners with **only one small screen**. +- A learner will **need to focus on both your screen share and their + work**. +- Share a **portrait**/**vertical half of your screen** (840 × 1080 is our standard and your + maximum). +- Zoom provides a "Share a part of screen" that is good for this. + - Our latest streaming setup (day 4) can take the portrait part for + you so you can share landscape. + - Zoom + Linux + Wayland display manager doesn't have "Share a + portion of the screen" + - You can share a single window portrait. + - Or you can start your desktop session in "X11" or "Xorg" legacy + mode. + - Or possibly other workarounds (does anyone know other solutions?) + +:::{figure} screenshare/landscape.png +:width: 80% + +A FullHD 1920x1080 screen shared. Learners have to make this really small if +they want to have something else open. +::: + +:::{figure} screenshare/portrait.png +:width: 45% + +Portrait layout. Allows learners to have something else open in the other half. +::: + +Motivation for portrait layout: +- This makes it easier for you to look at some other notes or to coordinate + with other instructors at the same time + without distracting with too much information. +- This makes it possible for participants to have something else open in the + other screen half: terminal or browser or notebook. + + +### Instructor perspective + +:::{figure} screenshare/instructor.png +:width: 75% + +**I1**: +This is how it can look for the instructor. Zoom is sharing a portion of the left +side, the right side is free for following notes, chat, etc. +::: + + +### Learner perspective + +Here are three examples of how it can look for the learner. + +:::{figure} screenshare/learner-large.png +:width: 75% + +**L1**: +Learner with a large screen, Zoom in dual-monitor mode so that the instructor +pictures are not shown. Screen-share is on the left side, collaborative notes +at bottom left, terminal and web browser on the right. +::: + +:::{figure} screenshare/learner-normal.png +:width: 75% + +**L2**: +A learner with a single large screen (Zoom in "single monitor mode"). +Instructor screen share at right, learner stuff at left. +::: + +:::{figure} screenshare/learner-small.png +:width: 75% + +**L3**: +A learner with a particularly small screen. Instructor screen-share at left, +your windows at right. +::: + + +## Share the history of your commands + +Even if you type slowly it is almost impossible to follow every command. We +all get distracted or want to read up on something or while following a command +fails on the learner laptop while instructor gets no error. + +**Add pauses** and **share the commands that you have typed** so that one can catch up. + +Below are some examples (some more successful than others) of sharing history +of commands. + +:::{figure} screenshare/history-portrait.png +:width: 50% + +**H1**: +A vertical screen layout shared. Note the extra shell history at the top. The +web browser is at the bottom, because the Zoom toolbar can cover the bottom +bit. +::: + +:::{figure} screenshare/history-rsh.png +:width: 75% + +**H2**: +This isn't a screen-share from CodeRefinery, but may be instructive. Note the +horizontal layout and shell history at the bottom right. +::: + +:::{figure} screenshare/history-landscape-dark.png +:width: 75% + +**H3**: +Similar to above, but dark. Includes contents on the right. +::: + +:::{figure} screenshare/history-portrait-light.png +:width: 50% + +**H4**: +Jupyter + terminal, including the ``fish`` shell and the terminal history. +::: + +:::{figure} screenshare/history-portrait-dark.png +:width: 50% + +**H5**: +Lesson + terminal, ``tmux`` plus terminal history and dark background. +::: + +:::{figure} screenshare/portrait.png +:width: 50% + +**H6**: +HPC Kickstart course. Note the colors contrast of the windows and colors of +the prompt and text. The history is smaller and doesn't take up primary +working space. The working directory is in the window title bar. +::: + +:::{figure} https://raw.githubusercontent.com/bast/history-window/main/demo.gif +:width: 80% + +**H7**: +Show command history "picture-in-picture", in the same terminal window. +::: + + +## How to configure history sharing + +You need to find a way to show the recent commands you have entered, so that +learners can see the recent commands. Below are many solutions. Try them out +and see what works for you. + +- [prompt-log](): + It adds a interesting idea that the command you enter is in color and also + provides terminal history before the command returns. + +- **Simple**: The simple way is `PROMPT_COMMAND="history -a"` and then + `tail -f -n0 ~/.bash_history`, but this doesn't capture ssh, + sub-shells, and only shows the command after it is completed. + +- **Better yet still simple**: Many Software Carpentry instructors use + [this script](https://github.com/rgaiacs/swc-shell-split-window), + which sets the prompt, splits the terminal window using tmux and displays command history + in the upper panel. Requirement: [tmux](https://github.com/tmux/tmux/wiki) + +- **Better (bash)**: This prints the output before the command is run, + instead of after. Tail with `tail -f ~/demos.out`. + ``` + BASH_LOG=~/demos.out + bash_log_commands () { + # https://superuser.com/questions/175799 + [ -n "$COMP_LINE" ] && return # do nothing if completing + [[ "$PROMPT_COMMAND" =~ "$BASH_COMMAND" ]] && return # don't cause a preexec for $PROMPT_COMMAND + local this_command=`HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"`; + echo "$this_command" >> "$BASH_LOG" + } + trap 'bash_log_commands' DEBUG + ``` + +- **Better (zsh)**: This works like above, with zsh. Tail with `tail -f + ~/demos.out`. + ``` + preexec() { echo $1 >> ~/demos.out } + ``` + +- **Better (fish)**: This works like above, but for fish. Tail with + `tail -f ~/demos.out`. + ``` + function cmd_log --on-event fish_preexec ; echo "$argv" >> ~/demos.out ; end + ``` + +- **Better (tmuxp)**: This will save some typing. + [TmuxP](https://tmuxp.git-pull.com/) is a Python program (`pip install + tmuxp`) that gives you programmable `tmux` sessions. One configuration that + works (in this case for `fish` shell): + ```yaml + session_name: demo + windows: + - window_name: demo + layout: main-horizontal + options: + main-pane-height: 7 + panes: + - shell_command: + - touch /tmp/demo.history + - tail -f /tmp/demo.history + - shell_command: + - function cmd_log --on-event fish_preexec ; echo "$argv" >> /tmp/demo.history ; end + ``` + +- **Windows PowerShell**: In [Windows Terminal](https://docs.microsoft.com/en-us/windows/terminal/), + a split can be made by pressing `CTRL+SHIFT+=`. Then, in one of the splits, the following + PowerShell command will start tracking the shell history: + ``` + Get-Content (Get-PSReadlineOption).HistorySavePath -Wait + ``` + Unfortunately, this only shows commands after they have been executed. + +- [Tavatar: shell history mirroring teaching tool](https://github.com/Sabryr/Tavatar) can copy recent history to a remote server. + +- [history-window](https://github.com/bast/history-window): Show command + history "picture-in-picture" when teaching command line. Requires Bash. + + +## Font, colors, and prompt + +### Terminal color schemes + +- Dark text on light background, *not* dark theme. Research and our + experience says that dark-text-on-light is better in some cases and + similar in others. +- You might want to make the background light grey, to avoid + over-saturating people's eyes and provide some contrast to the pure + white web browser. (this was an accessibility recommendation when + looking for ideal color schemes) +- Do you have any yellows or reds in your prompt or program outputs? + Adjust colors if possible. + + +### Font size + +- Font should be large (a separate history terminal can have a smaller + font). +- Be prepared to resize the terminal and font as needed. Find out + the keyboard shortcuts to do this since you will need it. + + +### Prompt + +At the beginning of the workshop your goal is to have a shell +**as easy to follow as possible** and **as close to what learners will +see on their screens**: +- Your prompt should be minimal: few distractions, and not take up many + columns of text. +- [prompt-log]() does + this for you. +- The minimum to do is is `export PS1='\$ '`. +- Blank line between entries: `export PS1='\n\$ '`. +- Have a space after the `$` or `%` or whatever prompt character you + use. +- Strongly consider the Bash shell. This is what most new people will + use, and Bash will be less confusing to them. +- Eliminate menu bars and any other decoration that uses valuable + screen space. +- Add colors only if it simplifies the reading of the prompt. + +Later in the workshop or in more advanced lessons: +- Using other shells and being more adventurous is OK - learners will + know what is essential to the terminal and what is extra for your + environment. + +Try to find a good balance between: +- Showing a simple setup and showing a more realistic setup. +- Showing a consistent setup among all instructors and showing a + variety of setups. + + +## Habits we need to un-learn + +- **Do not clear the terminal**. Un-learn CTRL-L or `clear` if possible. + More people will wonder what + just got lost than are helped by seeing a blank screen. Push + ``ENTER`` a few times instead to add some white space. +- **Do not rapidly switch between windows** or navigate quickly between multiple + terminals, browser tabs, etc. This is useful during your own work when nobody + is watching, but it is very hard to follow for learners. +- Avoid using **aliases** or **shortcuts** that are not part of the + standard setup. Learners probably don't have them, and they will fail + if they try to follow your typing. Consider even to rename corresponding + files (`.bashrc`, `.gitconfig`, `.ssh/config`, `.ssh/authorized_keys`, `.conda/*`). +- Be careful about using **tab completion** or **reverse history search** if these + haven't been introduced yet. + + +## Desktop environment and browser + +- Try to remove window title bars if they take up lots of space + without adding value to the learner. +- Can you easily resize your windows for adjusting during teaching? +- Does your web browser have a way to reduce its menu bars and other + decoration size? + - Firefox-based browsers: go to `about:config` and set + `layout.css.devPixelsPerPx` to a value slightly smaller than one, + like `0.75`. Be careful you don't set it too small or large since + it might be hard to recover! When you set it to something smaller + than 1, all window decorations become smaller, and you compensate + by zooming in on the website more (you can set the default zoom to + be greater than 100% to compensate). Overall, you get more + information and less distraction. + + +## How to switch between teaching setup and work setup? + +- Make a dedicated "demos" profile in your terminal emulator, if + relevant. Or use a different terminal emulator just for demos. +- Same idea for the browser: Consider using a different browser profile for + teaching/demos. +- Another idea is to containerize the setup for teaching. + We might demonstrate this during the {ref}`cool-gems` session later. + +--- + +:::{keypoints} +- Share **portrait layout** instead of sharing entire screen +- **Adjust your prompt** to make commands easy to read +- **Readability** and beauty is important: adjust your setup for your audience +- **Share the history** of your commands +- Get set up a **few days in advance** and get feedback from someone else. + Feedback and time to improve is very important to make things clear and accessible. + 10 minutes before the session starts is typically too late. +::: + + +## Exercises + +:::{exercise} Evaluate screen captures (20 min) + +Evaluate screenshots on this page. Discuss the trade-offs of each one. Which +one do you prefer? Which are useful in each situation? + +Please take notes in the collaborative document. +::: + +:::{exercise} Set up your own environment (20 min) + +Set up your screen to teach something. Get some feedback from another learner +or your exercise group. +::: + + +## Other resources + +- +- diff --git a/branch/main/_sources/session-4-intro.md.txt b/branch/main/_sources/session-4-intro.md.txt new file mode 100644 index 0000000..15cf32e --- /dev/null +++ b/branch/main/_sources/session-4-intro.md.txt @@ -0,0 +1,28 @@ +(session-4-intro)= + +# Session 4 intro + +This session covers streaming and technical production. Some +introductory notes: + +* (As of 2024) This is the first and only comprehensive introduction + to our online streaming. +* These practices are new and well-refined internally, but a + *different* kind of refinement is needed to teach and reuse them. +* The lessons have outlines of what to talk about, but it's just an + outline. It is *not* refined, since thees things are *new*. Many + things will have to be figured out as we talk. +* This session is a demo of lots of basics. + * Ask questions - otherwise it will be boring + * If you want to use this in real life: you will need *mentoring + sessions* and active help. Contact us to do that. + + +:::{warning} + +**Audio and video weirdness** + +We are setting up video and audio recording, but also capturing that +for re-sharing it. There may be anomalies as video or audio +feedback. Please be prepared. +::: diff --git a/branch/main/_sources/sound.md.txt b/branch/main/_sources/sound.md.txt new file mode 100644 index 0000000..bc4ba16 --- /dev/null +++ b/branch/main/_sources/sound.md.txt @@ -0,0 +1,170 @@ +(sound)= + +# Sound + +:::{objectives} +- Understand that sound quality is very important +- Evaluate your and others sound quality and know how to improve it +- Test tips and tricks for achieving good sound quality +::: + +:::{instructor-note} +- Teaching: 10 min +- Exercises: 10 min +::: + + + +## The importance of audio + +- Pleasing audio quality makes events much more enjoyable +- Audio is one of the most important things you can control +- Things that can go wrong: + - Too quiet + - Too loud + - Instructors' volumes imbalanced + - Background noise + - Low-quality/breaking up audio hard to hear. + - "Ducking" (first words lower volume, or lower volume other times) + + + +## Tips for good sound quality + +- Have a headset with mounted microphone + - Even if you have a professional external microphone, it doesn't + matter if your room has bad acoustics. + - The close pickup can't be beat with normal tools. + - As long as it's headset mounted, price doesn't seem to matter + *that* much. +- Don't use Bluetooth + - Bluetooth can have too much latency (300-500ms) + - This may seem small but for interactive work, it's a lot + - Use a wired headset, or wireless with a non-Bluetooth USB plug + (like gaming headsets have). These have much lower latency. + - Bluetooth 5 can have much lower latency, but you probably + shouldn't count on that without testing. + - It can also have lower sound quality on some devices due to + bandwidth limitations. +- Once you have a headset, turn input noise cancellation to low + (wherever it might be: headphone, meeting software, etc.). + + + +## Balancing and dynamic adjustment + +- It's important that instructors volumes match. +- An exercise will go over a systematic procedure for matching + volumes. + - Practice so that you can do this quickly. +- May need re-adjusting when instructors swap out or start getting + excited. +- An exercise below will demonstrate our procedure. + + + +## Speak up when there are problems + +- If you notice someone with audio issues, let them know right away + (voice if bad, or chat/notes if less urgent). +- Take the time to fix it as soon as practical. +- Make a culture of *speaking up, helping, and not suffering*. + + + +## Recommendations + +- Procure some reasonable headset. +- Low/medium-priced gaming-type headsets have worked well for us. + - (gaming headsets usually aren't Bluetooth, because gaming needs + low latency.) +- Show this page to your workplace (if you have one) and call a good + headset work equipment. + + + +## Exercises + +:::{exercise} Sound-1: Evaluate sound quality +It's important to be able to discuss with others the quality of their +audio. They can't hear themselves, after all. + +- Within the teams, discuss each person's audio quality and what kind + of setup they have. +- Be respectful and constructive (and realize that people came + prepared to listen, not teach). +- Consider, for example + - Volume + - Clarity + - Background noise + - Noise cancellation artifacts + - "Ducking": first words at lower volume or missing +- Discuss how to bring this up during other courses and meetings. +::: + + +:::{exercise} Sound-2: Adjust volume up and down +In addition to individual quality, it is important that sound is +balanced among all instructors. Have you ever been to a event when +one person is too quiet and they can't make themselves any louder? +And they can't adjust it? + +You should ensure that you have a range of volumes available to you. +You might have to look into several different locations in order to +make the full adjustment (). + +- Go to your sound settings +- One by one, each person + - Adjusts their microphone volume so quiet that they can't be heard. + - Adjusts their microphone volume so that it is extremely loud (this + may require going beyond 100% if possible). +- Basically, make sure you aren't so close to either end that you have + no potential to make an adjustment in that direction. +- Everyone tries to set the volume to something reasonable, in + preparation for the next exercise. + +Once you know where these settings are , you won't be panicked when the +volume is too low or high during a course. +::: + + +:::{exercise} Sound-3: Do a balance check +It's important that instructor audio is balanced (the same volume). +But how can you do this? + +- Pick a leader. +- The leader decides the order ("I am first, then [name-1] and + [name-2]") +- The leader says "one". Everyone else says "one" in the order + specified. +- The leader says "two". Everyone else says "two" in the order. +- The leader asks for opinions on who they think is louder or softer. + If there are more than three people, you can figure it out + yourselves. With less than two, you have to ask someone in the + audience. + +Example: +- Leader: Let's do a sound check. I am first, then AAA and BBB. +- Leader: One +- AAA: One +- BBB: One +- Leader: Two +- AAA: Two +- BBB: Two +- Leader: Three +- AAA: Three +- BBB: Three +- Leader: How did that sound to everyone? +- [Someone else]: Leader and BBB were pretty similar but AAA is a bit + lower. +::: + + + +## Summary + +:::{keypoints} +- Audio quality is important and one of the most notable parts of the + workshop. +- Improving audio isn't hard or expensive, but does require preparation. +::: diff --git a/branch/main/_sources/streaming-whats-next.md.txt b/branch/main/_sources/streaming-whats-next.md.txt new file mode 100644 index 0000000..68a62d9 --- /dev/null +++ b/branch/main/_sources/streaming-whats-next.md.txt @@ -0,0 +1,31 @@ +(streaming-whats-next)= + +# What's next? + +:::{objectives} +- Know next steps if you want to do streaming +::: + +:::{instructor-note} +- Teaching: 5 min +- Q&A 5 min +::: + +What comes next? + +- We talked a lot about theory, and gave demonstrations. +- Hands-on is very different. We recommend working with someone to + put it in practice. +- + + +- Work with someone who can show you the way +- Use it for smaller courses with a backup plan + + +## See also + +:::{keypoints} +- These lessons about streaming have been the theoretical part of +streaming training. +::: diff --git a/branch/main/_sources/streaming.md.txt b/branch/main/_sources/streaming.md.txt new file mode 100644 index 0000000..614b847 --- /dev/null +++ b/branch/main/_sources/streaming.md.txt @@ -0,0 +1,94 @@ +(streaming)= + +# Behind the stream + +:::{objectives} +- Take a first look at the broadcaster's view. +- Get to know what happens "behind the stream" of a workshop +- See what the "broadcaster" sees and what they need to do. +- Not yet: learn details of how to do this. +::: + +:::{instructor-note} +- Teaching: 20 min +- Q&A 10 min +::: + +In this episode, you'll see an end-to-end view of streaming from the +broadcaster's point of view. It's a tour but not an explanation or +tutorial. + + + +## Who does what + +We have certain role definitions: + +- **Broadcaster**: Our term for the person who manages the streaming. +- **Director**: Person who is guiding the instructors to their + sessions, changing the scenes, calling the breaks, etc. + - Could be the same as broadcaster. +- **Instructor**: One who is teaching. They don't have to know + anything else about how streaming works. + +This lesson describes what the Broadcaster/Director sees. + + +## Window layouts + +What does the broadcaster see on their screen? + +- What are the main windows you see? +- What do each of them do? +- Which ones do you need to focus on? +- How do you keep all this straight in your head? + + +## CodeRefinery control panel + +- A custom application that controls scenes +- Based on OBS-websocket (remote control connection for OBS - we'll + learn about this later) +- Can also work remotely, so that you can have a remote director + + +## How scenes are controlled + +What has to be done during a course? + +- How do you start the stream? +- How do you change the view? +- How do you adjust things based on what the instructors share? +- How do you coordinate with the instructors? +- How do you know when to change the view? + + +## Getting it set up + +- How hard was it to figure this out? +- How hard is it to set it up for each new workshop? + + +## What can go wrong + +- What's the worst that has happened? +- What if you need to walk away for a bit? +- Someone broadcasts something unexpectedly + + +## Alternatives + +- Youtube vs Twitch +- Zoom stream directly to YouTube/Twitch +- Direct streaming platform, e.g. streamyard + + +## Q&A + +Q&A from audience + + +:::{keypoints} +- The broadcaster's view shouldn't be so scary. +- There is a lot to manage, but each individual part isn't that hard. +::: diff --git a/branch/main/_sources/teaching-philosophies.md.txt b/branch/main/_sources/teaching-philosophies.md.txt new file mode 100644 index 0000000..7609af2 --- /dev/null +++ b/branch/main/_sources/teaching-philosophies.md.txt @@ -0,0 +1,155 @@ +(teaching-philosophies)= + +# CodeRefinery teaching philosophies + +:::{objectives} +- Get to know the teaching philosophies of CodeRefinery instructors +::: + +:::{instructor-note} +- Teaching: 10 min +- Discussion: 20 min +::: + + +## Introduction + +During this episode we split into breakoutrooms and discuss own teaching philosophies. +Collect your teaching philosophies in the collaborative document. We will be going through +these and the end of the lesson. + +:::{challenge} Ice-breaker in groups (20 minutes) +- Share your approach to teaching and your teaching philosophy with your group. +- Please share your tricks and solutions in the live document for others. + +Additional ice-breaker questions: +- What is your motivation for taking this training? +- How structured or informal are your own teaching needs? +- What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching? +- What other skills need to be taught, but academic teaching isn't the right setting? +::: + + +## Instructor views + +Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops. + +It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us. + +:::{prereq} Video recordings +We have recorded some of the below as videos: +::: + +:::{challenge} Bjørn Lindi +My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this "BLOB" (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the "BLOB", to be able to share it with others. + +In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic. + +When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson. + +Tools that I find useful in preparing a lesson is concept maps and Learner Personas (though I have developed too few of them): +- [Concept Maps](https://teachtogether.tech/#s:memory-concept-maps) +- [Learner Personas](https://teachtogether.tech/#s:process-personas) +::: + +:::{challenge} Radovan Bast +My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos. + +My goal for a lesson is to spark curiosity to try things after the lesson, both +for the novices ("This looks like a useful tool, I want to try using it after +the workshop.") and the more experienced participants ("Aha - I did not know +you could do this. I wonder whether I can make it work with X."). I like to +start lessons with a question because this makes participants look up from +their browsers. + +Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise. + +For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate the +answer. + +I try to avoid jargon and "war stories" from the professional developers' +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid "customer", +"production", also a lot of Agile jargon is hard to relate to. + +Less and clear is better than more and unclear. Simple examples are better than +complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +"simply", "just", "easy". If participants take home one or two points from a +lesson, that's for me success. + +I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don't want to be +surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or slide. +This allows me to skip and distill the essence and not read bullet point by +bullet point. + +I try to never deviate from the script and if I do, be very explicit about it. + +A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel listening to me. + +I very much like the co-teaching approach where the other person helps +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson. +::: + +:::{challenge} Sabry Razick +My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case. +::: + +:::{challenge} Richard Darst +Like many people, I've often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I've realized long ago that my most important lessons weren't +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I've realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds. + +My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I'm often start at the +very basics, because this is what I see missing most often. + +When teaching, I like lots of audience questions and don't mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don't have to know everything perfectly, just show how +you'd approach a problem. +::: + +:::{challenge} Stepas Toliautas +I aim for my learners to understand things (concepts, techniques...), instead of just memorizing them. The phrase I use from time to time when teaching information technology topics (be it hardware or software) is "there is no magic": everything can be explained if necessary. While CodeRefinery also emphasizes usefulness/ immediate applicability of the content, often having the correct notions actually helps to start using them sooner and with less mistakes. + +I try to guide my audience through the presented material with occasional questions related to previous topics and common knowledge -- to help them link the concepts already during the lesson. I'm also fully aware that waiting for someone to answer is quite uncomfortable in-person and doubly so in an online environment, especially if no one uses their cameras :) + +And if I get the question I don't have the answer for (or material to show it) at the moment, in university classes I prepare and come back to it next time. While with one-off workshops there might not be a "next time", open-source material used by CodeRefinery allows to have the same outcome: the latest and greatest version stays available for self-study afterwards. +::: + + +## Summary + +:::{keypoints} +- People have different viewpoints on teaching. +::: diff --git a/branch/main/_sources/video-editing.md.txt b/branch/main/_sources/video-editing.md.txt new file mode 100644 index 0000000..b41ee26 --- /dev/null +++ b/branch/main/_sources/video-editing.md.txt @@ -0,0 +1,468 @@ +(video-editing)= + +# Video editing + +:::{objectives} +- Get to know ways of quick video editing to be able to provide + accessible videos +- Learn how video editing can be distributed and done the same day. +::: + +:::{instructor-note} +- Teaching: 20 min +- Exercises: 20 min +::: + + +Video recordings could be useful for people watching later, +but also are (perhaps more) useful for **immediate review and catching +up after missing a day in a workshop**. For this, they need to be +released immediately, within a few hours of the workshop. +CodeRefinery does this, and you can too. + +Hypothesis: videos must be processed the same evening as they were +recorded, otherwise (it may never happen) or (it's too late to be +useful). To do that, we have to make processing *good enough* (not +perfect) and *fast* and the work *distributeable*. + + + +## Primary articles + +* Video editor role description: + +* ffmpeg-editlist: the primary tool: + + * Example YAML editlists: + + + +## How this relates to streaming + +- If you stream, then the audience *can not* appear in the recorded + videos +- This allows you to release videos *very quickly* if you have the + right tools. +- When you have a large audience, the videos start helping more + (review a missed day, catch up later, review later) +- Thus + - If you would never want videos, there may never be a benefit to + streaming + - If you want videos, it gives motivation to stream. + + +## Summary + +* Basic principle: privacy is more important than any other factor. + If we can't guarantee privacy, we can't release videos at all. + + - Disclaimers such as "if you don't want to appear in a recording, + leave your video off and don't say anything", since a) accidents + happen especially when coming back from breakout rooms. b) it + creates an incentive to not interact or participate in the course. + +* Livestreaming is important here: by separating the instruction from + the audience audio/video, there is no privacy risk in the raw + recording. They could be released or shared unprocessed. + +* Our overall priorities + + 1) No learner (or anyone not staff) video, audio, names, etc. are + present in the recordings. + 2) Good descriptions. + 3) Removing breaks and other dead time. + 4) Splitting videos into useful chunks (e.g. per-episode), perhaps + equal with the next one: + 5) Good Table of Contents information so learners can jump to the + right spots (this also helps with “good description”.) + +* [ffmpeg-editlist](https://github.com/coderefinery/ffmpeg-editlist) + allows us to define an edit in a text file (crowdsourceable on + Github), and then generate videos very quickly. + + +## How we do it + +The full explanation is in the form of the exercises below. As a +summary: + +- Record raw video (if from a stream, audience can't possibly be in + it) +- Run Whisper to get good-enough subtitles. Distribute to someone for + checking and improving. +- Define the editing steps (which segments become which videos and + their descriptions) in a YAML file. +- Run ffmpeg-editlist, which takes combines the previous three steps + into final videos. + + + +## Exercises + +### Exercise A + +These exercises will take you through the whole sequence. + +:::::{exercise} Editing-1: Get your sample video + +Download a sample video: + +* Video (raw): +* Whisper subtitles (of raw video): + +* [Schedule of + workshop](https://scicomp.aalto.fi/training/scip/kickstart-2023/#schedule) + (day 1, 11:35--12:25) - used for making the descriptions. ::::: + + +:::::{exercise} Editing-2: Run Whisper to generate raw subtitles and test video. + +First off, install Whisper and generate the base subtitles, based +on the. Since this is probably too much to expect for a short +lesson, they are provided for you (above), but if you want you can +try using Whisper, or generating the subtitles some other way. + +You can start generating subtitles now, while you do the next +steps, so that they are ready by the time you are ready to apply +the editlist. ffmpeg-editlist can also slice up the subtitles from +the main video to make subtitles for each segment you cut out. + +Whisper is left as an exercise to the reader. + +::::{solution} + +Example Whisper command: + +```console +$ whisper --device cuda --output_format srt --initial_prompt="Welcome to CodeRefinery day four." --lang en --condition_on_previous_text False INPUT.mkv +``` + +An initial prompt like this make Whisper more likely to output +full sentences, instead of a stream of words with no +punctuation. +:::: +::::: + +:::::{exercise} Editing-3: Create the basic editlist.yaml file + +Install +[ffmpeg-editlist](https://github.com/coderefinery/ffmpeg-editlist) and +try to follow its instructions, to create an edit with these features: + +* The input definition. +* Two output sections: the "Intro to the course", and "From data + storage to your science" talks (Remember it said the recording + started at 11:35... look at the schedule for hints on when it + might start!). This should have a start/end timestamp from the + *original* video. + +A basic example: + +```yaml +- input: day1-raw.mkv + +# This is the output from one section. Your result should have two of these sections. +- output: part1.mkv + title: something + description: >- + some long + description of the + segment + editlist: + - start: 10:00 # start timestamp of the section, in *original* video + - end: 20:00 # end timestamp of the section, in the *original* video +``` + +::::{solution} + +This is an excerpt from our [actual editlist file of this +course](https://github.com/AaltoSciComp/video-editlists-asc/blob/master/kickstart-2023.yaml#L16-L53) + +```yaml +- input: day1-obs.mkv + +- output: day1-intro.mkv + title: 1.2 Introduction + description: >- + General introduction to the workshop. + + https://scicomp.aalto.fi/training/kickstart/intro/ + + editlist: + - start: 00:24:10 + - end: 00:37:31 + + +- output: day1-from-data-storage-to-your-science.mkv + title: "1.3 From data storage to your science" + description: >- + Data is how most computational work starts, whether it is + externally collected, simulation code, or generated. And these + days, you can work on data even remotely, and these workflows + aren't obvious. We discuss how data storage choices lead to + computational workflows. + + https://hackmd.io/@AaltoSciComp/SciCompIntro + + editlist: + - start: 00:37:43 + - end: 00:50:05 +``` +:::: +::::: + +:::::{admonition} Discussion: what makes a video easy to edit? +--- +class: discussion +--- + +* Clear speaking and have high audio quality. +* For subtitle generation: Separate sentences cleanly, otherwise it + gets in a "stream of words" instead of "punctuated sentences" + mode. +* Clearly screen-sharing the place you are at, including section + name. +* Clear transitions, "OK, now let's move on to the next lesson, + LESSON-NAME. Going back to the main page, we see it here." +* Clearly indicate where the transitions are +* Hover mouse cursor over the area you are currently talking about. +* Scroll screen when you move on to a new topic. +* Accurate course webpage and sticking to the schedule + +All of these are also good for learners. By editing videos, you +become an advocate for good teaching overall. +::::: + + +:::::{exercise} Editing-4: Run ffmpeg-editlist + +Install ffmpeg-editlist: ``pip install ffmpeg-editlist[srt]`` (you +may want to use a virtual environment, but these are very minimal +dependencies). + +The ``ffmpeg`` command line tool must be available in your +``PATH``. + +::::{solution} + +It can be run with (where ``.`` is the directory containing the +input files): + +```console +$ ffmpeg-editlist editlist.yaml . +``` + +Just running like this is quick and works, but the stream may be +garbled in the first few seconds (because it's missing a key +frame). (A future exercise will go over fixing this. +Basically, add the ``--reencode`` option, which re-encodes the +video (this is **slow**). Don't do it yet. + +Look at the ``.info.txt`` files that come out. +:::: +::::: + + +:::::{exercise} Editing-5: Add more features + +* Several chapter definitions.(re-run and you should see a + ``.info.txt`` file also generated). Video chapter definitions + are timestamps of the *original* video, that get translated to + timestamps of the *output* video. + + ```yaml + + - output: part1.mkv + editlist: + - start: 10:00 + - -: Introduction # <-- New, `-` means "at start time" + - 10:45: Part 1 # <-- New + - 15:00: Part 2 # <-- New + - end: 20:00 + ``` + + Look at the ``.info.txt`` files that come out now. What is new in it? + +* Add in "workshop title", "workshop description", and see the + ``.info.txt`` files that come out now. This is ready for + copy-pasting into a YouTube description (first line is the title, + rest is the description). + + Look at the new ``.info.txt`` files. What is new? + +::::{solution} + +* This course actually didn't have chapters for the first day + sessions, but you can [see chapters for day 2 + here](https://github.com/AaltoSciComp/video-editlists-asc/blob/master/kickstart-2023.yaml#L239-L262), + for example. +* [Example of the workshop description for this + course](https://github.com/AaltoSciComp/video-editlists-asc/blob/master/kickstart-2023.yaml#L1-L13) +* Example info.txt file for the general introduction to the + course. The part after the ``-----`` is the workshop description. + + ``` + 1.2 Introduction - HPC/SciComp Kickstart summer 2023 + + General introduction to the workshop. + + https://scicomp.aalto.fi/training/kickstart/intro/ + + 00:00 Begin introduction <-- Invented for the exercise demo, not real + 03:25 Ways to attend <-- Invented for the exercise demo, not real + 07:12 What if you get lost <-- Invented for the exercise demo, not real + + ----- + + This is part of the Aalto Scientific Computing "Getting + started with Scientific Computing and HPC Kickstart" 2023 + workshop. The videos are available to everyone, but may be + most useful to the people who attended the workshop and want + to review later. + + Playlist: + https://www.youtube.com/playlist?list=PLZLVmS9rf3nMKR2jMglaN4su3ojWtWMVw + + Workshop webpage: + https://scicomp.aalto.fi/training/scip/kickstart-2023/ + + Aalto Scientific Computing: https://scicomp.aalto.fi/ + ``` +:::: +::::: + +:::::{exercise} Editing-6: Subtitles + +Re-run ffmpeg-editlist with the ``--srt`` option (you have to +install it with ``pip install ffmpeg-editlist[srt]`` to pull in the +necessary dependency). Notice how ``.srt`` files come out now. + +Use some subtitle editor to edit the *original* subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use ``subtitle-editor`` on Linux, or find some other +tool. + +What do you learn from editing the subtitles? + +::::{solution} + +```console +$ ffmpeg-editlist --srt editlist.yaml +``` + +There should now be a ``.srt`` file also generated. It +generated by finding the ``.srt`` of the original video, and +cutting it the same way it cuts the video. Look and you see it +aligns with the original. + +This means that someone could have been working on fixing the +Whisper subtitles while someone else was doing the yaml-editing. +:::: +::::: + + +:::::{exercise} Editing-6: Subtitles + +Re-run ffmpeg-editlist with the ``--srt`` option (you have to +install it with ``pip install ffmpeg-editlist[srt]`` to pull in the +necessary dependency). Notice how ``.srt`` files come out now. + +Use some subtitle editor to edit the *original* subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use ``subtitle-editor`` on Linux, or find some other +tool. + +What do you learn from editing the subtitles? +::::: + + +:::::{exercise} Editing-7: Generate the final output file. + +* Run ffmpeg-editlist with the ``--reencode`` option: this + re-encodes the video and makes sure that there is no black point + at the start. + +* If you re-run with ``--check``, it won't output a new video file, + but it *will* re-output the ``.info.txt`` and ``.srt`` files. + This is useful when you adjust descriptions or chapters. +::::: + + +:::::{admonition} Discussion: how to distribute this? +--- +class: discussion +--- + +Create a flowchat of all the parts that need to be done, and which +parts can be done in parallel. Don't forget things that you might +need to do before the workshop starts. + +How hard was this editing? Was it worth it? +::::: + + +### Exercise B + + +This is a more limited (and older) version of the above exercise, +using an synthetic example video. + +:::::{exercise} Use ffmpeg-editlist to edit this sample video + +Prerequisites: ``ffmpeg`` must be installed on your computer +outside of Python. Be able to install ffmpeg-editlist. This is +simple in a Python virtual environment, but if not the only +dependency is ``PyYAML``. + +* Download the sample video: +* Copy a sample editlist YAML +* Modify it to cut out the dead time at the beginning and the end. +* If desired, add a description and table-of-contents to the + video. +* Run ffmpeg-editlist to produce a processed video. + +::::{solution} + +```yaml +- input: sample-video-to-edit.raw.mkv +- output: sample-video-to-edit.processed.mkv + description: > + editlist: + - start: 00:16 + - 00:15: demonstration + - 00:20: discussion + - stop: 00:25 +``` + +```console +$ ffmpeg-editlist editlist.yaml video/ -o video/ +``` + +Along with the processed video, we get +``sample-video-to-edit.processed.mkv.info.txt``:: + +``` +This is a sample video + + +00:00 Demonstration +00:04 Discussion +``` +:::: +::::: + +## See also + +* ffmpeg-editlist demo: +* Full demo of producing videos (everything in these exercises): +* Example YAML editlists: + + + + + +:::{keypoints} +- Video editing is very useful for learning +- Set your time budget and make it good enough in that time +- Reviewing videos improves your teaching, too. +::: diff --git a/branch/main/_sources/why-we-stream.md.txt b/branch/main/_sources/why-we-stream.md.txt new file mode 100644 index 0000000..56d5e5e --- /dev/null +++ b/branch/main/_sources/why-we-stream.md.txt @@ -0,0 +1,100 @@ +(why-we-stream)= + +# Why we stream + +:::{objectives} +- Learn the general history of CodeRefinery streaming. +- Discuss the benefits of streaming and recording +- Discuss the downsides and difficulties +::: + +:::{instructor-note} +- Discussion: 10 min +- Q&A: 5 min +- Exercises: 0 min +::: + + +This is a general discussion of the topics of the day, focused on the +history of why we stream and record, how we got here, and how people +feel about it. We won't focus on how anything is done. + + +## Icebreaker questions + +- What is the most people you have taught for? +- What are the distinct parts of teaching, that can be + separated? (teaching, helping, etc) + + +## What is streaming and recording? + +- Streaming is mass communication: one to many + - Interaction audience→presenters is more limited (but different) +- Using consumer-grade tools, normal people can reach huge audiences + by Twitch/YouTube/etc. +- This isn't actually that hard: people with much less training than + us do it all the time. +- They reach huge audiences and maintain engagement for long events. + +**Recording and rapid video editing is useful even without +streaming.** + + +## History + +- In-person workshops + - 3 × full day, required travel, infrequent, one-shot +- Covid and remote teaching + - Traditional "Zoom" teaching several times +- Mega-CodeRefinery workshop + - 100-person Zoom teaching + - Emphasis on teams +- Research Software Hour + - Livestream free-form discussions on Twitch +- Streamed "HPC Kickstart" courses + + + +## Benefits and disadvantages + +Benefits: +- Larger size gives more (but different) interaction possibility + - "Notes" for async Q&A +- Recording (with no privacy risk) allows instant reviews +- Stream-scale allows for many of the things you have learned about in + days 1-3. + +Disadvantages: +- Requires training for using the tools +- Requires a certain scale to be worth it +- Coordination is much harder for big events + +When would I recommend it? +- No: For small courses +- Questionable: Medium sized courses with no videos +- Yes: When you want the largest audience +- Yes: When you want without registration required +- Yes: When you want good reusability/fast videos + + +## Future prospects (briefly) + +- Streaming probably stays as a CodeRefinery tool +- We *can* scale our courses much larger than they are now. Why don't + we, together with others? +- These tools are useful in other places too + - I've used them to record my own talks to make videos of my + single-person presentations or record conference talks nicer than Zoom. + + +## Q&A + +Q&A from audience + + +:::{keypoints} +- Streaming optimizes a course for different things +- The disadvantages can be compensated for +- There are benefits and disadvantages +::: diff --git a/branch/main/_sphinx_design_static/design-tabs.js b/branch/main/_sphinx_design_static/design-tabs.js new file mode 100644 index 0000000..b25bd6a --- /dev/null +++ b/branch/main/_sphinx_design_static/design-tabs.js @@ -0,0 +1,101 @@ +// @ts-check + +// Extra JS capability for selected tabs to be synced +// The selection is stored in local storage so that it persists across page loads. + +/** + * @type {Record} + */ +let sd_id_to_elements = {}; +const storageKeyPrefix = "sphinx-design-tab-id-"; + +/** + * Create a key for a tab element. + * @param {HTMLElement} el - The tab element. + * @returns {[string, string, string] | null} - The key. + * + */ +function create_key(el) { + let syncId = el.getAttribute("data-sync-id"); + let syncGroup = el.getAttribute("data-sync-group"); + if (!syncId || !syncGroup) return null; + return [syncGroup, syncId, syncGroup + "--" + syncId]; +} + +/** + * Initialize the tab selection. + * + */ +function ready() { + // Find all tabs with sync data + + /** @type {string[]} */ + let groups = []; + + document.querySelectorAll(".sd-tab-label").forEach((label) => { + if (label instanceof HTMLElement) { + let data = create_key(label); + if (data) { + let [group, id, key] = data; + + // add click event listener + // @ts-ignore + label.onclick = onSDLabelClick; + + // store map of key to elements + if (!sd_id_to_elements[key]) { + sd_id_to_elements[key] = []; + } + sd_id_to_elements[key].push(label); + + if (groups.indexOf(group) === -1) { + groups.push(group); + // Check if a specific tab has been selected via URL parameter + const tabParam = new URLSearchParams(window.location.search).get( + group + ); + if (tabParam) { + console.log( + "sphinx-design: Selecting tab id for group '" + + group + + "' from URL parameter: " + + tabParam + ); + window.sessionStorage.setItem(storageKeyPrefix + group, tabParam); + } + } + + // Check is a specific tab has been selected previously + let previousId = window.sessionStorage.getItem( + storageKeyPrefix + group + ); + if (previousId === id) { + // console.log( + // "sphinx-design: Selecting tab from session storage: " + id + // ); + // @ts-ignore + label.previousElementSibling.checked = true; + } + } + } + }); +} + +/** + * Activate other tabs with the same sync id. + * + * @this {HTMLElement} - The element that was clicked. + */ +function onSDLabelClick() { + let data = create_key(this); + if (!data) return; + let [group, id, key] = data; + for (const label of sd_id_to_elements[key]) { + if (label === this) continue; + // @ts-ignore + label.previousElementSibling.checked = true; + } + window.sessionStorage.setItem(storageKeyPrefix + group, id); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/branch/main/_sphinx_design_static/sphinx-design.min.css b/branch/main/_sphinx_design_static/sphinx-design.min.css new file mode 100644 index 0000000..860c36d --- /dev/null +++ b/branch/main/_sphinx_design_static/sphinx-design.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative;font-size:var(--sd-fontsize-dropdown)}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary.sd-summary-title{padding:.5em .6em .5em 1em;font-size:var(--sd-fontsize-dropdown-title);font-weight:var(--sd-fontweight-dropdown-title);user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;list-style:none;display:inline-flex;justify-content:space-between}details.sd-dropdown summary.sd-summary-title::-webkit-details-marker{display:none}details.sd-dropdown summary.sd-summary-title:focus{outline:none}details.sd-dropdown summary.sd-summary-title .sd-summary-icon{margin-right:.6em;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary.sd-summary-title .sd-summary-text{flex-grow:1;line-height:1.5;padding-right:.5rem}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker{pointer-events:none;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker svg{opacity:.6}details.sd-dropdown summary.sd-summary-title:hover .sd-summary-state-marker svg{opacity:1;transform:scale(1.1)}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown .sd-summary-chevron-right{transition:.25s}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-right{transform:rotate(90deg)}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-down{transform:rotate(180deg)}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-bg: rgba(0, 113, 188, 0.2);--sd-color-secondary-bg: rgba(108, 117, 125, 0.2);--sd-color-success-bg: rgba(40, 167, 69, 0.2);--sd-color-info-bg: rgba(23, 162, 184, 0.2);--sd-color-warning-bg: rgba(240, 179, 126, 0.2);--sd-color-danger-bg: rgba(220, 53, 69, 0.2);--sd-color-light-bg: rgba(248, 249, 250, 0.2);--sd-color-muted-bg: rgba(108, 117, 125, 0.2);--sd-color-dark-bg: rgba(33, 37, 41, 0.2);--sd-color-black-bg: rgba(0, 0, 0, 0.2);--sd-color-white-bg: rgba(255, 255, 255, 0.2);--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem;--sd-fontsize-dropdown: inherit;--sd-fontsize-dropdown-title: 1rem;--sd-fontweight-dropdown-title: 700} diff --git a/branch/main/_static/_sphinx_javascript_frameworks_compat.js b/branch/main/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 0000000..8141580 --- /dev/null +++ b/branch/main/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/branch/main/_static/basic.css b/branch/main/_static/basic.css new file mode 100644 index 0000000..f316efc --- /dev/null +++ b/branch/main/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/branch/main/_static/check-solid.svg b/branch/main/_static/check-solid.svg new file mode 100644 index 0000000..92fad4b --- /dev/null +++ b/branch/main/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/branch/main/_static/clipboard.min.js b/branch/main/_static/clipboard.min.js new file mode 100644 index 0000000..54b3c46 --- /dev/null +++ b/branch/main/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/branch/main/_static/copybutton.css b/branch/main/_static/copybutton.css new file mode 100644 index 0000000..f1916ec --- /dev/null +++ b/branch/main/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/branch/main/_static/copybutton.js b/branch/main/_static/copybutton.js new file mode 100644 index 0000000..2ea7ff3 --- /dev/null +++ b/branch/main/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/branch/main/_static/copybutton_funcs.js b/branch/main/_static/copybutton_funcs.js new file mode 100644 index 0000000..dbe1aaa --- /dev/null +++ b/branch/main/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/branch/main/_static/css/badge_only.css b/branch/main/_static/css/badge_only.css new file mode 100644 index 0000000..c718cee --- /dev/null +++ b/branch/main/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/branch/main/_static/css/fonts/Roboto-Slab-Bold.woff b/branch/main/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/branch/main/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/branch/main/_static/css/fonts/Roboto-Slab-Bold.woff2 b/branch/main/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/branch/main/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/branch/main/_static/css/fonts/Roboto-Slab-Regular.woff b/branch/main/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/branch/main/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/branch/main/_static/css/fonts/Roboto-Slab-Regular.woff2 b/branch/main/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/branch/main/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/branch/main/_static/css/fonts/fontawesome-webfont.eot b/branch/main/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/branch/main/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/branch/main/_static/css/fonts/fontawesome-webfont.svg b/branch/main/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/branch/main/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/branch/main/_static/css/fonts/fontawesome-webfont.ttf b/branch/main/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/branch/main/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/branch/main/_static/css/fonts/fontawesome-webfont.woff b/branch/main/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/branch/main/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/branch/main/_static/css/fonts/fontawesome-webfont.woff2 b/branch/main/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/branch/main/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/branch/main/_static/css/fonts/lato-bold-italic.woff b/branch/main/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/branch/main/_static/css/fonts/lato-bold-italic.woff differ diff --git a/branch/main/_static/css/fonts/lato-bold-italic.woff2 b/branch/main/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/branch/main/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/branch/main/_static/css/fonts/lato-bold.woff b/branch/main/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/branch/main/_static/css/fonts/lato-bold.woff differ diff --git a/branch/main/_static/css/fonts/lato-bold.woff2 b/branch/main/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/branch/main/_static/css/fonts/lato-bold.woff2 differ diff --git a/branch/main/_static/css/fonts/lato-normal-italic.woff b/branch/main/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/branch/main/_static/css/fonts/lato-normal-italic.woff differ diff --git a/branch/main/_static/css/fonts/lato-normal-italic.woff2 b/branch/main/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/branch/main/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/branch/main/_static/css/fonts/lato-normal.woff b/branch/main/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/branch/main/_static/css/fonts/lato-normal.woff differ diff --git a/branch/main/_static/css/fonts/lato-normal.woff2 b/branch/main/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/branch/main/_static/css/fonts/lato-normal.woff2 differ diff --git a/branch/main/_static/css/theme.css b/branch/main/_static/css/theme.css new file mode 100644 index 0000000..19a446a --- /dev/null +++ b/branch/main/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/branch/main/_static/design-tabs.js b/branch/main/_static/design-tabs.js new file mode 100644 index 0000000..b25bd6a --- /dev/null +++ b/branch/main/_static/design-tabs.js @@ -0,0 +1,101 @@ +// @ts-check + +// Extra JS capability for selected tabs to be synced +// The selection is stored in local storage so that it persists across page loads. + +/** + * @type {Record} + */ +let sd_id_to_elements = {}; +const storageKeyPrefix = "sphinx-design-tab-id-"; + +/** + * Create a key for a tab element. + * @param {HTMLElement} el - The tab element. + * @returns {[string, string, string] | null} - The key. + * + */ +function create_key(el) { + let syncId = el.getAttribute("data-sync-id"); + let syncGroup = el.getAttribute("data-sync-group"); + if (!syncId || !syncGroup) return null; + return [syncGroup, syncId, syncGroup + "--" + syncId]; +} + +/** + * Initialize the tab selection. + * + */ +function ready() { + // Find all tabs with sync data + + /** @type {string[]} */ + let groups = []; + + document.querySelectorAll(".sd-tab-label").forEach((label) => { + if (label instanceof HTMLElement) { + let data = create_key(label); + if (data) { + let [group, id, key] = data; + + // add click event listener + // @ts-ignore + label.onclick = onSDLabelClick; + + // store map of key to elements + if (!sd_id_to_elements[key]) { + sd_id_to_elements[key] = []; + } + sd_id_to_elements[key].push(label); + + if (groups.indexOf(group) === -1) { + groups.push(group); + // Check if a specific tab has been selected via URL parameter + const tabParam = new URLSearchParams(window.location.search).get( + group + ); + if (tabParam) { + console.log( + "sphinx-design: Selecting tab id for group '" + + group + + "' from URL parameter: " + + tabParam + ); + window.sessionStorage.setItem(storageKeyPrefix + group, tabParam); + } + } + + // Check is a specific tab has been selected previously + let previousId = window.sessionStorage.getItem( + storageKeyPrefix + group + ); + if (previousId === id) { + // console.log( + // "sphinx-design: Selecting tab from session storage: " + id + // ); + // @ts-ignore + label.previousElementSibling.checked = true; + } + } + } + }); +} + +/** + * Activate other tabs with the same sync id. + * + * @this {HTMLElement} - The element that was clicked. + */ +function onSDLabelClick() { + let data = create_key(this); + if (!data) return; + let [group, id, key] = data; + for (const label of sd_id_to_elements[key]) { + if (label === this) continue; + // @ts-ignore + label.previousElementSibling.checked = true; + } + window.sessionStorage.setItem(storageKeyPrefix + group, id); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/branch/main/_static/doctools.js b/branch/main/_static/doctools.js new file mode 100644 index 0000000..4d67807 --- /dev/null +++ b/branch/main/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/branch/main/_static/documentation_options.js b/branch/main/_static/documentation_options.js new file mode 100644 index 0000000..87fc516 --- /dev/null +++ b/branch/main/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'dirhtml', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/branch/main/_static/file.png b/branch/main/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/branch/main/_static/file.png differ diff --git a/branch/main/_static/jquery.js b/branch/main/_static/jquery.js new file mode 100644 index 0000000..c4c6022 --- /dev/null +++ b/branch/main/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!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(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=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,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).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 w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\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(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.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,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){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 H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.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--)b.attrHandle[n[r]]=t}function pe(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 de(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 d=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")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.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}},b.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[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.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},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),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(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.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},j=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)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(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==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(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?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{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 G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.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("(^|"+M+")"+e+"("+M+"|$)"))&&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:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.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 S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(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").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.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),m(t)&&(t=t.call(e,n,S.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)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.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"===S.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"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.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)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.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?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.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)}}),S.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){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/main/_static/js/html5shiv.min.js b/branch/main/_static/js/html5shiv.min.js new file mode 100644 index 0000000..cd1c674 --- /dev/null +++ b/branch/main/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/main/_static/js/theme.js b/branch/main/_static/js/theme.js new file mode 100644 index 0000000..1fddb6e --- /dev/null +++ b/branch/main/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/branch/main/_static/minipres.js b/branch/main/_static/minipres.js new file mode 100644 index 0000000..ad11c87 --- /dev/null +++ b/branch/main/_static/minipres.js @@ -0,0 +1,223 @@ +// Add goTo method to elements +// http://stackoverflow.com/questions/4801655/how-to-go-to-a-specific-element-on-page +(function($) { + $.fn.goTo = function() { + $('html, body').animate({ + scrollTop: $(this).offset().top //+ 'px' + }, 'fast'); + return this; // for chaining... + } +})(jQuery); + +// NO good way to do this!. Copy a hack from here +// https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript +// https://stackoverflow.com/a/2880929 +var urlParams; +(window.onpopstate = function () { + var match, + pl = /\+/g, // Regex for replacing addition symbol with a space + search = /([^&=]+)=?([^&]*)/g, + decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, + query = window.location.search.substring(1); + urlParams = {}; + while (match = search.exec(query)) + urlParams[decode(match[1])] = decode(match[2]); +})(); + +// Select heading levels +var maxHeading = urlParams['h'] +if (maxHeading === undefined) maxHeading = 2 +var headingLevels = []; +for (h=2 ; h (sections.length-1) ) { + // if we would scroll past bottom, or above top, do nothing + return; + } + + console.log('xxxxxx'); + var targetSection = sections[targetPos]; + console.log(targetSection, typeof(targetSection)); + + // Return targetSection top and height + var secProperties = section_top_and_height(targetSection); + var top = secProperties['top']; + var height = secProperties['height'] + var win_height = window.innerHeight; + //console.info(top, height, win_height) + + var scroll_to = 0; + if (height >= win_height || height == 0) { + scroll_to = top; + } else { + scroll_to = top - (win_height-height)/3.; + } + //console.info(top, height, win_height, scroll_to) + + $('html, body').animate({ + scrollTop: scroll_to //+ 'px' + }, 'fast'); + +} + + +function minipres() { + /* Enable the minipres mode: + - call the hide() function + - set up the scrolling listener + */ + document.addEventListener('keydown', function (event) { + switch(event.which) { + case 37: // left + switch_slide(-1); + event.preventDefault(); + return false; + break; + //case 38: // up + case 39: // right + switch_slide(+1); + event.preventDefault(); + return false; + break; + //case 40: // down + default: + return; // exit this handler for other keys + } + }, true) + + hide() + + // Increase space between sections + //$("div .section").css('margin-bottom', '50%'); + $(sectionSelector).css('margin-top', '50%'); + + // Reduce size/color of other sections + if (hiddenSectionSelector.length > 0) { + var hideNodes = $(hiddenSectionSelector); + console.log(typeof hideNodes, hideNodes); + for (node in hideNodes) { + console.log("a", typeof node, node); + node = hideNodes[node]; // what's right way to iterate values? + console.log("b", typeof node, node); + if (node.parentNode && node.parentNode.className == "section") { + node = node.parentNode; + console.log("c", typeof node, node); + //node.css['transform'] = 'scale(.5)'; + //node.css['transform-origin'] = 'top center'; + $(node).css('color', 'lightgrey'); + //$(node).css('font-size', '20%'); + //$(node).css('visibility', 'collapse'); + //ntahousnatouhasno; + } + } + } +} + +function hide() { + /* Hide all non-essential elements on the page + */ + + // This is for sphinx_rst_theme and readthedocs + $(".wy-nav-side").remove(); + $(".wy-nav-content-wrap").css('margin-left', 0); + $('.rst-versions').remove(); // readthedocs version selector + + // Add other formats here. +} + + +var slideshow = minipres; + +if (window.location.search.match(/[?&](minipres|slideshow|pres)([=&]|$)/) ) { + //minipres() + window.addEventListener("load", minipres); +} else if (window.location.search.match(/[?&](plain)([=&]|$)/) ) { + window.addEventListener("load", hide); +} diff --git a/branch/main/_static/minus.png b/branch/main/_static/minus.png new file mode 100644 index 0000000..d96755f Binary files /dev/null and b/branch/main/_static/minus.png differ diff --git a/branch/main/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css b/branch/main/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css new file mode 100644 index 0000000..3356631 --- /dev/null +++ b/branch/main/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css @@ -0,0 +1,2342 @@ +/* Variables */ +:root { + --mystnb-source-bg-color: #f7f7f7; + --mystnb-stdout-bg-color: #fcfcfc; + --mystnb-stderr-bg-color: #fdd; + --mystnb-traceback-bg-color: #fcfcfc; + --mystnb-source-border-color: #ccc; + --mystnb-source-margin-color: green; + --mystnb-stdout-border-color: #f7f7f7; + --mystnb-stderr-border-color: #f7f7f7; + --mystnb-traceback-border-color: #ffd6d6; + --mystnb-hide-prompt-opacity: 70%; + --mystnb-source-border-radius: .4em; + --mystnb-source-border-width: 1px; +} + +/* Whole cell */ +div.container.cell { + padding-left: 0; + margin-bottom: 1em; +} + +/* Removing all background formatting so we can control at the div level */ +.cell_input div.highlight, +.cell_output pre, +.cell_input pre, +.cell_output .output { + border: none; + box-shadow: none; +} + +.cell_output .output pre, +.cell_input pre { + margin: 0px; +} + +/* Input cells */ +div.cell div.cell_input, +div.cell details.above-input>summary { + padding-left: 0em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + background-color: var(--mystnb-source-bg-color); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; + border-radius: var(--mystnb-source-border-radius); +} + +div.cell_input>div, +div.cell_output div.output>div.highlight { + margin: 0em !important; + border: none !important; +} + +/* All cell outputs */ +.cell_output { + padding-left: 1em; + padding-right: 0em; + margin-top: 1em; +} + +/* Text outputs from cells */ +.cell_output .output.text_plain, +.cell_output .output.traceback, +.cell_output .output.stream, +.cell_output .output.stderr { + margin-top: 1em; + margin-bottom: 0em; + box-shadow: none; +} + +.cell_output .output.text_plain, +.cell_output .output.stream { + background: var(--mystnb-stdout-bg-color); + border: 1px solid var(--mystnb-stdout-border-color); +} + +.cell_output .output.stderr { + background: var(--mystnb-stderr-bg-color); + border: 1px solid var(--mystnb-stderr-border-color); +} + +.cell_output .output.traceback { + background: var(--mystnb-traceback-bg-color); + border: 1px solid var(--mystnb-traceback-border-color); +} + +/* Collapsible cell content */ +div.cell details.above-input div.cell_input { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-top: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; +} + +div.cell div.cell_input.above-output-prompt { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +div.cell details.above-input>summary { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; + padding-left: 1em; + margin-bottom: 0; +} + +div.cell details.above-output>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.below-input>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-top: none; + border-bottom-left-radius: var(--mystnb-source-border-radius); + border-bottom-right-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.hide>summary>span { + opacity: var(--mystnb-hide-prompt-opacity); +} + +div.cell details.hide[open]>summary>span.collapsed { + display: none; +} + +div.cell details.hide:not([open])>summary>span.expanded { + display: none; +} + +@keyframes collapsed-fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} +div.cell details.hide[open]>summary~* { + -moz-animation: collapsed-fade-in 0.3s ease-in-out; + -webkit-animation: collapsed-fade-in 0.3s ease-in-out; + animation: collapsed-fade-in 0.3s ease-in-out; +} + +/* Math align to the left */ +.cell_output .MathJax_Display { + text-align: left !important; +} + +/* Pandas tables. Pulled from the Jupyter / nbsphinx CSS */ +div.cell_output table { + border: none; + border-collapse: collapse; + border-spacing: 0; + color: black; + font-size: 1em; + table-layout: fixed; +} + +div.cell_output thead { + border-bottom: 1px solid black; + vertical-align: bottom; +} + +div.cell_output tr, +div.cell_output th, +div.cell_output td { + text-align: right; + vertical-align: middle; + padding: 0.5em 0.5em; + line-height: normal; + white-space: normal; + max-width: none; + border: none; +} + +div.cell_output th { + font-weight: bold; +} + +div.cell_output tbody tr:nth-child(odd) { + background: #f5f5f5; +} + +div.cell_output tbody tr:hover { + background: rgba(66, 165, 245, 0.2); +} + +/** source code line numbers **/ +span.linenos { + opacity: 0.5; +} + +/* Inline text from `paste` operation */ + +span.pasted-text { + font-weight: bold; +} + +span.pasted-inline img { + max-height: 2em; +} + +tbody span.pasted-inline img { + max-height: none; +} + +/* Font colors for translated ANSI escape sequences +Color values are copied from Jupyter Notebook +https://github.com/jupyter/notebook/blob/52581f8eda9b319eb0390ac77fe5903c38f81e3e/notebook/static/notebook/less/ansicolors.less#L14-L21 +Background colors from +https://nbsphinx.readthedocs.io/en/latest/code-cells.html#ANSI-Colors +*/ +div.highlight .-Color-Bold { + font-weight: bold; +} + +div.highlight .-Color[class*=-Black] { + color: #3E424D +} + +div.highlight .-Color[class*=-Red] { + color: #E75C58 +} + +div.highlight .-Color[class*=-Green] { + color: #00A250 +} + +div.highlight .-Color[class*=-Yellow] { + color: #DDB62B +} + +div.highlight .-Color[class*=-Blue] { + color: #208FFB +} + +div.highlight .-Color[class*=-Magenta] { + color: #D160C4 +} + +div.highlight .-Color[class*=-Cyan] { + color: #60C6C8 +} + +div.highlight .-Color[class*=-White] { + color: #C5C1B4 +} + +div.highlight .-Color[class*=-BGBlack] { + background-color: #3E424D +} + +div.highlight .-Color[class*=-BGRed] { + background-color: #E75C58 +} + +div.highlight .-Color[class*=-BGGreen] { + background-color: #00A250 +} + +div.highlight .-Color[class*=-BGYellow] { + background-color: #DDB62B +} + +div.highlight .-Color[class*=-BGBlue] { + background-color: #208FFB +} + +div.highlight .-Color[class*=-BGMagenta] { + background-color: #D160C4 +} + +div.highlight .-Color[class*=-BGCyan] { + background-color: #60C6C8 +} + +div.highlight .-Color[class*=-BGWhite] { + background-color: #C5C1B4 +} + +/* Font colors for 8-bit ANSI */ + +div.highlight .-Color[class*=-C0] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC0] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C1] { + color: #800000 +} + +div.highlight .-Color[class*=-BGC1] { + background-color: #800000 +} + +div.highlight .-Color[class*=-C2] { + color: #008000 +} + +div.highlight .-Color[class*=-BGC2] { + background-color: #008000 +} + +div.highlight .-Color[class*=-C3] { + color: #808000 +} + +div.highlight .-Color[class*=-BGC3] { + background-color: #808000 +} + +div.highlight .-Color[class*=-C4] { + color: #000080 +} + +div.highlight .-Color[class*=-BGC4] { + background-color: #000080 +} + +div.highlight .-Color[class*=-C5] { + color: #800080 +} + +div.highlight .-Color[class*=-BGC5] { + background-color: #800080 +} + +div.highlight .-Color[class*=-C6] { + color: #008080 +} + +div.highlight .-Color[class*=-BGC6] { + background-color: #008080 +} + +div.highlight .-Color[class*=-C7] { + color: #C0C0C0 +} + +div.highlight .-Color[class*=-BGC7] { + background-color: #C0C0C0 +} + +div.highlight .-Color[class*=-C8] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC8] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C9] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC9] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C10] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC10] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C11] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC11] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C12] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC12] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C13] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC13] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C14] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC14] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C15] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC15] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C16] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC16] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C17] { + color: #00005F +} + +div.highlight .-Color[class*=-BGC17] { + background-color: #00005F +} + +div.highlight .-Color[class*=-C18] { + color: #000087 +} + +div.highlight .-Color[class*=-BGC18] { + background-color: #000087 +} + +div.highlight .-Color[class*=-C19] { + color: #0000AF +} + +div.highlight .-Color[class*=-BGC19] { + background-color: #0000AF +} + +div.highlight .-Color[class*=-C20] { + color: #0000D7 +} + +div.highlight .-Color[class*=-BGC20] { + background-color: #0000D7 +} + +div.highlight .-Color[class*=-C21] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC21] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C22] { + color: #005F00 +} + +div.highlight .-Color[class*=-BGC22] { + background-color: #005F00 +} + +div.highlight .-Color[class*=-C23] { + color: #005F5F +} + +div.highlight .-Color[class*=-BGC23] { + background-color: #005F5F +} + +div.highlight .-Color[class*=-C24] { + color: #005F87 +} + +div.highlight .-Color[class*=-BGC24] { + background-color: #005F87 +} + +div.highlight .-Color[class*=-C25] { + color: #005FAF +} + +div.highlight .-Color[class*=-BGC25] { + background-color: #005FAF +} + +div.highlight .-Color[class*=-C26] { + color: #005FD7 +} + +div.highlight .-Color[class*=-BGC26] { + background-color: #005FD7 +} + +div.highlight .-Color[class*=-C27] { + color: #005FFF +} + +div.highlight .-Color[class*=-BGC27] { + background-color: #005FFF +} + +div.highlight .-Color[class*=-C28] { + color: #008700 +} + +div.highlight .-Color[class*=-BGC28] { + background-color: #008700 +} + +div.highlight .-Color[class*=-C29] { + color: #00875F +} + +div.highlight .-Color[class*=-BGC29] { + background-color: #00875F +} + +div.highlight .-Color[class*=-C30] { + color: #008787 +} + +div.highlight .-Color[class*=-BGC30] { + background-color: #008787 +} + +div.highlight .-Color[class*=-C31] { + color: #0087AF +} + +div.highlight .-Color[class*=-BGC31] { + background-color: #0087AF +} + +div.highlight .-Color[class*=-C32] { + color: #0087D7 +} + +div.highlight .-Color[class*=-BGC32] { + background-color: #0087D7 +} + +div.highlight .-Color[class*=-C33] { + color: #0087FF +} + +div.highlight .-Color[class*=-BGC33] { + background-color: #0087FF +} + +div.highlight .-Color[class*=-C34] { + color: #00AF00 +} + +div.highlight .-Color[class*=-BGC34] { + background-color: #00AF00 +} + +div.highlight .-Color[class*=-C35] { + color: #00AF5F +} + +div.highlight .-Color[class*=-BGC35] { + background-color: #00AF5F +} + +div.highlight .-Color[class*=-C36] { + color: #00AF87 +} + +div.highlight .-Color[class*=-BGC36] { + background-color: #00AF87 +} + +div.highlight .-Color[class*=-C37] { + color: #00AFAF +} + +div.highlight .-Color[class*=-BGC37] { + background-color: #00AFAF +} + +div.highlight .-Color[class*=-C38] { + color: #00AFD7 +} + +div.highlight .-Color[class*=-BGC38] { + background-color: #00AFD7 +} + +div.highlight .-Color[class*=-C39] { + color: #00AFFF +} + +div.highlight .-Color[class*=-BGC39] { + background-color: #00AFFF +} + +div.highlight .-Color[class*=-C40] { + color: #00D700 +} + +div.highlight .-Color[class*=-BGC40] { + background-color: #00D700 +} + +div.highlight .-Color[class*=-C41] { + color: #00D75F +} + +div.highlight .-Color[class*=-BGC41] { + background-color: #00D75F +} + +div.highlight .-Color[class*=-C42] { + color: #00D787 +} + +div.highlight .-Color[class*=-BGC42] { + background-color: #00D787 +} + +div.highlight .-Color[class*=-C43] { + color: #00D7AF +} + +div.highlight .-Color[class*=-BGC43] { + background-color: #00D7AF +} + +div.highlight .-Color[class*=-C44] { + color: #00D7D7 +} + +div.highlight .-Color[class*=-BGC44] { + background-color: #00D7D7 +} + +div.highlight .-Color[class*=-C45] { + color: #00D7FF +} + +div.highlight .-Color[class*=-BGC45] { + background-color: #00D7FF +} + +div.highlight .-Color[class*=-C46] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC46] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C47] { + color: #00FF5F +} + +div.highlight .-Color[class*=-BGC47] { + background-color: #00FF5F +} + +div.highlight .-Color[class*=-C48] { + color: #00FF87 +} + +div.highlight .-Color[class*=-BGC48] { + background-color: #00FF87 +} + +div.highlight .-Color[class*=-C49] { + color: #00FFAF +} + +div.highlight .-Color[class*=-BGC49] { + background-color: #00FFAF +} + +div.highlight .-Color[class*=-C50] { + color: #00FFD7 +} + +div.highlight .-Color[class*=-BGC50] { + background-color: #00FFD7 +} + +div.highlight .-Color[class*=-C51] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC51] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C52] { + color: #5F0000 +} + +div.highlight .-Color[class*=-BGC52] { + background-color: #5F0000 +} + +div.highlight .-Color[class*=-C53] { + color: #5F005F +} + +div.highlight .-Color[class*=-BGC53] { + background-color: #5F005F +} + +div.highlight .-Color[class*=-C54] { + color: #5F0087 +} + +div.highlight .-Color[class*=-BGC54] { + background-color: #5F0087 +} + +div.highlight .-Color[class*=-C55] { + color: #5F00AF +} + +div.highlight .-Color[class*=-BGC55] { + background-color: #5F00AF +} + +div.highlight .-Color[class*=-C56] { + color: #5F00D7 +} + +div.highlight .-Color[class*=-BGC56] { + background-color: #5F00D7 +} + +div.highlight .-Color[class*=-C57] { + color: #5F00FF +} + +div.highlight .-Color[class*=-BGC57] { + background-color: #5F00FF +} + +div.highlight .-Color[class*=-C58] { + color: #5F5F00 +} + +div.highlight .-Color[class*=-BGC58] { + background-color: #5F5F00 +} + +div.highlight .-Color[class*=-C59] { + color: #5F5F5F +} + +div.highlight .-Color[class*=-BGC59] { + background-color: #5F5F5F +} + +div.highlight .-Color[class*=-C60] { + color: #5F5F87 +} + +div.highlight .-Color[class*=-BGC60] { + background-color: #5F5F87 +} + +div.highlight .-Color[class*=-C61] { + color: #5F5FAF +} + +div.highlight .-Color[class*=-BGC61] { + background-color: #5F5FAF +} + +div.highlight .-Color[class*=-C62] { + color: #5F5FD7 +} + +div.highlight .-Color[class*=-BGC62] { + background-color: #5F5FD7 +} + +div.highlight .-Color[class*=-C63] { + color: #5F5FFF +} + +div.highlight .-Color[class*=-BGC63] { + background-color: #5F5FFF +} + +div.highlight .-Color[class*=-C64] { + color: #5F8700 +} + +div.highlight .-Color[class*=-BGC64] { + background-color: #5F8700 +} + +div.highlight .-Color[class*=-C65] { + color: #5F875F +} + +div.highlight .-Color[class*=-BGC65] { + background-color: #5F875F +} + +div.highlight .-Color[class*=-C66] { + color: #5F8787 +} + +div.highlight .-Color[class*=-BGC66] { + background-color: #5F8787 +} + +div.highlight .-Color[class*=-C67] { + color: #5F87AF +} + +div.highlight .-Color[class*=-BGC67] { + background-color: #5F87AF +} + +div.highlight .-Color[class*=-C68] { + color: #5F87D7 +} + +div.highlight .-Color[class*=-BGC68] { + background-color: #5F87D7 +} + +div.highlight .-Color[class*=-C69] { + color: #5F87FF +} + +div.highlight .-Color[class*=-BGC69] { + background-color: #5F87FF +} + +div.highlight .-Color[class*=-C70] { + color: #5FAF00 +} + +div.highlight .-Color[class*=-BGC70] { + background-color: #5FAF00 +} + +div.highlight .-Color[class*=-C71] { + color: #5FAF5F +} + +div.highlight .-Color[class*=-BGC71] { + background-color: #5FAF5F +} + +div.highlight .-Color[class*=-C72] { + color: #5FAF87 +} + +div.highlight .-Color[class*=-BGC72] { + background-color: #5FAF87 +} + +div.highlight .-Color[class*=-C73] { + color: #5FAFAF +} + +div.highlight .-Color[class*=-BGC73] { + background-color: #5FAFAF +} + +div.highlight .-Color[class*=-C74] { + color: #5FAFD7 +} + +div.highlight .-Color[class*=-BGC74] { + background-color: #5FAFD7 +} + +div.highlight .-Color[class*=-C75] { + color: #5FAFFF +} + +div.highlight .-Color[class*=-BGC75] { + background-color: #5FAFFF +} + +div.highlight .-Color[class*=-C76] { + color: #5FD700 +} + +div.highlight .-Color[class*=-BGC76] { + background-color: #5FD700 +} + +div.highlight .-Color[class*=-C77] { + color: #5FD75F +} + +div.highlight .-Color[class*=-BGC77] { + background-color: #5FD75F +} + +div.highlight .-Color[class*=-C78] { + color: #5FD787 +} + +div.highlight .-Color[class*=-BGC78] { + background-color: #5FD787 +} + +div.highlight .-Color[class*=-C79] { + color: #5FD7AF +} + +div.highlight .-Color[class*=-BGC79] { + background-color: #5FD7AF +} + +div.highlight .-Color[class*=-C80] { + color: #5FD7D7 +} + +div.highlight .-Color[class*=-BGC80] { + background-color: #5FD7D7 +} + +div.highlight .-Color[class*=-C81] { + color: #5FD7FF +} + +div.highlight .-Color[class*=-BGC81] { + background-color: #5FD7FF +} + +div.highlight .-Color[class*=-C82] { + color: #5FFF00 +} + +div.highlight .-Color[class*=-BGC82] { + background-color: #5FFF00 +} + +div.highlight .-Color[class*=-C83] { + color: #5FFF5F +} + +div.highlight .-Color[class*=-BGC83] { + background-color: #5FFF5F +} + +div.highlight .-Color[class*=-C84] { + color: #5FFF87 +} + +div.highlight .-Color[class*=-BGC84] { + background-color: #5FFF87 +} + +div.highlight .-Color[class*=-C85] { + color: #5FFFAF +} + +div.highlight .-Color[class*=-BGC85] { + background-color: #5FFFAF +} + +div.highlight .-Color[class*=-C86] { + color: #5FFFD7 +} + +div.highlight .-Color[class*=-BGC86] { + background-color: #5FFFD7 +} + +div.highlight .-Color[class*=-C87] { + color: #5FFFFF +} + +div.highlight .-Color[class*=-BGC87] { + background-color: #5FFFFF +} + +div.highlight .-Color[class*=-C88] { + color: #870000 +} + +div.highlight .-Color[class*=-BGC88] { + background-color: #870000 +} + +div.highlight .-Color[class*=-C89] { + color: #87005F +} + +div.highlight .-Color[class*=-BGC89] { + background-color: #87005F +} + +div.highlight .-Color[class*=-C90] { + color: #870087 +} + +div.highlight .-Color[class*=-BGC90] { + background-color: #870087 +} + +div.highlight .-Color[class*=-C91] { + color: #8700AF +} + +div.highlight .-Color[class*=-BGC91] { + background-color: #8700AF +} + +div.highlight .-Color[class*=-C92] { + color: #8700D7 +} + +div.highlight .-Color[class*=-BGC92] { + background-color: #8700D7 +} + +div.highlight .-Color[class*=-C93] { + color: #8700FF +} + +div.highlight .-Color[class*=-BGC93] { + background-color: #8700FF +} + +div.highlight .-Color[class*=-C94] { + color: #875F00 +} + +div.highlight .-Color[class*=-BGC94] { + background-color: #875F00 +} + +div.highlight .-Color[class*=-C95] { + color: #875F5F +} + +div.highlight .-Color[class*=-BGC95] { + background-color: #875F5F +} + +div.highlight .-Color[class*=-C96] { + color: #875F87 +} + +div.highlight .-Color[class*=-BGC96] { + background-color: #875F87 +} + +div.highlight .-Color[class*=-C97] { + color: #875FAF +} + +div.highlight .-Color[class*=-BGC97] { + background-color: #875FAF +} + +div.highlight .-Color[class*=-C98] { + color: #875FD7 +} + +div.highlight .-Color[class*=-BGC98] { + background-color: #875FD7 +} + +div.highlight .-Color[class*=-C99] { + color: #875FFF +} + +div.highlight .-Color[class*=-BGC99] { + background-color: #875FFF +} + +div.highlight .-Color[class*=-C100] { + color: #878700 +} + +div.highlight .-Color[class*=-BGC100] { + background-color: #878700 +} + +div.highlight .-Color[class*=-C101] { + color: #87875F +} + +div.highlight .-Color[class*=-BGC101] { + background-color: #87875F +} + +div.highlight .-Color[class*=-C102] { + color: #878787 +} + +div.highlight .-Color[class*=-BGC102] { + background-color: #878787 +} + +div.highlight .-Color[class*=-C103] { + color: #8787AF +} + +div.highlight .-Color[class*=-BGC103] { + background-color: #8787AF +} + +div.highlight .-Color[class*=-C104] { + color: #8787D7 +} + +div.highlight .-Color[class*=-BGC104] { + background-color: #8787D7 +} + +div.highlight .-Color[class*=-C105] { + color: #8787FF +} + +div.highlight .-Color[class*=-BGC105] { + background-color: #8787FF +} + +div.highlight .-Color[class*=-C106] { + color: #87AF00 +} + +div.highlight .-Color[class*=-BGC106] { + background-color: #87AF00 +} + +div.highlight .-Color[class*=-C107] { + color: #87AF5F +} + +div.highlight .-Color[class*=-BGC107] { + background-color: #87AF5F +} + +div.highlight .-Color[class*=-C108] { + color: #87AF87 +} + +div.highlight .-Color[class*=-BGC108] { + background-color: #87AF87 +} + +div.highlight .-Color[class*=-C109] { + color: #87AFAF +} + +div.highlight .-Color[class*=-BGC109] { + background-color: #87AFAF +} + +div.highlight .-Color[class*=-C110] { + color: #87AFD7 +} + +div.highlight .-Color[class*=-BGC110] { + background-color: #87AFD7 +} + +div.highlight .-Color[class*=-C111] { + color: #87AFFF +} + +div.highlight .-Color[class*=-BGC111] { + background-color: #87AFFF +} + +div.highlight .-Color[class*=-C112] { + color: #87D700 +} + +div.highlight .-Color[class*=-BGC112] { + background-color: #87D700 +} + +div.highlight .-Color[class*=-C113] { + color: #87D75F +} + +div.highlight .-Color[class*=-BGC113] { + background-color: #87D75F +} + +div.highlight .-Color[class*=-C114] { + color: #87D787 +} + +div.highlight .-Color[class*=-BGC114] { + background-color: #87D787 +} + +div.highlight .-Color[class*=-C115] { + color: #87D7AF +} + +div.highlight .-Color[class*=-BGC115] { + background-color: #87D7AF +} + +div.highlight .-Color[class*=-C116] { + color: #87D7D7 +} + +div.highlight .-Color[class*=-BGC116] { + background-color: #87D7D7 +} + +div.highlight .-Color[class*=-C117] { + color: #87D7FF +} + +div.highlight .-Color[class*=-BGC117] { + background-color: #87D7FF +} + +div.highlight .-Color[class*=-C118] { + color: #87FF00 +} + +div.highlight .-Color[class*=-BGC118] { + background-color: #87FF00 +} + +div.highlight .-Color[class*=-C119] { + color: #87FF5F +} + +div.highlight .-Color[class*=-BGC119] { + background-color: #87FF5F +} + +div.highlight .-Color[class*=-C120] { + color: #87FF87 +} + +div.highlight .-Color[class*=-BGC120] { + background-color: #87FF87 +} + +div.highlight .-Color[class*=-C121] { + color: #87FFAF +} + +div.highlight .-Color[class*=-BGC121] { + background-color: #87FFAF +} + +div.highlight .-Color[class*=-C122] { + color: #87FFD7 +} + +div.highlight .-Color[class*=-BGC122] { + background-color: #87FFD7 +} + +div.highlight .-Color[class*=-C123] { + color: #87FFFF +} + +div.highlight .-Color[class*=-BGC123] { + background-color: #87FFFF +} + +div.highlight .-Color[class*=-C124] { + color: #AF0000 +} + +div.highlight .-Color[class*=-BGC124] { + background-color: #AF0000 +} + +div.highlight .-Color[class*=-C125] { + color: #AF005F +} + +div.highlight .-Color[class*=-BGC125] { + background-color: #AF005F +} + +div.highlight .-Color[class*=-C126] { + color: #AF0087 +} + +div.highlight .-Color[class*=-BGC126] { + background-color: #AF0087 +} + +div.highlight .-Color[class*=-C127] { + color: #AF00AF +} + +div.highlight .-Color[class*=-BGC127] { + background-color: #AF00AF +} + +div.highlight .-Color[class*=-C128] { + color: #AF00D7 +} + +div.highlight .-Color[class*=-BGC128] { + background-color: #AF00D7 +} + +div.highlight .-Color[class*=-C129] { + color: #AF00FF +} + +div.highlight .-Color[class*=-BGC129] { + background-color: #AF00FF +} + +div.highlight .-Color[class*=-C130] { + color: #AF5F00 +} + +div.highlight .-Color[class*=-BGC130] { + background-color: #AF5F00 +} + +div.highlight .-Color[class*=-C131] { + color: #AF5F5F +} + +div.highlight .-Color[class*=-BGC131] { + background-color: #AF5F5F +} + +div.highlight .-Color[class*=-C132] { + color: #AF5F87 +} + +div.highlight .-Color[class*=-BGC132] { + background-color: #AF5F87 +} + +div.highlight .-Color[class*=-C133] { + color: #AF5FAF +} + +div.highlight .-Color[class*=-BGC133] { + background-color: #AF5FAF +} + +div.highlight .-Color[class*=-C134] { + color: #AF5FD7 +} + +div.highlight .-Color[class*=-BGC134] { + background-color: #AF5FD7 +} + +div.highlight .-Color[class*=-C135] { + color: #AF5FFF +} + +div.highlight .-Color[class*=-BGC135] { + background-color: #AF5FFF +} + +div.highlight .-Color[class*=-C136] { + color: #AF8700 +} + +div.highlight .-Color[class*=-BGC136] { + background-color: #AF8700 +} + +div.highlight .-Color[class*=-C137] { + color: #AF875F +} + +div.highlight .-Color[class*=-BGC137] { + background-color: #AF875F +} + +div.highlight .-Color[class*=-C138] { + color: #AF8787 +} + +div.highlight .-Color[class*=-BGC138] { + background-color: #AF8787 +} + +div.highlight .-Color[class*=-C139] { + color: #AF87AF +} + +div.highlight .-Color[class*=-BGC139] { + background-color: #AF87AF +} + +div.highlight .-Color[class*=-C140] { + color: #AF87D7 +} + +div.highlight .-Color[class*=-BGC140] { + background-color: #AF87D7 +} + +div.highlight .-Color[class*=-C141] { + color: #AF87FF +} + +div.highlight .-Color[class*=-BGC141] { + background-color: #AF87FF +} + +div.highlight .-Color[class*=-C142] { + color: #AFAF00 +} + +div.highlight .-Color[class*=-BGC142] { + background-color: #AFAF00 +} + +div.highlight .-Color[class*=-C143] { + color: #AFAF5F +} + +div.highlight .-Color[class*=-BGC143] { + background-color: #AFAF5F +} + +div.highlight .-Color[class*=-C144] { + color: #AFAF87 +} + +div.highlight .-Color[class*=-BGC144] { + background-color: #AFAF87 +} + +div.highlight .-Color[class*=-C145] { + color: #AFAFAF +} + +div.highlight .-Color[class*=-BGC145] { + background-color: #AFAFAF +} + +div.highlight .-Color[class*=-C146] { + color: #AFAFD7 +} + +div.highlight .-Color[class*=-BGC146] { + background-color: #AFAFD7 +} + +div.highlight .-Color[class*=-C147] { + color: #AFAFFF +} + +div.highlight .-Color[class*=-BGC147] { + background-color: #AFAFFF +} + +div.highlight .-Color[class*=-C148] { + color: #AFD700 +} + +div.highlight .-Color[class*=-BGC148] { + background-color: #AFD700 +} + +div.highlight .-Color[class*=-C149] { + color: #AFD75F +} + +div.highlight .-Color[class*=-BGC149] { + background-color: #AFD75F +} + +div.highlight .-Color[class*=-C150] { + color: #AFD787 +} + +div.highlight .-Color[class*=-BGC150] { + background-color: #AFD787 +} + +div.highlight .-Color[class*=-C151] { + color: #AFD7AF +} + +div.highlight .-Color[class*=-BGC151] { + background-color: #AFD7AF +} + +div.highlight .-Color[class*=-C152] { + color: #AFD7D7 +} + +div.highlight .-Color[class*=-BGC152] { + background-color: #AFD7D7 +} + +div.highlight .-Color[class*=-C153] { + color: #AFD7FF +} + +div.highlight .-Color[class*=-BGC153] { + background-color: #AFD7FF +} + +div.highlight .-Color[class*=-C154] { + color: #AFFF00 +} + +div.highlight .-Color[class*=-BGC154] { + background-color: #AFFF00 +} + +div.highlight .-Color[class*=-C155] { + color: #AFFF5F +} + +div.highlight .-Color[class*=-BGC155] { + background-color: #AFFF5F +} + +div.highlight .-Color[class*=-C156] { + color: #AFFF87 +} + +div.highlight .-Color[class*=-BGC156] { + background-color: #AFFF87 +} + +div.highlight .-Color[class*=-C157] { + color: #AFFFAF +} + +div.highlight .-Color[class*=-BGC157] { + background-color: #AFFFAF +} + +div.highlight .-Color[class*=-C158] { + color: #AFFFD7 +} + +div.highlight .-Color[class*=-BGC158] { + background-color: #AFFFD7 +} + +div.highlight .-Color[class*=-C159] { + color: #AFFFFF +} + +div.highlight .-Color[class*=-BGC159] { + background-color: #AFFFFF +} + +div.highlight .-Color[class*=-C160] { + color: #D70000 +} + +div.highlight .-Color[class*=-BGC160] { + background-color: #D70000 +} + +div.highlight .-Color[class*=-C161] { + color: #D7005F +} + +div.highlight .-Color[class*=-BGC161] { + background-color: #D7005F +} + +div.highlight .-Color[class*=-C162] { + color: #D70087 +} + +div.highlight .-Color[class*=-BGC162] { + background-color: #D70087 +} + +div.highlight .-Color[class*=-C163] { + color: #D700AF +} + +div.highlight .-Color[class*=-BGC163] { + background-color: #D700AF +} + +div.highlight .-Color[class*=-C164] { + color: #D700D7 +} + +div.highlight .-Color[class*=-BGC164] { + background-color: #D700D7 +} + +div.highlight .-Color[class*=-C165] { + color: #D700FF +} + +div.highlight .-Color[class*=-BGC165] { + background-color: #D700FF +} + +div.highlight .-Color[class*=-C166] { + color: #D75F00 +} + +div.highlight .-Color[class*=-BGC166] { + background-color: #D75F00 +} + +div.highlight .-Color[class*=-C167] { + color: #D75F5F +} + +div.highlight .-Color[class*=-BGC167] { + background-color: #D75F5F +} + +div.highlight .-Color[class*=-C168] { + color: #D75F87 +} + +div.highlight .-Color[class*=-BGC168] { + background-color: #D75F87 +} + +div.highlight .-Color[class*=-C169] { + color: #D75FAF +} + +div.highlight .-Color[class*=-BGC169] { + background-color: #D75FAF +} + +div.highlight .-Color[class*=-C170] { + color: #D75FD7 +} + +div.highlight .-Color[class*=-BGC170] { + background-color: #D75FD7 +} + +div.highlight .-Color[class*=-C171] { + color: #D75FFF +} + +div.highlight .-Color[class*=-BGC171] { + background-color: #D75FFF +} + +div.highlight .-Color[class*=-C172] { + color: #D78700 +} + +div.highlight .-Color[class*=-BGC172] { + background-color: #D78700 +} + +div.highlight .-Color[class*=-C173] { + color: #D7875F +} + +div.highlight .-Color[class*=-BGC173] { + background-color: #D7875F +} + +div.highlight .-Color[class*=-C174] { + color: #D78787 +} + +div.highlight .-Color[class*=-BGC174] { + background-color: #D78787 +} + +div.highlight .-Color[class*=-C175] { + color: #D787AF +} + +div.highlight .-Color[class*=-BGC175] { + background-color: #D787AF +} + +div.highlight .-Color[class*=-C176] { + color: #D787D7 +} + +div.highlight .-Color[class*=-BGC176] { + background-color: #D787D7 +} + +div.highlight .-Color[class*=-C177] { + color: #D787FF +} + +div.highlight .-Color[class*=-BGC177] { + background-color: #D787FF +} + +div.highlight .-Color[class*=-C178] { + color: #D7AF00 +} + +div.highlight .-Color[class*=-BGC178] { + background-color: #D7AF00 +} + +div.highlight .-Color[class*=-C179] { + color: #D7AF5F +} + +div.highlight .-Color[class*=-BGC179] { + background-color: #D7AF5F +} + +div.highlight .-Color[class*=-C180] { + color: #D7AF87 +} + +div.highlight .-Color[class*=-BGC180] { + background-color: #D7AF87 +} + +div.highlight .-Color[class*=-C181] { + color: #D7AFAF +} + +div.highlight .-Color[class*=-BGC181] { + background-color: #D7AFAF +} + +div.highlight .-Color[class*=-C182] { + color: #D7AFD7 +} + +div.highlight .-Color[class*=-BGC182] { + background-color: #D7AFD7 +} + +div.highlight .-Color[class*=-C183] { + color: #D7AFFF +} + +div.highlight .-Color[class*=-BGC183] { + background-color: #D7AFFF +} + +div.highlight .-Color[class*=-C184] { + color: #D7D700 +} + +div.highlight .-Color[class*=-BGC184] { + background-color: #D7D700 +} + +div.highlight .-Color[class*=-C185] { + color: #D7D75F +} + +div.highlight .-Color[class*=-BGC185] { + background-color: #D7D75F +} + +div.highlight .-Color[class*=-C186] { + color: #D7D787 +} + +div.highlight .-Color[class*=-BGC186] { + background-color: #D7D787 +} + +div.highlight .-Color[class*=-C187] { + color: #D7D7AF +} + +div.highlight .-Color[class*=-BGC187] { + background-color: #D7D7AF +} + +div.highlight .-Color[class*=-C188] { + color: #D7D7D7 +} + +div.highlight .-Color[class*=-BGC188] { + background-color: #D7D7D7 +} + +div.highlight .-Color[class*=-C189] { + color: #D7D7FF +} + +div.highlight .-Color[class*=-BGC189] { + background-color: #D7D7FF +} + +div.highlight .-Color[class*=-C190] { + color: #D7FF00 +} + +div.highlight .-Color[class*=-BGC190] { + background-color: #D7FF00 +} + +div.highlight .-Color[class*=-C191] { + color: #D7FF5F +} + +div.highlight .-Color[class*=-BGC191] { + background-color: #D7FF5F +} + +div.highlight .-Color[class*=-C192] { + color: #D7FF87 +} + +div.highlight .-Color[class*=-BGC192] { + background-color: #D7FF87 +} + +div.highlight .-Color[class*=-C193] { + color: #D7FFAF +} + +div.highlight .-Color[class*=-BGC193] { + background-color: #D7FFAF +} + +div.highlight .-Color[class*=-C194] { + color: #D7FFD7 +} + +div.highlight .-Color[class*=-BGC194] { + background-color: #D7FFD7 +} + +div.highlight .-Color[class*=-C195] { + color: #D7FFFF +} + +div.highlight .-Color[class*=-BGC195] { + background-color: #D7FFFF +} + +div.highlight .-Color[class*=-C196] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC196] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C197] { + color: #FF005F +} + +div.highlight .-Color[class*=-BGC197] { + background-color: #FF005F +} + +div.highlight .-Color[class*=-C198] { + color: #FF0087 +} + +div.highlight .-Color[class*=-BGC198] { + background-color: #FF0087 +} + +div.highlight .-Color[class*=-C199] { + color: #FF00AF +} + +div.highlight .-Color[class*=-BGC199] { + background-color: #FF00AF +} + +div.highlight .-Color[class*=-C200] { + color: #FF00D7 +} + +div.highlight .-Color[class*=-BGC200] { + background-color: #FF00D7 +} + +div.highlight .-Color[class*=-C201] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC201] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C202] { + color: #FF5F00 +} + +div.highlight .-Color[class*=-BGC202] { + background-color: #FF5F00 +} + +div.highlight .-Color[class*=-C203] { + color: #FF5F5F +} + +div.highlight .-Color[class*=-BGC203] { + background-color: #FF5F5F +} + +div.highlight .-Color[class*=-C204] { + color: #FF5F87 +} + +div.highlight .-Color[class*=-BGC204] { + background-color: #FF5F87 +} + +div.highlight .-Color[class*=-C205] { + color: #FF5FAF +} + +div.highlight .-Color[class*=-BGC205] { + background-color: #FF5FAF +} + +div.highlight .-Color[class*=-C206] { + color: #FF5FD7 +} + +div.highlight .-Color[class*=-BGC206] { + background-color: #FF5FD7 +} + +div.highlight .-Color[class*=-C207] { + color: #FF5FFF +} + +div.highlight .-Color[class*=-BGC207] { + background-color: #FF5FFF +} + +div.highlight .-Color[class*=-C208] { + color: #FF8700 +} + +div.highlight .-Color[class*=-BGC208] { + background-color: #FF8700 +} + +div.highlight .-Color[class*=-C209] { + color: #FF875F +} + +div.highlight .-Color[class*=-BGC209] { + background-color: #FF875F +} + +div.highlight .-Color[class*=-C210] { + color: #FF8787 +} + +div.highlight .-Color[class*=-BGC210] { + background-color: #FF8787 +} + +div.highlight .-Color[class*=-C211] { + color: #FF87AF +} + +div.highlight .-Color[class*=-BGC211] { + background-color: #FF87AF +} + +div.highlight .-Color[class*=-C212] { + color: #FF87D7 +} + +div.highlight .-Color[class*=-BGC212] { + background-color: #FF87D7 +} + +div.highlight .-Color[class*=-C213] { + color: #FF87FF +} + +div.highlight .-Color[class*=-BGC213] { + background-color: #FF87FF +} + +div.highlight .-Color[class*=-C214] { + color: #FFAF00 +} + +div.highlight .-Color[class*=-BGC214] { + background-color: #FFAF00 +} + +div.highlight .-Color[class*=-C215] { + color: #FFAF5F +} + +div.highlight .-Color[class*=-BGC215] { + background-color: #FFAF5F +} + +div.highlight .-Color[class*=-C216] { + color: #FFAF87 +} + +div.highlight .-Color[class*=-BGC216] { + background-color: #FFAF87 +} + +div.highlight .-Color[class*=-C217] { + color: #FFAFAF +} + +div.highlight .-Color[class*=-BGC217] { + background-color: #FFAFAF +} + +div.highlight .-Color[class*=-C218] { + color: #FFAFD7 +} + +div.highlight .-Color[class*=-BGC218] { + background-color: #FFAFD7 +} + +div.highlight .-Color[class*=-C219] { + color: #FFAFFF +} + +div.highlight .-Color[class*=-BGC219] { + background-color: #FFAFFF +} + +div.highlight .-Color[class*=-C220] { + color: #FFD700 +} + +div.highlight .-Color[class*=-BGC220] { + background-color: #FFD700 +} + +div.highlight .-Color[class*=-C221] { + color: #FFD75F +} + +div.highlight .-Color[class*=-BGC221] { + background-color: #FFD75F +} + +div.highlight .-Color[class*=-C222] { + color: #FFD787 +} + +div.highlight .-Color[class*=-BGC222] { + background-color: #FFD787 +} + +div.highlight .-Color[class*=-C223] { + color: #FFD7AF +} + +div.highlight .-Color[class*=-BGC223] { + background-color: #FFD7AF +} + +div.highlight .-Color[class*=-C224] { + color: #FFD7D7 +} + +div.highlight .-Color[class*=-BGC224] { + background-color: #FFD7D7 +} + +div.highlight .-Color[class*=-C225] { + color: #FFD7FF +} + +div.highlight .-Color[class*=-BGC225] { + background-color: #FFD7FF +} + +div.highlight .-Color[class*=-C226] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC226] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C227] { + color: #FFFF5F +} + +div.highlight .-Color[class*=-BGC227] { + background-color: #FFFF5F +} + +div.highlight .-Color[class*=-C228] { + color: #FFFF87 +} + +div.highlight .-Color[class*=-BGC228] { + background-color: #FFFF87 +} + +div.highlight .-Color[class*=-C229] { + color: #FFFFAF +} + +div.highlight .-Color[class*=-BGC229] { + background-color: #FFFFAF +} + +div.highlight .-Color[class*=-C230] { + color: #FFFFD7 +} + +div.highlight .-Color[class*=-BGC230] { + background-color: #FFFFD7 +} + +div.highlight .-Color[class*=-C231] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC231] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C232] { + color: #080808 +} + +div.highlight .-Color[class*=-BGC232] { + background-color: #080808 +} + +div.highlight .-Color[class*=-C233] { + color: #121212 +} + +div.highlight .-Color[class*=-BGC233] { + background-color: #121212 +} + +div.highlight .-Color[class*=-C234] { + color: #1C1C1C +} + +div.highlight .-Color[class*=-BGC234] { + background-color: #1C1C1C +} + +div.highlight .-Color[class*=-C235] { + color: #262626 +} + +div.highlight .-Color[class*=-BGC235] { + background-color: #262626 +} + +div.highlight .-Color[class*=-C236] { + color: #303030 +} + +div.highlight .-Color[class*=-BGC236] { + background-color: #303030 +} + +div.highlight .-Color[class*=-C237] { + color: #3A3A3A +} + +div.highlight .-Color[class*=-BGC237] { + background-color: #3A3A3A +} + +div.highlight .-Color[class*=-C238] { + color: #444444 +} + +div.highlight .-Color[class*=-BGC238] { + background-color: #444444 +} + +div.highlight .-Color[class*=-C239] { + color: #4E4E4E +} + +div.highlight .-Color[class*=-BGC239] { + background-color: #4E4E4E +} + +div.highlight .-Color[class*=-C240] { + color: #585858 +} + +div.highlight .-Color[class*=-BGC240] { + background-color: #585858 +} + +div.highlight .-Color[class*=-C241] { + color: #626262 +} + +div.highlight .-Color[class*=-BGC241] { + background-color: #626262 +} + +div.highlight .-Color[class*=-C242] { + color: #6C6C6C +} + +div.highlight .-Color[class*=-BGC242] { + background-color: #6C6C6C +} + +div.highlight .-Color[class*=-C243] { + color: #767676 +} + +div.highlight .-Color[class*=-BGC243] { + background-color: #767676 +} + +div.highlight .-Color[class*=-C244] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC244] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C245] { + color: #8A8A8A +} + +div.highlight .-Color[class*=-BGC245] { + background-color: #8A8A8A +} + +div.highlight .-Color[class*=-C246] { + color: #949494 +} + +div.highlight .-Color[class*=-BGC246] { + background-color: #949494 +} + +div.highlight .-Color[class*=-C247] { + color: #9E9E9E +} + +div.highlight .-Color[class*=-BGC247] { + background-color: #9E9E9E +} + +div.highlight .-Color[class*=-C248] { + color: #A8A8A8 +} + +div.highlight .-Color[class*=-BGC248] { + background-color: #A8A8A8 +} + +div.highlight .-Color[class*=-C249] { + color: #B2B2B2 +} + +div.highlight .-Color[class*=-BGC249] { + background-color: #B2B2B2 +} + +div.highlight .-Color[class*=-C250] { + color: #BCBCBC +} + +div.highlight .-Color[class*=-BGC250] { + background-color: #BCBCBC +} + +div.highlight .-Color[class*=-C251] { + color: #C6C6C6 +} + +div.highlight .-Color[class*=-BGC251] { + background-color: #C6C6C6 +} + +div.highlight .-Color[class*=-C252] { + color: #D0D0D0 +} + +div.highlight .-Color[class*=-BGC252] { + background-color: #D0D0D0 +} + +div.highlight .-Color[class*=-C253] { + color: #DADADA +} + +div.highlight .-Color[class*=-BGC253] { + background-color: #DADADA +} + +div.highlight .-Color[class*=-C254] { + color: #E4E4E4 +} + +div.highlight .-Color[class*=-BGC254] { + background-color: #E4E4E4 +} + +div.highlight .-Color[class*=-C255] { + color: #EEEEEE +} + +div.highlight .-Color[class*=-BGC255] { + background-color: #EEEEEE +} diff --git a/branch/main/_static/plus.png b/branch/main/_static/plus.png new file mode 100644 index 0000000..7107cec Binary files /dev/null and b/branch/main/_static/plus.png differ diff --git a/branch/main/_static/pygments.css b/branch/main/_static/pygments.css new file mode 100644 index 0000000..84ab303 --- /dev/null +++ b/branch/main/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/branch/main/_static/searchtools.js b/branch/main/_static/searchtools.js new file mode 100644 index 0000000..b08d58c --- /dev/null +++ b/branch/main/_static/searchtools.js @@ -0,0 +1,620 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/branch/main/_static/sphinx-design.min.css b/branch/main/_static/sphinx-design.min.css new file mode 100644 index 0000000..860c36d --- /dev/null +++ b/branch/main/_static/sphinx-design.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative;font-size:var(--sd-fontsize-dropdown)}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary.sd-summary-title{padding:.5em .6em .5em 1em;font-size:var(--sd-fontsize-dropdown-title);font-weight:var(--sd-fontweight-dropdown-title);user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;list-style:none;display:inline-flex;justify-content:space-between}details.sd-dropdown summary.sd-summary-title::-webkit-details-marker{display:none}details.sd-dropdown summary.sd-summary-title:focus{outline:none}details.sd-dropdown summary.sd-summary-title .sd-summary-icon{margin-right:.6em;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary.sd-summary-title .sd-summary-text{flex-grow:1;line-height:1.5;padding-right:.5rem}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker{pointer-events:none;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker svg{opacity:.6}details.sd-dropdown summary.sd-summary-title:hover .sd-summary-state-marker svg{opacity:1;transform:scale(1.1)}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown .sd-summary-chevron-right{transition:.25s}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-right{transform:rotate(90deg)}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-down{transform:rotate(180deg)}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-bg: rgba(0, 113, 188, 0.2);--sd-color-secondary-bg: rgba(108, 117, 125, 0.2);--sd-color-success-bg: rgba(40, 167, 69, 0.2);--sd-color-info-bg: rgba(23, 162, 184, 0.2);--sd-color-warning-bg: rgba(240, 179, 126, 0.2);--sd-color-danger-bg: rgba(220, 53, 69, 0.2);--sd-color-light-bg: rgba(248, 249, 250, 0.2);--sd-color-muted-bg: rgba(108, 117, 125, 0.2);--sd-color-dark-bg: rgba(33, 37, 41, 0.2);--sd-color-black-bg: rgba(0, 0, 0, 0.2);--sd-color-white-bg: rgba(255, 255, 255, 0.2);--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem;--sd-fontsize-dropdown: inherit;--sd-fontsize-dropdown-title: 1rem;--sd-fontweight-dropdown-title: 700} diff --git a/branch/main/_static/sphinx_highlight.js b/branch/main/_static/sphinx_highlight.js new file mode 100644 index 0000000..8a96c69 --- /dev/null +++ b/branch/main/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/branch/main/_static/sphinx_lesson.css b/branch/main/_static/sphinx_lesson.css new file mode 100644 index 0000000..14b20c6 --- /dev/null +++ b/branch/main/_static/sphinx_lesson.css @@ -0,0 +1,51 @@ +/* sphinx_lesson.css */ + +body.wy-body-for-nav img.with-border { + border: 2px solid; +} + +.rst-content .admonition-no-content { + padding-bottom: 0px; +} + +.rst-content .demo > .admonition-title::before { + content: "\01F440"; /* Eyes */ } +.rst-content .type-along > .admonition-title::before { + content: "\02328\0FE0F"; /* Keyboard */ } +.rst-content .exercise > .admonition-title::before { + content: "\0270D\0FE0F"; /* Hand */ } +.rst-content .solution > .admonition-title::before { + content: "\02714\0FE0E"; /* Check mark */ } +.rst-content .homework > .admonition-title::before { + content: "\01F4DD"; /* Memo */ } +.rst-content .discussion > .admonition-title::before { + content: "\01F4AC"; /* Speech balloon */ } +.rst-content .questions > .admonition-title::before { + content: "\02753\0FE0E"; /* Question mark */ } +.rst-content .prerequisites > .admonition-title::before { + content: "\02699"; /* Gear */ } +.rst-content .seealso > .admonition-title::before { + content: "\027A1\0FE0E"; /* Question mark */ } + + +/* instructor-note */ +.rst-content .instructor-note { + background: #e7e7e7; +} +.rst-content .instructor-note > .admonition-title { + background: #6a6a6a; +} +.rst-content .instructor-note > .admonition-title::before { + content: ""; +} + + +/* sphinx_toggle_button, make the font white */ +.rst-content .toggle.admonition button.toggle-button { + color: white; +} + +/* sphinx-togglebutton, remove underflow when toggled to hidden mode */ +.rst-content .admonition.toggle-hidden { + padding-bottom: 0px; +} diff --git a/branch/main/_static/sphinx_rtd_theme_ext_color_contrast.css b/branch/main/_static/sphinx_rtd_theme_ext_color_contrast.css new file mode 100644 index 0000000..e68feb8 --- /dev/null +++ b/branch/main/_static/sphinx_rtd_theme_ext_color_contrast.css @@ -0,0 +1,47 @@ +/* The following are for web accessibility of sphinx_rtd_theme: they + * solve some of the most frequent contrast issues. Remove when this + * solved: + * https://github.com/readthedocs/sphinx_rtd_theme/issues/971 + */ +/* background: #fcfcfc, note boxes #E7F2FA */ +a { color: #2573A7; } /* original #2980B9, #1F5C84; */ +body { color: #242424; } /* original #404040, #383838 */ +.wy-side-nav-search>a, .wy-side-nav-search .wy-dropdown>a { + color: #ffffff; +} /* original #fcfcfc */ +footer { color: #737373; } /* original gray=#808080*/ +footer span.commit code, footer span.commit .rst-content tt, .rst-content footer span.commit tt { + color: #737373; +} /* original gray=#808080*/ +.rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal { + color: #AB2314; +} +/* Sidebar background */ +.wy-side-nav-search { background-color: #277CB4;} + +/* Same, but for pygments */ +.highlight .ch { color: #3E7A89; } /* #! line */ +.highlight .c1 { color: #3E7A89; } /* also comments */ +.highlight .nv { color: #AD3ECC; } /* variable */ +.highlight .gp { color: #B45608; } /* prompt character, $*/ +.highlight .si { color: #3975B1; } /* ${} variable text */ +.highlight .nc { color: #0C78A7; } + +/* Sphinx admonitions */ +/* warning */ +.wy-alert.wy-alert-warning .wy-alert-title, .rst-content .wy-alert-warning.note .wy-alert-title, .rst-content .attention .wy-alert-title, .rst-content .caution .wy-alert-title, .rst-content .wy-alert-warning.danger .wy-alert-title, .rst-content .wy-alert-warning.error .wy-alert-title, .rst-content .wy-alert-warning.hint .wy-alert-title, .rst-content .wy-alert-warning.important .wy-alert-title, .rst-content .wy-alert-warning.tip .wy-alert-title, .rst-content .warning .wy-alert-title, .rst-content .wy-alert-warning.seealso .wy-alert-title, .rst-content .admonition-todo .wy-alert-title, .rst-content .wy-alert-warning.admonition .wy-alert-title, .wy-alert.wy-alert-warning .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-warning .admonition-title, .rst-content .wy-alert-warning.note .admonition-title, .rst-content .attention .admonition-title, .rst-content .caution .admonition-title, .rst-content .wy-alert-warning.danger .admonition-title, .rst-content .wy-alert-warning.error .admonition-title, .rst-content .wy-alert-warning.hint .admonition-title, .rst-content .wy-alert-warning.important .admonition-title, .rst-content .wy-alert-warning.tip .admonition-title, .rst-content .warning .admonition-title, .rst-content .wy-alert-warning.seealso .admonition-title, .rst-content .admonition-todo .admonition-title, .rst-content .wy-alert-warning.admonition .admonition-title { + background: #B15E16; } +/* important */ +.wy-alert.wy-alert-success .wy-alert-title, .rst-content .wy-alert-success.note .wy-alert-title, .rst-content .wy-alert-success.attention .wy-alert-title, .rst-content .wy-alert-success.caution .wy-alert-title, .rst-content .wy-alert-success.danger .wy-alert-title, .rst-content .wy-alert-success.error .wy-alert-title, .rst-content .hint .wy-alert-title, .rst-content .important .wy-alert-title, .rst-content .tip .wy-alert-title, .rst-content .wy-alert-success.warning .wy-alert-title, .rst-content .wy-alert-success.seealso .wy-alert-title, .rst-content .wy-alert-success.admonition-todo .wy-alert-title, .rst-content .wy-alert-success.admonition .wy-alert-title, .wy-alert.wy-alert-success .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-success .admonition-title, .rst-content .wy-alert-success.note .admonition-title, .rst-content .wy-alert-success.attention .admonition-title, .rst-content .wy-alert-success.caution .admonition-title, .rst-content .wy-alert-success.danger .admonition-title, .rst-content .wy-alert-success.error .admonition-title, .rst-content .hint .admonition-title, .rst-content .important .admonition-title, .rst-content .tip .admonition-title, .rst-content .wy-alert-success.warning .admonition-title, .rst-content .wy-alert-success.seealso .admonition-title, .rst-content .wy-alert-success.admonition-todo .admonition-title, .rst-content .wy-alert-success.admonition .admonition-title { + background: #12826C; } +/* seealso, note, etc */ +.wy-alert.wy-alert-info .wy-alert-title, .rst-content .note .wy-alert-title, .rst-content .wy-alert-info.attention .wy-alert-title, .rst-content .wy-alert-info.caution .wy-alert-title, .rst-content .wy-alert-info.danger .wy-alert-title, .rst-content .wy-alert-info.error .wy-alert-title, .rst-content .wy-alert-info.hint .wy-alert-title, .rst-content .wy-alert-info.important .wy-alert-title, .rst-content .wy-alert-info.tip .wy-alert-title, .rst-content .wy-alert-info.warning .wy-alert-title, .rst-content .seealso .wy-alert-title, .rst-content .wy-alert-info.admonition-todo .wy-alert-title, .rst-content .wy-alert-info.admonition .wy-alert-title, .wy-alert.wy-alert-info .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-info .admonition-title, .rst-content .note .admonition-title, .rst-content .wy-alert-info.attention .admonition-title, .rst-content .wy-alert-info.caution .admonition-title, .rst-content .wy-alert-info.danger .admonition-title, .rst-content .wy-alert-info.error .admonition-title, .rst-content .wy-alert-info.hint .admonition-title, .rst-content .wy-alert-info.important .admonition-title, .rst-content .wy-alert-info.tip .admonition-title, .rst-content .wy-alert-info.warning .admonition-title, .rst-content .seealso .admonition-title, .rst-content .wy-alert-info.admonition-todo .admonition-title, .rst-content .wy-alert-info.admonition .admonition-title { + background: #277CB4; } +/* error, danger */ +.rst-content .danger .admonition-title, .rst-content .danger .wy-alert-title, .rst-content .error .admonition-title, .rst-content .error .wy-alert-title, .rst-content .wy-alert-danger.admonition-todo .admonition-title, .rst-content .wy-alert-danger.admonition-todo .wy-alert-title, .rst-content .wy-alert-danger.admonition .admonition-title, .rst-content .wy-alert-danger.admonition .wy-alert-title, .rst-content .wy-alert-danger.attention .admonition-title, .rst-content .wy-alert-danger.attention .wy-alert-title, .rst-content .wy-alert-danger.caution .admonition-title, .rst-content .wy-alert-danger.caution .wy-alert-title, .rst-content .wy-alert-danger.hint .admonition-title, .rst-content .wy-alert-danger.hint .wy-alert-title, .rst-content .wy-alert-danger.important .admonition-title, .rst-content .wy-alert-danger.important .wy-alert-title, .rst-content .wy-alert-danger.note .admonition-title, .rst-content .wy-alert-danger.note .wy-alert-title, .rst-content .wy-alert-danger.seealso .admonition-title, .rst-content .wy-alert-danger.seealso .wy-alert-title, .rst-content .wy-alert-danger.tip .admonition-title, .rst-content .wy-alert-danger.tip .wy-alert-title, .rst-content .wy-alert-danger.warning .admonition-title, .rst-content .wy-alert-danger.warning .wy-alert-title, .rst-content .wy-alert.wy-alert-danger .admonition-title, .wy-alert.wy-alert-danger .rst-content .admonition-title, .wy-alert.wy-alert-danger .wy-alert-title { + background: #e31704; +} + +/* Generic admonition titles */ +.wy-alert-title, .rst-content .admonition-title { + background: #277CB4; } diff --git a/branch/main/_static/tabs.css b/branch/main/_static/tabs.css new file mode 100644 index 0000000..957ba60 --- /dev/null +++ b/branch/main/_static/tabs.css @@ -0,0 +1,89 @@ +.sphinx-tabs { + margin-bottom: 1rem; +} + +[role="tablist"] { + border-bottom: 1px solid #a0b3bf; +} + +.sphinx-tabs-tab { + position: relative; + font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; + color: #1D5C87; + line-height: 24px; + margin: 0; + font-size: 16px; + font-weight: 400; + background-color: rgba(255, 255, 255, 0); + border-radius: 5px 5px 0 0; + border: 0; + padding: 1rem 1.5rem; + margin-bottom: 0; +} + +.sphinx-tabs-tab[aria-selected="true"] { + font-weight: 700; + border: 1px solid #a0b3bf; + border-bottom: 1px solid white; + margin: -1px; + background-color: white; +} + +.sphinx-tabs-tab:focus { + z-index: 1; + outline-offset: 1px; +} + +.sphinx-tabs-panel { + position: relative; + padding: 1rem; + border: 1px solid #a0b3bf; + margin: 0px -1px -1px -1px; + border-radius: 0 0 5px 5px; + border-top: 0; + background: white; +} + +.sphinx-tabs-panel.code-tab { + padding: 0.4rem; +} + +.sphinx-tab img { + margin-bottom: 24 px; +} + +/* Dark theme preference styling */ + +@media (prefers-color-scheme: dark) { + body[data-theme="auto"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); + } + + body[data-theme="auto"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); + } + + body[data-theme="auto"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 1px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); + } +} + +/* Explicit dark theme styling */ + +body[data-theme="dark"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); +} + +body[data-theme="dark"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); +} + +body[data-theme="dark"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 2px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); +} diff --git a/branch/main/_static/tabs.js b/branch/main/_static/tabs.js new file mode 100644 index 0000000..48dc303 --- /dev/null +++ b/branch/main/_static/tabs.js @@ -0,0 +1,145 @@ +try { + var session = window.sessionStorage || {}; +} catch (e) { + var session = {}; +} + +window.addEventListener("DOMContentLoaded", () => { + const allTabs = document.querySelectorAll('.sphinx-tabs-tab'); + const tabLists = document.querySelectorAll('[role="tablist"]'); + + allTabs.forEach(tab => { + tab.addEventListener("click", changeTabs); + }); + + tabLists.forEach(tabList => { + tabList.addEventListener("keydown", keyTabs); + }); + + // Restore group tab selection from session + const lastSelected = session.getItem('sphinx-tabs-last-selected'); + if (lastSelected != null) selectNamedTabs(lastSelected); +}); + +/** + * Key focus left and right between sibling elements using arrows + * @param {Node} e the element in focus when key was pressed + */ +function keyTabs(e) { + const tab = e.target; + let nextTab = null; + if (e.keyCode === 39 || e.keyCode === 37) { + tab.setAttribute("tabindex", -1); + // Move right + if (e.keyCode === 39) { + nextTab = tab.nextElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.firstElementChild; + } + // Move left + } else if (e.keyCode === 37) { + nextTab = tab.previousElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.lastElementChild; + } + } + } + + if (nextTab !== null) { + nextTab.setAttribute("tabindex", 0); + nextTab.focus(); + } +} + +/** + * Select or deselect clicked tab. If a group tab + * is selected, also select tab in other tabLists. + * @param {Node} e the element that was clicked + */ +function changeTabs(e) { + // Use this instead of the element that was clicked, in case it's a child + const notSelected = this.getAttribute("aria-selected") === "false"; + const positionBefore = this.parentNode.getBoundingClientRect().top; + const notClosable = !this.parentNode.classList.contains("closeable"); + + deselectTabList(this); + + if (notSelected || notClosable) { + selectTab(this); + const name = this.getAttribute("name"); + selectNamedTabs(name, this.id); + + if (this.classList.contains("group-tab")) { + // Persist during session + session.setItem('sphinx-tabs-last-selected', name); + } + } + + const positionAfter = this.parentNode.getBoundingClientRect().top; + const positionDelta = positionAfter - positionBefore; + // Scroll to offset content resizing + window.scrollTo(0, window.scrollY + positionDelta); +} + +/** + * Select tab and show associated panel. + * @param {Node} tab tab to select + */ +function selectTab(tab) { + tab.setAttribute("aria-selected", true); + + // Show the associated panel + document + .getElementById(tab.getAttribute("aria-controls")) + .removeAttribute("hidden"); +} + +/** + * Hide the panels associated with all tabs within the + * tablist containing this tab. + * @param {Node} tab a tab within the tablist to deselect + */ +function deselectTabList(tab) { + const parent = tab.parentNode; + const grandparent = parent.parentNode; + + Array.from(parent.children) + .forEach(t => t.setAttribute("aria-selected", false)); + + Array.from(grandparent.children) + .slice(1) // Skip tablist + .forEach(panel => panel.setAttribute("hidden", true)); +} + +/** + * Select grouped tabs with the same name, but no the tab + * with the given id. + * @param {Node} name name of grouped tab to be selected + * @param {Node} clickedId id of clicked tab + */ +function selectNamedTabs(name, clickedId=null) { + const groupedTabs = document.querySelectorAll(`.sphinx-tabs-tab[name="${name}"]`); + const tabLists = Array.from(groupedTabs).map(tab => tab.parentNode); + + tabLists + .forEach(tabList => { + // Don't want to change the tabList containing the clicked tab + const clickedTab = tabList.querySelector(`[id="${clickedId}"]`); + if (clickedTab === null ) { + // Select first tab with matching name + const tab = tabList.querySelector(`.sphinx-tabs-tab[name="${name}"]`); + deselectTabList(tab); + selectTab(tab); + } + }) +} + +if (typeof exports === 'undefined') { + exports = {}; +} + +exports.keyTabs = keyTabs; +exports.changeTabs = changeTabs; +exports.selectTab = selectTab; +exports.deselectTabList = deselectTabList; +exports.selectNamedTabs = selectNamedTabs; diff --git a/branch/main/_static/term_role_formatting.css b/branch/main/_static/term_role_formatting.css new file mode 100644 index 0000000..0b66095 --- /dev/null +++ b/branch/main/_static/term_role_formatting.css @@ -0,0 +1,4 @@ +/* Make terms bold */ +a.reference span.std-term { + font-weight: bold; +} diff --git a/branch/main/_static/togglebutton.css b/branch/main/_static/togglebutton.css new file mode 100644 index 0000000..54a6787 --- /dev/null +++ b/branch/main/_static/togglebutton.css @@ -0,0 +1,160 @@ +/** + * Admonition-based toggles + */ + +/* Visibility of the target */ +.admonition.toggle .admonition-title ~ * { + transition: opacity .3s, height .3s; +} + +/* Toggle buttons inside admonitions so we see the title */ +.admonition.toggle { + position: relative; +} + +/* Titles should cut off earlier to avoid overlapping w/ button */ +.admonition.toggle .admonition-title { + padding-right: 25%; + cursor: pointer; +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:hover { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 1%); +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:active { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 3%); +} + +/* Remove extra whitespace below the admonition title when hidden */ +.admonition.toggle-hidden { + padding-bottom: 0; +} + +.admonition.toggle-hidden .admonition-title { + margin-bottom: 0; +} + +/* hides all the content of a page until de-toggled */ +.admonition.toggle-hidden .admonition-title ~ * { + height: 0; + margin: 0; + opacity: 0; + visibility: hidden; +} + +/* General button style and position*/ +button.toggle-button { + /** + * Background and shape. By default there's no background + * but users can style as they wish + */ + background: none; + border: none; + outline: none; + + /* Positioning just inside the admonition title */ + position: absolute; + right: 0.5em; + padding: 0px; + border: none; + outline: none; +} + +/* Display the toggle hint on wide screens */ +@media (min-width: 768px) { + button.toggle-button.toggle-button-hidden:before { + content: attr(data-toggle-hint); /* This will be filled in by JS */ + font-size: .8em; + align-self: center; + } +} + +/* Icon behavior */ +.tb-icon { + transition: transform .2s ease-out; + height: 1.5em; + width: 1.5em; + stroke: currentColor; /* So that we inherit the color of other text */ +} + +/* The icon should point right when closed, down when open. */ +/* Open */ +.admonition.toggle button .tb-icon { + transform: rotate(90deg); +} + +/* Closed */ +.admonition.toggle button.toggle-button-hidden .tb-icon { + transform: rotate(0deg); +} + +/* With details toggles, we don't rotate the icon so it points right */ +details.toggle-details .tb-icon { + height: 1.4em; + width: 1.4em; + margin-top: 0.1em; /* To center the button vertically */ +} + + +/** + * Details-based toggles. + * In this case, we wrap elements with `.toggle` in a details block. + */ + +/* Details blocks */ +details.toggle-details { + margin: 1em 0; +} + + +details.toggle-details summary { + display: flex; + align-items: center; + cursor: pointer; + list-style: none; + border-radius: .2em; + border-left: 3px solid #1976d2; + background-color: rgb(204 204 204 / 10%); + padding: 0.2em 0.7em 0.3em 0.5em; /* Less padding on left because the SVG has left margin */ + font-size: 0.9em; +} + +details.toggle-details summary:hover { + background-color: rgb(204 204 204 / 20%); +} + +details.toggle-details summary:active { + background: rgb(204 204 204 / 28%); +} + +.toggle-details__summary-text { + margin-left: 0.2em; +} + +details.toggle-details[open] summary { + margin-bottom: .5em; +} + +details.toggle-details[open] summary .tb-icon { + transform: rotate(90deg); +} + +details.toggle-details[open] summary ~ * { + animation: toggle-fade-in .3s ease-out; +} + +@keyframes toggle-fade-in { + from {opacity: 0%;} + to {opacity: 100%;} +} + +/* Print rules - we hide all toggle button elements at print */ +@media print { + /* Always hide the summary so the button doesn't show up */ + details.toggle-details summary { + display: none; + } +} \ No newline at end of file diff --git a/branch/main/_static/togglebutton.js b/branch/main/_static/togglebutton.js new file mode 100644 index 0000000..215a7ee --- /dev/null +++ b/branch/main/_static/togglebutton.js @@ -0,0 +1,187 @@ +/** + * Add Toggle Buttons to elements + */ + +let toggleChevron = ` + + + +`; + +var initToggleItems = () => { + var itemsToToggle = document.querySelectorAll(togglebuttonSelector); + console.log(`[togglebutton]: Adding toggle buttons to ${itemsToToggle.length} items`) + // Add the button to each admonition and hook up a callback to toggle visibility + itemsToToggle.forEach((item, index) => { + if (item.classList.contains("admonition")) { + // If it's an admonition block, then we'll add a button inside + // Generate unique IDs for this item + var toggleID = `toggle-${index}`; + var buttonID = `button-${toggleID}`; + + item.setAttribute('id', toggleID); + if (!item.classList.contains("toggle")){ + item.classList.add("toggle"); + } + // This is the button that will be added to each item to trigger the toggle + var collapseButton = ` + `; + + title = item.querySelector(".admonition-title") + title.insertAdjacentHTML("beforeend", collapseButton); + thisButton = document.getElementById(buttonID); + + // Add click handlers for the button + admonition title (if admonition) + admonitionTitle = document.querySelector(`#${toggleID} > .admonition-title`) + if (admonitionTitle) { + // If an admonition, then make the whole title block clickable + admonitionTitle.addEventListener('click', toggleClickHandler); + admonitionTitle.dataset.target = toggleID + admonitionTitle.dataset.button = buttonID + } else { + // If not an admonition then we'll listen for the button click + thisButton.addEventListener('click', toggleClickHandler); + } + + // Now hide the item for this toggle button unless explicitly noted to show + if (!item.classList.contains("toggle-shown")) { + toggleHidden(thisButton); + } + } else { + // If not an admonition, wrap the block in a
block + // Define the structure of the details block and insert it as a sibling + var detailsBlock = ` +
+ + ${toggleChevron} + ${toggleHintShow} + +
`; + item.insertAdjacentHTML("beforebegin", detailsBlock); + + // Now move the toggle-able content inside of the details block + details = item.previousElementSibling + details.appendChild(item) + item.classList.add("toggle-details__container") + + // Set up a click trigger to change the text as needed + details.addEventListener('click', (click) => { + let parent = click.target.parentElement; + if (parent.tagName.toLowerCase() == "details") { + summary = parent.querySelector("summary"); + details = parent; + } else { + summary = parent; + details = parent.parentElement; + } + // Update the inner text for the proper hint + if (details.open) { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintShow; + } else { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintHide; + } + + }); + + // If we have a toggle-shown class, open details block should be open + if (item.classList.contains("toggle-shown")) { + details.click(); + } + } + }) +}; + +// This should simply add / remove the collapsed class and change the button text +var toggleHidden = (button) => { + target = button.dataset['target'] + var itemToToggle = document.getElementById(target); + if (itemToToggle.classList.contains("toggle-hidden")) { + itemToToggle.classList.remove("toggle-hidden"); + button.classList.remove("toggle-button-hidden"); + } else { + itemToToggle.classList.add("toggle-hidden"); + button.classList.add("toggle-button-hidden"); + } +} + +var toggleClickHandler = (click) => { + // Be cause the admonition title is clickable and extends to the whole admonition + // We only look for a click event on this title to trigger the toggle. + + if (click.target.classList.contains("admonition-title")) { + button = click.target.querySelector(".toggle-button"); + } else if (click.target.classList.contains("tb-icon")) { + // We've clicked the icon and need to search up one parent for the button + button = click.target.parentElement; + } else if (click.target.tagName == "polyline") { + // We've clicked the SVG elements inside the button, need to up 2 layers + button = click.target.parentElement.parentElement; + } else if (click.target.classList.contains("toggle-button")) { + // We've clicked the button itself and so don't need to do anything + button = click.target; + } else { + console.log(`[togglebutton]: Couldn't find button for ${click.target}`) + } + target = document.getElementById(button.dataset['button']); + toggleHidden(target); +} + +// If we want to blanket-add toggle classes to certain cells +var addToggleToSelector = () => { + const selector = ""; + if (selector.length > 0) { + document.querySelectorAll(selector).forEach((item) => { + item.classList.add("toggle"); + }) + } +} + +// Helper function to run when the DOM is finished +const sphinxToggleRunWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} +sphinxToggleRunWhenDOMLoaded(addToggleToSelector) +sphinxToggleRunWhenDOMLoaded(initToggleItems) + +/** Toggle details blocks to be open when printing */ +if (toggleOpenOnPrint == "true") { + window.addEventListener("beforeprint", () => { + // Open the details + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.dataset["togglestatus"] = el.open; + el.open = true; + }); + + // Open the admonitions + document.querySelectorAll(".admonition.toggle.toggle-hidden").forEach((el) => { + console.log(el); + el.querySelector("button.toggle-button").click(); + el.dataset["toggle_after_print"] = "true"; + }); + }); + window.addEventListener("afterprint", () => { + // Re-close the details that were closed + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.open = el.dataset["togglestatus"] == "true"; + delete el.dataset["togglestatus"]; + }); + + // Re-close the admonition toggle buttons + document.querySelectorAll(".admonition.toggle").forEach((el) => { + if (el.dataset["toggle_after_print"] == "true") { + el.querySelector("button.toggle-button").click(); + delete el.dataset["toggle_after_print"]; + } + }); + }); +} diff --git a/branch/main/co-teaching/index.html b/branch/main/co-teaching/index.html new file mode 100644 index 0000000..fee9eb9 --- /dev/null +++ b/branch/main/co-teaching/index.html @@ -0,0 +1,301 @@ + + + + + + + Co-teaching — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Co-teaching

+
+

Objectives

+
    +
  • Get to know the principle of co-teaching: How we do it and how you can too.

  • +
  • Learn the team teaching concept and how to tailor it to your situation.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 15 min

  • +
  • Exercises: 10 min

  • +
  • Discussion: 5 min

  • +
+
+
+

Overview

+

CodeRefinery lessons benefit from the application of the concepts of co-teaching.

+
+

Co-teaching

+

Co-teaching can be defined as “the division of labor between educators to plan, organize, instruct and make assessments on the same group of students, generally in a common classroom, and often with a strong focus on those teaching as a team complementing one another’s particular skills or other strengths”.

+
+

Co-teaching can be used in various forms, some of which are present in our workshops:

+
    +
  • Teaching + support, e.g. one of the teachers leading instruction while the other watches over and maintains the collaborative document (HackMD/HedgeDoc/…).

  • +
  • Another similar example is remote learning groups that watch the streamed CodeRefinery lessons guided by the local instructors.

  • +
  • Having open-source material and planning jointly allows multiple instances of a lesson to be held by multiple teachers:

    +
      +
    • parallel teaching, to different audiences at the same time,

    • +
    • alternative teaching, to different audiences at the same or different time, with potential content adjustments (for example, different installation procedures).

    • +
    +
  • +
  • Team teaching, where the lesson is presented by multiple (in most cases, two) teachers who actively engage in conversation with each other. The team-teaching concept is explained in more detail in the CodeRefinery manual.

  • +
+

In reality, different forms are very often mixed or fused together, even within a single lesson.

+

Co-teaching is not an online-only concept. However, it is very practical in online teaching due to larger number of instructors and learners potentially available to join a teaching session.

+
+
+

Co-teaching and team teaching benefits

+
    +
  • It saves preparation time. Co-teachers can rely on each other’s strengths while creating/ revising the material as well as in unexpected situations during the lesson.

  • +
  • It helps with onboarding new instructors. One of the co-teachers can be learning at the same time, either the subtleties of the material taught (in this case literally being the “voice of the audience”) or the teaching process itself.

  • +
  • Team teaching looks more interactive and engaging to the audience in many cases, without forcing the learners to speak up if they can’t or don’t want to do so.

  • +
  • It also ensures responsive feedback and less workload by having more active minds.

  • +
+
+

Are there any downsides?

+

Not every learner and not every instructor might like the team-teaching approach.

+
    +
  • It might seem less structured, unprepared, and chaotic, even with preparation.

    +
      +
    • It might create situations where instructors accidentally talk over each other or “interrupt” and change the flow of the lesson.

    • +
    • For some instructors it can be stressful to not know in advance what questions they get asked from the co-instructor.

    • +
    • Sometimes when an unexpected question is asked that throws the other instructor off, it can add to the feeling of chaos and unpreparedness.

    • +
    +
  • +
  • It can be interactive and engaging but it can also end up awkward if the co-teachers don’t have a good synergy.

    +
      +
    • Can sound awkward: Main instructor talking all the time and at the end asking co-instructor whether everything is clear and co-instructor only saying “yes”.

    • +
    • Possibly more engaging: Co-instructor asking questions which help with the flow and a common understanding of the material.

    • +
    +
  • +
+
+
+
+

Team teaching specifics

+
    +
  • For successful team teaching, additional coordination is needed, first of all to agree on the teaching model (see below) and the person in control (the director) for the lesson or its parts.

  • +
  • It’s useful to keep track of the lecture plan. The discussion is a good way to make lesson more interactive and adjust to the audience, but deviating too much will become disorienting (for example, if someone dropped their attention for a minute and now is trying to catch-up by reading lecture notes).

  • +
  • Experienced solo teacher might have a habit to keep talking (lecturing), while the co-teacher might not want to “interrupt”. Therefore, it is important for the leading presenter to anticipate and allow for remarks/ questions, and this can be different from one’s previous teaching style at first.

  • +
+
+
+

Team teaching models

+

We propose two basic models, but of course there is a constant continuum.

+
+

Guide and demo-giver

+

One person serves the role of guide, explaining the big picture and context of the examples.

+

Another, the demo-giver,

+
    +
  • shows the typing and does the examples,

  • +
  • might take the role of a learner who is asking about what is going on, to actually explain the details, or to comment occasionally.

  • +
+

Hands-on demos and exercises work especially well like this.

+
+
+

Presenter and interviewer

+

In this case, one is the presenter who is mostly explaining (including demos or examples), and trying to move the forward through the material.

+

Another, the interviewer,

+
    +
  • serves as a learner or spotter,

  • +
  • fills in gaps by asking relevant questions,

  • +
  • tries to comment to the presenter when things are going off track.

  • +
+

This can be seen as closer to classical teaching, but with a dedicated and prepared “voice of the audience”.

+
+
+

Exercise

+
+

Discuss the models of team teaching (10 min)

+

While in breakout rooms, discuss one of the basic team-teaching models presented here:

+
    +
  • Have you already tried this or similar model in your teaching?

  • +
  • Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best?

  • +
+

Write your comments in the collaborative document.

+
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Co-teaching focuses on complementing individual skills and strengths in teaching process.

  • +
  • Co-teaching may save time, reduce teachers’ workload and make lessons more interactive/ engaging.

  • +
  • Team teaching requires some adjustments in lesson preparation and delivery.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/coderefinery-intro/index.html b/branch/main/coderefinery-intro/index.html new file mode 100644 index 0000000..1e52a61 --- /dev/null +++ b/branch/main/coderefinery-intro/index.html @@ -0,0 +1,280 @@ + + + + + + + About the CodeRefinery project and CodeRefinery workshops in general — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • + Edit on GitHub +
  • +
+
+
+
+
+ +
+

About the CodeRefinery project and CodeRefinery workshops in general

+
+

Objectives

+
    +
  • Discuss what CodeRefinery is and how we got here

  • +
  • Understand about the challenges to define our target audience

  • +
+
+

CodeRefinery is a +Nordic e-Infrastructure Collaboration (NeIC) +project that has started in October 2016 and is currently +funded until February 2025. We are working on the continuation plans.

+

The funding from 2022-2025 is designed to keep this project active +beyond 2025 by forming a support network and building a community of +instructors and contributors.

+
+

History

+

The CodeRefinery project idea grew out of two SeSE courses given at KTH Stockholm in 2014 and 2016. +The project proposal itself was submitted to NeIC in 2015, accepted in 2015, and started in 2016.

+

We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form.

+
+
+

Goals

+
    +
  • Develop and maintain training material on good enough software development practices for researchers that write code/scripts/notebooks.

  • +
  • Our material addresses all academic disciplines and tries to be as programming language-independent as possible.

  • +
  • Provide a code repository hosting service that is open and free +for all researchers based in universities and research institutes from Nordic countries.

  • +
  • Provide training opportunities in the Nordics using (Carpentries and) CodeRefinery training materials.

  • +
  • Evolve the project towards a community-driven project with a network of instructors and contributors.

  • +
+
+
+

Community

+
+../_images/community.png +
+

Image showing the key areas of the CodeRefinery community: Workshops, chat inlcuding help channel, online meetings and co-working, +other collaborative training, eg on High Performance Computing topics.

+
+
+

CodeRefinery is not just workshops, we are community and want you to be part of it!

+

There are many different levels of involvement, from the occasional commenter in chat, +CodeRefinery ambassador (people who like the project and workshops and help us spreading the word) or lesson issue creators and lesson contributors to +local host, co-instructor or co-organizer.

+

Best first step in any case is to join the CodeRefinery Zulip chat +or let us know about your interest at support@coderefinery.org.

+
+
+

Target audience

+

One common question we get is how do we relate to the Carpentries. +This section describes how we see it:

+
+

Carpentries audience

+

The Carpentries aims to teach computational competence to learners through an applied approach, +avoiding the theoretical and general in favor of the practical and specific.

+

Mostly, learners do not need to have any prior experience in programming. +One major goal of a Carpentries workshop is to raise awareness on the tools researchers can learn/use to speed up their research.

+

By showing learners how to solve specific problems with specific tools and providing hands-on practice, +learners develops confidence for future learning.

+
+

Novices

+

We often qualify Carpentries learners as novices: they do not know what they need to learn yet. +A typical example is the usage of version control: the Carpentries lesson +Version Control with Git +aims to give a +very high level conceptual overview of Git but it does not explain how it can be used in research projects.

+
+
+
+

CodeRefinery audience

+

In that sense, CodeRefinery workshops differ from Carpentries workshops as we assume +our audience already writes code and scripts and we aim at teaching them best software practices.

+

Our learners usually do not have a good overview of best software practices but are aware of the need to learn them. +Very often, they know of the tools (Git, Jupyter, etc.) we are teaching +but have difficulties to make the best use of them in their software development workflow.

+

Whenever we can, we direct learners that do not have sufficient coding experience to Carpentries workshops.

+
+

Competent practitioners

+

We often qualify CodeRefinery learners as competent practitioners because they already have an understanding of their needs.

+
+ +
+
+

Keypoints: CodeRefinery

+
    +
  • Teaches intermediate-level software development tool lessons

  • +
  • It is difficult to define “best practices”, we try to teach “good enough” practices

  • +
  • Training network for other lessons

  • +
  • Publicly-funded discrete projects (3 projects actually) transitioning towards an open community project

  • +
  • We have online material, teaching, and exercise sessions

  • +
  • Our main target audience are competent practitioners, but also novices and experts can get something out of the workshops

  • +
  • We want more people to work with us, and to work with more people

  • +
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/collaborative-notes/index.html b/branch/main/collaborative-notes/index.html new file mode 100644 index 0000000..6062c6d --- /dev/null +++ b/branch/main/collaborative-notes/index.html @@ -0,0 +1,530 @@ + + + + + + + Collaborative notes — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Collaborative notes

+
+

Objectives

+
    +
  • Be able to provide a highly interactive online workshop environment with collaborative documents

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Exercise: 15 min

  • +
  • Questions & Answers: 5 min

  • +
+
+
+

Introduction

+

The Collaborative document is how you interact with the participants. +The participants can ask questions and give feedback through the collaborative +document. During a CodeRefinery session there can be a large a volume of questions. +A dedicated person, a Collaborative document-manager, is needed to answer and edit the collaborative document. +Let us see how the collaborative document is used, then discuss the role of +the editor or collaborative document-manager.

+
+
+

Collaborative document mechanics and controls

+

Technologies that can be used as a collaborative document are Hackmd, HedgeDoc, +or Google Docs

+

Hackmd or HedgeDoc are real-time text editor online. We use it to:

+
    +
  • As a threaded chat, to answer questions and provide other information without +interrupting the main flow of the room.

  • +
  • provide everyone with a more equal opportunity to ask questions.

  • +
  • create notes which will be archived, for your later reference.

  • +
+

You do not need to login/create an account to be able to edit the document.

+
+

Basic controls

+
+../_images/hackmd--controls.png +
+

This may look slightly different on mobile devices and small windows.

+
+
+
    +
  • At the top (left or right), you can switch between view, +edit, and split view and edit modes.

  • +
  • You write in markdown here. Don’t +worry about the syntax, just see what others do and try to be like +that! Someone will come and fix any problems there may be.

  • +
  • Please go back to view mode if you think you won’t edit for a +while - it will still live update.

  • +
+
+
+

Asking questions

+

Always ask questions and add new sections at the very bottom. +You can also answer and comment on older questions, too.

+
+../_images/hackmd--questions2.png +
+

Questions and answers in bullet points

+
+
+

Since we plan to publish the questions and answers later as part +of the workshop page, we recommend to not use any names. You can indicate +your own name to make it easier to discuss more during the workshop but +then always use this form: [name=Myname]. This makes it easier for +us to automatically remove all names before publishing the notes.

+

Other hints:

+
    +
  • Use +1 to agree with a statement or question (we are more likely +to comment on it).

  • +
  • Please leave some blank lines at the bottom

  • +
  • NOTE: Please don’t “select all”, it highlights for everyone and adds a +risk of losing data (there are periodic backups, but not instant).

  • +
  • It can be quite demanding to follow the collaborative document closely. Keep an eye +on it, but consider how distracted you may get from the course. For +things beyond the scope of the course, we may come back and answer +later.

  • +
+
+
+

Don’t get overwhelmed

+

There can be a flood of information on the collaborative document. Scan for what is +important, then if you would like come back later. But it is +important to keep checking it.

+
+
+

Privacy

+
    +
  • Assume the collaborative document is public and published: you never +need to put your name there.

  • +
  • The collaborative document will be published on the website afterwards. We will +remove all non-instructors names, but it’s easier if you don’t add +it there in the first place.

  • +
  • Please keep the link private during the workshop, since since +security is “editable by those who have the link”.

  • +
  • You can use [name=YOURNAME], to name yourself. We will remove +all names (but not the comments) before archiving the notes (use +this format to make it easy for us).

  • +
+
+
+
+

Exercise

+
+

Discuss how to collaborate and handle questions (15 min)

+

Write down your conclusions in the shared document. Items to discuss are:

+
    +
  • What is your experience with questions and discussions while teaching?

  • +
  • How do you deal with them?

  • +
  • What kind of technologies do you prefer: chat, shared document, or voices +and discussion raised during instruction? And why?

  • +
+
+
+
+

Collaborative Document Manager

+

We have one person who is a “Collaborative Document helper”. This isn’t the only +person that should edit and answer, but one person shouldn’t have too +much else on their mind so can focus on it. They also make sure that +the collaborative document is updated with exercise, break, and other meta-information to +keep people on track.

+

Below, (*) = important.

+
+

Before the workshop

+
    +
  • Create a new collaborative document for the workshop

  • +
  • make sure that editing is enabled for anyone without login

  • +
  • Add workshop information, links to the workshop page and material +and an example question and answer to the top of the collaborative document(see below)

  • +
+
+
+

Most things to edit (everyone)

+

Make it easy to post after the course and consistent to follow:

+
    +
  • Tag all names with [name=XXX] (so they can be removed later), +remove other personal data or make it obvious.

  • +
  • Add in information on exercises (new section for them, link, end +time, what to accomplish)

  • +
  • Make a logical section structure (# for title, ## for sections, +### for episodes, etc. - or what makes sense)

  • +
+
+
+

General Collaborative Document practices

+
+../_images/hackmd--full-demo.png +
+

A live demo of a Collaborative Document during a Q&A time. The two instructors are +discussing some of the import answers. Multiple learners have asked +questions, multiple answers, and some remaining to be answered

+
+
+

Keep it formatted well:

+
    +
  • (*) Tag names you see with [name=XXX] so that we can remove it +later.

  • +
  • Heading level # is only the page title

  • +
  • Add a new ## heading when a new lesson or similar thing is +started (introduction, icebreaker, break between lessons, etc)

  • +
  • Add a new ### heading when a new episode, exercise, break +(within exercise session)

  • +
  • Ensure people are asking questions at the bottom, direct them there +if they aren’t.

  • +
  • (*) Ensure each question is a bullet point. Each answer or follow-up +should be a bullet point below.

    +
      +
    • Should you use more deeply nested bullet points, or have only one +level below the initial question? It depends on the context, but +if a conversation goes on too long, try not to let it go too +deep.

    • +
    +
  • +
+

Update with meta-talk, so that learners can follow along easily:

+
    +
  • Add Icebreaker and introductory material of the day. Try to talk to +people as they joined to get them to open the collaborative document and answer.

  • +
  • Anything important for following along should not be only said via +voice. It needs to be in the collaborative document, too.

  • +
  • New lessons or episodes, with links to them.

  • +
  • For exercises, link to exercise and add the duration, end time, +goals. If these are unclear, bring it up to the instructor by voice.

  • +
  • Add a status display about breaks.

  • +
+

Screenshare it when necessary:

+
    +
  • During breaks and other times, share the collaborative document(including the +notification about break, and when it ends).

  • +
  • It is nice if the arrangement allows some of the latest questions to +be seen, so people are reminded to ask there.

  • +
  • Someone else may do this, but should make sure it happens.

  • +
+

Answer questions

+
    +
  • If there is an question that should be answered by the instructor by +voice, bring it up (by voice) to the instructor immediately.

  • +
  • How soon do you answer questions? Two points of view:

    +
      +
    • Answer questions right away: can be really intense to follow.

    • +
    • Wait some so that we don’t overload learners: reduces the info +flow. But then do people need to check back more often.

    • +
    • You need to find your own balance. Maybe a quick answer right +away, and more detailed later. Or delay answers during the most +important parts of the lecture.

    • +
    +
  • +
  • Avoid wall-of-text answers. If reading an answer takes too long, it +puts the person (and other people who even try to read it) behind +even more by taking up valuable mental energy. If an answer needs a +wall of text, consider these alternatives:

    +
      +
    • Progressive bullet points getting more detailed (first ones +useful alone for basic cases)

    • +
    • Don’t be worried to say “don’t worry about this now, let’s talk +later.”

    • +
    • Figure out the root problem instead of answering every possible +interpretation

    • +
    • Declare it advanced and that you will come back later.

    • +
    +
  • +
+

Ensure it can be posted quickly:

+
    +
  • The collaborative document gets posted to the workshop webpage. For this, it needs some +minimal amount of formatting (it doesn’t need to be perfect, just +not horrible).

  • +
  • All names and private information needs to be stripped. This is why +you should rigorously tag all names with [name=XXX] so they can be +removed (see above).

    +
      +
    • Learner names can be completely removed. CR staff names can be +[name=CR] or something similar.

    • +
    • There may be other private URLs at the top or bottom.

    • +
    +
  • +
  • If possible, send the PR adding the collaborative document to the workshop webpage +(though others can do this, too).

  • +
+
+
+

Collaborative document format example

+
# Workshop, day 1
+
+
+## Lesson name
+https://coderefinery.github.io/lesson/
+
+### Episode name
+https://coderefinery.github.io/01-episode/
+
+- This is a question
+  - Anwser
+  - More detailed answer
+- question
+  - answer
+
+### Exercises:
+https://link-to-exercise/.../.../#section
+20 minutes, until xx:45
+Try to accomplish all of points 1-3.  Parts 4-5 are optional.
+
+Breakout room status:
+- room 2, need help with Linux permissions
+- room 5, done
+
+### Break
+:::danger
+We are on a 10 minute break until xx:10
+:::
+
+
+## Lesson 2
+https://coderefinery.github.io/lesson-2/
+
+
+
+
+
+

Posting the collaborative document to the website

+

The collaborative document should be posted sooner rather than later, and hopefully the +steps above will make it easy to do so quickly. You could wait a few +hours, to allow any remaining questions to be asked an answered.

+
    +
  • Download as markdown

  • +
  • Remove any private links at the top

  • +
  • Adjust headings so that they are reasonable

  • +
  • Look for private info and remove it

    +
      +
    • Search document for [name=???] (change to [name=staff] or +[name=learner])

    • +
    • Any names not tagged with [name=]

    • +
    • usernames in URLs

    • +
    • private links

    • +
    +
  • +
+
+
+

Feedback template

+
## Feedback, day N
+
+:::info
+### News for day N+1
+- .
+- .
+:::
+
+### Today was (multi-answer):
+- too fast: 
+- just right: 
+- too slow: 
+- too easy: 
+- right level: 
+- too advanced: 
+- I would recommend this course to others: 
+- Exercises were good: 
+- I would recommend today to others: 
+- I wouldn't recommend today: 
+
+### One good thing about today:
+- ...
+- ...
+
+### One thing to be improved for next time:
+- ...
+- ...
+
+### Any other comments:
+- ...
+- ...
+
+
+
+

Keypoints

+
    +
  • Having a collaborative document improves communication and interaction.

  • +
  • Answering questions requires a dedicated person - A Collaborative Document Manager.

  • +
  • The collaborative document should be posted on the web site as soon as possible.

  • +
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/computational-thinking/index.html b/branch/main/computational-thinking/index.html new file mode 100644 index 0000000..26bd609 --- /dev/null +++ b/branch/main/computational-thinking/index.html @@ -0,0 +1,189 @@ + + + + + + + Computational thinking — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Computational thinking

+
+

Objectives

+
    +
  • Explain what is computational thinking

  • +
  • Get to know how the theory of computational thinking can be used in teaching

  • +
  • Short exercise

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 10 min

  • +
+
+

Materials available as slides.

+
+

Keypoints

+
    +
  • Computational Thinking consists of 4 main parts: decomposition, pattern recognition, abstraction and algorithmic design.

  • +
  • How can this be a useful framework for solving problems?

  • +
  • How can this be used practically?

  • +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/cool-gems/index.html b/branch/main/cool-gems/index.html new file mode 100644 index 0000000..d173047 --- /dev/null +++ b/branch/main/cool-gems/index.html @@ -0,0 +1,181 @@ + + + + + + + Sharing teaching gems — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Sharing teaching gems

+
+

Objectives

+
    +
  • Our goal is to share our teaching tricks and tools and demonstrate them in +very short presentations/discussions.

  • +
+
+
+

Instructor note

+
    +
  • Demonstrations: 35 min

  • +
+
+

Here we encourage participants to take the screen share for 3 minutes and +demonstrate either some tool or trick they found useful for their teaching or +something from a course you liked.

+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/feedback-and-impact/index.html b/branch/main/feedback-and-impact/index.html new file mode 100644 index 0000000..37a1f37 --- /dev/null +++ b/branch/main/feedback-and-impact/index.html @@ -0,0 +1,421 @@ + + + + + + + How we collect feedback and measure impact — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

How we collect feedback and measure impact

+
+

Objectives

+
    +
  • Discuss how one can collect feedback from learners (“what can we improve?”).

  • +
  • Discuss how we convert feedback into actionable items.

  • +
  • Discuss how we measure the impact of teaching (“did we achieve our goals?”).

  • +
  • Discuss the “why”.

  • +
  • Get to know the reasons and sources of inspiration behind major lesson and workshop updates.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 20 min

  • +
  • Exercises: 10 min

  • +
+
+
+

Asking questions before the workshop

+ +
+
+

Collecting feedback as we teach

+
    +
  • Each day we ask for feedback in the collaborative notes.

    +
      +
    • One good thing about today.

    • +
    • One thing to improve for next time.

    • +
    • Any other comments?

    • +
    +
  • +
  • During the workshop we sometimes check in and ask about the pace, example:

    +
    How is the speed so far? (add an "o")
    +- Too fast:   oooooo
    +- Too slow:   ooo
    +- Just right: ooooooooooooooooooo
    +
    +
    +
  • +
  • We publish all questions, answers, and feedback. Example: https://coderefinery.github.io/2024-03-12-workshop/questions/

  • +
  • How we follow up:

    +
      +
    • Some problems we can fix already before the next workshop day.

    • +
    • We convert feedback/problems into GitHub issues and track these close to the lesson material.

    • +
    +
  • +
+
+
+

Trying to measure impact with longer-term surveys

+ +
+
+

Lessons learned

+
    +
  • Think about how to measure impact/success from the beginning.

  • +
  • Make the feedback and survey results public.

  • +
  • Make the results persistent and citable.

  • +
  • Have a mechanism to follow-up on feedback.

  • +
  • Anonymization is more than just removing or dissociating names.

  • +
  • Take time designing your survey and collect feedback on the survey itself.

  • +
+
+
+

Take time designing your survey

+

We are not experts in survey design but we reached out to RISE Research +Institutes of Sweden to get feedback on our survey questions. They provided us +with a lot of valuable feedback and suggestions for improvements. +Below are few examples.

+
+

Example 1

+

First version of our survey question about impact:

+
    +
  • “Do our workshops help to save time in future?” Please quantify in hours saved: …

  • +
+

Feedback:

+
    +
  • Difficult to answer.

  • +
  • Since when? Until all eternity?

  • +
+
+Screenshot of earlier version of the survey question about impact. +
+

Earlier version of the survey question about impact.

+
+
+

Feedback:

+
    +
  • The question “Do our workshops help to save time in future?” is unspecified, +unnecessary, and leading.

  • +
  • “No time saving” does not match the wording “save time” in the question.

  • +
+
+Screenshot of later version of the survey question about impact. +
+

Later version of the survey question about impact.

+
+
+
    +
  • The wording “have you saved” now matches “No time saved”.

  • +
+
+
+

Example 2

+
    +
  • Earlier version:

    +
    Would you judge your code to be better reusable/reproducible/modular/documented
    +as a result of attending the workshop?
    +
    +- More reusable
    +- More reproducible
    +- More modular
    +- Better documented
    +- None of the above
    +
    +
    +
  • +
  • Feedback: The question is not neutrally formulated and risks leading to +over-reporting of yes answers. Consider balancing so that the questions are +formulated more neutrally.

  • +
  • Reformulated to:

    +
    After attending the workshop, would you judge your code to be
    +more reusable or not more reusable?
    +
    +- My code is more reusable
    +- My code is not more reusable
    +- Not sure
    +
    +
    +
  • +
+
+
+

Example 3

+
    +
  • Early version:

    +
    What else has changed in how you write code since attending the workshop?
    +
    +[free-form text field]
    +
    +
    +
  • +
  • Feedback: Leading and assumes that something has changed.

  • +
  • Reformulated to:

    +
    Has anything else changed in how you write code for your research after
    +attending the workshop?
    +
    +[free-form text field]
    +
    +
    +
  • +
+
+
+

Example 4

+
    +
  • Earlier version:

    +
    Has it become easier for you to collaborate on software development with your
    +colleagues and collaborators?
    +
    +- Yes
    +- Not sure
    +- No
    +
    +
    +
  • +
  • Feedback:

    +
      +
    • Leading question.

    • +
    • Avoid “Yes” and “No” response options because respondents tend to answer +“Yes” if that option is available, leading to a risk of measurement error +(acquiescence bias).

    • +
    • Do not place “Not sure” in the middle of the scale because it captures +participants who actually don’t know and should therefore be placed at the +bottom instead of in the middle of the scale.

    • +
    +
  • +
  • Reformulated to:

    +
    After attending the workshop, has it become easier or not for you to
    +collaborate on software development with your colleagues and collaborators?
    +
    +- Collaboration is easier
    +- Collaboration is not easier
    +- Not sure
    +
    +
    +
  • +
+
+
+
+

Exercise: Group discussion (10 min)

+
+

Group discussion using the collaborative notes

+
    +
  • What tricks/techniques have you tried in your teaching or seen in someone +else’s teaching that you think have been particularly effective in collecting +feedback from learners?

  • +
  • Can you give tips or share your experiences about how to convert feedback +into actionable items?

  • +
  • How do you measure the impact of your teaching? Any tips or experiences about +what you have tried or seen other courses do?

  • +
  • Anybody knows of good resources on survey design? Please link them in +the collaborative notes.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/genindex/index.html b/branch/main/genindex/index.html new file mode 100644 index 0000000..4e3dc6b --- /dev/null +++ b/branch/main/genindex/index.html @@ -0,0 +1,170 @@ + + + + + + Index — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/branch/main/guide/index.html b/branch/main/guide/index.html new file mode 100644 index 0000000..9586f8a --- /dev/null +++ b/branch/main/guide/index.html @@ -0,0 +1,260 @@ + + + + + + + Instructor guide — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Instructor guide

+
+

Target audience

+
    +
  • Everyone teaching online workshops about computational topics or interested in teaching.

  • +
  • Previous and future instructors and helpers of CodeRefinery workshops.

  • +
+
+
+

Timing

+

Session 1

+
    +
  • 15 min: Intro

  • +
  • 45 min: Lesson design and development

  • +
  • 15 min: Break

  • +
  • 45 min: Lesson template

  • +
  • 15 min: Break

  • +
  • 30 min: How we collect feedback and measure impact

  • +
  • 10 min: Outro and feedback

  • +
+

Session 2

+
    +
  • 15 min: Intro

  • +
  • 10 min: About the CodeRefinery project and CodeRefinery workshops in general

  • +
  • 30 min: Collaborative notes and interaction

  • +
  • 15 min: Break

  • +
  • 35 min: Workshop overview, roles, onboarding/installation, helpers

  • +
  • 20 min: Sound

  • +
  • 15 min: Break

  • +
  • 30 min: Screenshare

  • +
  • 10 min: Outro and feedback

  • +
+

Session 3

+
    +
  • 15 min: Intro

  • +
  • 30 min: Computational thinking

  • +
  • 15 min: Break

  • +
  • 30 min: Teaching philosohies

  • +
  • 30 min: Co-teaching

  • +
  • 15 min: Break

  • +
  • 35 min: Sharing teaching tips, tricks, tools etc

  • +
  • 10 min: Outro and feedback

  • +
+

Session 4

+
    +
  • 15 min: Intro

  • +
  • 10 min: Why we stream

  • +
  • 20 min: Behind the stream

  • +
  • 15 min: Video editing (part 1)

  • +
  • 15 min: Break

  • +
  • 25 min: Video editing (part 2, exercise)

  • +
  • 20 min: OBS introduction

  • +
  • 15 min: Break

  • +
  • 30 min: OBS setup

  • +
  • 15 min: What’s next?

  • +
+
+
+

Talking points for each sessions intro

+
    +
  • Brief CodeRefinery intro

  • +
  • Instructors intros

  • +
  • Notes intro

    +
      +
    • Check-in

    • +
    • Icebreaker

    • +
    • Participant intros in breakoutrooms (Random assign first, then same for whole session)

    • +
    +
  • +
  • Daily schedule, learning objectives

  • +
  • Code of conduct

  • +
  • Chat (please use collaborative notes)

  • +
+
+
+

Participant preparations for each session

+

Copied from e-mail communication with participants before each session.

+

Session 1: +In general you will only need your brain for the exercises and discussions, but some will have the option to go deeper, which may require some accounts or tools to be set-up. We will inform about these things the week before each session.

+

For Session 1 we recommend to have a GitHub account (https://coderefinery.github.io/installation/github/#github). There will be an optional exercise where you can build a lesson locally. This requires a basic Python environment (https://github.com/coderefinery/sphinx-lesson-template/blob/main/requirements.txt), but do not worry if you cannot or do not want to set up these, there will be plenty of other exercises.

+

Session 2: +In general you will only need your brain for the exercises and discussions. To get the most out of this workshop day we recommend that you join the session with the same computer, display and microphone setup as you would usually use for teaching/ presenting. It may also help to get familar with the different options your computer and Zoom setup provides for screenshare and audio adjustments. +But it is not a must.

+

Session 3: +In general you will only need your brain for the exercises and discussions. If you want to share some “cool gem” in the last episode of this workshop day, please update your registration (link to edit can be found in the registration confirmation e-mail sent by support@coderefinery.org or noreply@neic.org). This is very low barrier, you do not have to be the developer of a tool or technique to share with the group what makes it useful for you; and it does not even have to be cool, sometimes the small “normal” things are the best. You can check out some topics that have been proposed so far in this GitHub issue (#90), you can also comment there if you want to add or change your topic. These will be lightning talk length, so something between 2-5 min depending on how many are interested to share something, but we can collect them all in the collaborative notes for further exploration/reading. +But it is not a must.

+

Session 4: +This upcoming session (session number 4) will cover the technical aspects of CodeRefinery-style online teaching. These topics have never before been covered in this much detail, so if it’s interesting to you, don’t miss it. (You might also want to pass this on to others who are interested in technical production of online events; registration is still open!).

+

First, we talk about why we stream (how we got here, advantages, disadvantages, how to be an instructor in a livestreamed workshop, and what it looks like from a broad level from the production side)

+

Then, we show how we are able to release videos so quickly. This is useful far beyond CodeRefinery, and there are also some hands-on exercises. Come prepared to set up a Python environment and the ffmpeg command line tool if you want to try these.

+

Finally, we see details about how to set up Zoom→Livestream environment for yourself. There isn’t time to do this as a proper exercise, but it’s the starting point and the instructor will offer help after the course for those interested. If you want to try this out during the session, install OBS Studio in advance.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/index.html b/branch/main/index.html new file mode 100644 index 0000000..b00b341 --- /dev/null +++ b/branch/main/index.html @@ -0,0 +1,275 @@ + + + + + + + Train the trainer workshop — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Train the trainer workshop

+
+

August/September 2024 CodeRefinery train the trainer workshop

+

Do you teach the use of computers and computational tools? Are you curious about scaling your training and learn about tested and proven practices from CodeRefinery workshops and other trainers? Join us for the CodeRefinery train the trainer workshop: four self-contained sessions on tools and techniques for computational training offer a great chance to enhance your teaching skills and learn about new tools and practices. What you will learn is also used a lot outside CodeRefinery, whenever good beginner friendly training is needed.

+

Learning objectives:

+
    +
  • Learn about tools and techniques and practice to create engaging online teaching experiences (screenshare, audio, etc.).

  • +
  • Become mentally ready to be an instructor in a collaborative interactive online workshop (not only large workshops but in general).

  • +
  • Learn how to design and develop lesson material collaboratively.

  • +
+

Target audience:

+
    +
  • Everyone teaching online workshops about computational topics or interested in teaching.

  • +
  • Previous and future instructors and helpers of CodeRefinery workshops.

  • +
+

Prerequisites: +An interest in teaching.

+

Workshop structure: +We aim for a mix of modular presentations and work in small groups. The latter will be done in breakoutrooms - +be prepared to switch on your camera and have a fruitful exchange with fellow participants!

+

Organizers and instructors:

+

The workshop is organized by partner organizations of the CodeRefinery project.

+

Facilitators and instructors:

+
    +
  • Radovan Bast

  • +
  • Richard Darst

  • +
  • Bjørn Lindi

  • +
  • Dhanya Pushpadas

  • +
  • Jarno Rantaharju

  • +
  • Stephan Smuts

  • +
  • Stepas Toliautas

  • +
  • Samantha Wittke

  • +
+

Content and timing:

+

The workshop consists of four sessions every Tuesday between August +13th and September 3rd 2024, + to +:

+
    +
  • Session 1: About lesson design, deployment and iterative improvement (Aug 13)

  • +
  • Session 2: Tools and techniques adopted in CodeRefinery workshops (Aug 20)

  • +
  • Session 3: About teaching & cool things we all would like to share (Aug 27)

  • +
  • Session 4: Workshop streaming practices and post-workshop tasks (Sep 3)

  • +
+

You can join all sessions, or the just the ones that interest you. More details on each session will be shared later.

+

The workshop is free of charge for everyone, please register below to get the Zoom link and other useful information for the workshop.

+

The workshop is over and registration is closed now.

+

If you have any questions, please write to support@coderefinery.org.

+
+ + + + + +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/lesson-development/index.html b/branch/main/lesson-development/index.html new file mode 100644 index 0000000..ba986b1 --- /dev/null +++ b/branch/main/lesson-development/index.html @@ -0,0 +1,424 @@ + + + + + + + Lesson design and development — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Lesson design and development

+
+

Objectives

+
    +
  • We share our design processes for teaching material and presentations.

  • +
  • Learn how to design lessons “backwards”, starting from learning objectives +and learner personas.

  • +
  • Learn good practices for improving existing material based on feedback.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 20 min

  • +
  • Exercises: 35 min

  • +
+
+
+

Exercise: How do you design your teaching material?

+
+

We collect notes using a shared document (5 min)

+
    +
  • When you start preparing a new lesson or training material, where do you start?

  • +
  • What tricks help you with “writer’s block” or the empty page problem?

  • +
  • Maybe you haven’t designed training material yet. But how do you start when creating a new presentation?

  • +
  • If your design process has changed over time, please describe what you used to do and what you do now instead.

  • +
  • What do you know now about preparing lessons/training/presentations that you wish you knew earlier?

  • +
+
+
+
+

Creating new teaching material

+
+

Typical problems

+
    +
  • Someone creates a lesson, but they think about what is interesting to them, +not what is important for the learners.

  • +
  • “I want to show a number of things which I think are cool about +tool X - how do I press these into 90 minutes?”

  • +
  • Write down material you want to cover and then sprinkle in some exercises.

  • +
  • Thinking about how I work, not how the learners work.

  • +
  • Trying to bring learners to their level/setup, not trying to meet the learners +where they are.

  • +
  • Not really knowing the learning objectives or the learner personas.

  • +
+
+
+

Better approach

+

Good questions to ask and discuss with a group of colleagues from diverse backgrounds:

+
    +
  • What is the expected educational level of my audience?

  • +
  • Have they been already exposed to the technologies I am planning to teach?

  • +
  • What tools do they already use?

  • +
  • What are the main issues they are currently experiencing?

  • +
  • What do they need to remember/understand/apply/analyze/evaluate/create +(Bloom’s taxonomy)?

  • +
  • Define learner personas.

  • +
  • It may be an advantage to share an imperfect lesson with others early to +collect feedback and suggestions before the lesson “solidifies” too much. +Draft it and collect feedback. The result will probably be better than +working in isolation towards a “perfect” lesson.

  • +
+
+
+

The process of designing a lesson “backwards”

+

As described in “A lesson design process” in the book Teaching Tech +Together:

+
    +
  1. Understand your learners.

  2. +
  3. Brainstorm rough ideas.

  4. +
  5. Create an summative assessment to know your overall goal.

    +
    +

    [Think of the things your learners will be able to do at the end of the lesson]

    +
    +
  6. +
  7. Create formative assessments to go from the starting point to this.

    +
    +

    [Think of some engaging and active exercises]

    +
    +
  8. +
  9. Order the formative assessments (exercises) into a reasonable order.

  10. +
  11. Write just enough material to get from one assessment (exercise) to +another.

  12. +
  13. Describe the course so the learners know if it is relevant to them.

  14. +
+
+
+
+

Improving existing lessons

+
+

All CodeRefinery lessons are on GitHub

+ +
+

Collect feedback during the workshop:

+
    +
  • Collect feedback from learners and instructors (Example from a past +workshop).

  • +
  • Convert feedback about lessons and suggestions for improvements into issues +so that these don’t get lost and stay close to the lesson material.

  • +
+

Collect feedback before you start a big rewrite:

+
    +
  • First open an issue and describe your idea and collect feedback before you +start with an extensive rewrite.

  • +
  • For things still under construction, open a draft pull/merge request to collect +feedback and to signal to others what you are working on.

  • +
+

Small picture changes vs. big picture changes:

+
    +
  • Lesson changes should be accompanied with instructor guide changes (it’s like +a documentation for the lesson material).

  • +
  • Instructor guide is essential for new instructors.

  • +
  • Before making larger changes, talk with somebody and discuss these changes.

  • +
+
+
+

Use case: our lessons

+

As an example to demonstrate the process of designing and improving lessons, we +will have a look at one of our own lessons: Introduction to version control +with Git.

+
    +
  • Initial 2014-2016 version

    + +
  • +
  • Some time in 2014-2015 attended Carpentries instructor training.

  • +
  • 2016: CodeRefinery started.

  • +
  • 2017: Started a new repository based on the Carpentries lesson template (at the time using Jekyll).

    +
      +
    • Exercises become part of the lesson.

    • +
    • We start in the command line and only later move to GitHub.

    • +
    +
  • +
  • 2019: A lot more thought about learning objectives and personas.

    +
      +
    • Also license change to CC-BY.

    • +
    +
  • +
  • 2022: Convert lesson from Jekyll to Sphinx.

    +
      +
    • Using the tools that we teach/advocate.

    • +
    • We can have tabs and better code highlighting/emphasis.

    • +
    • Easier local preview (Python environment instead of Ruby environment which we were not used to in our daily work).

    • +
    +
  • +
  • 2024: Big redesign. We move the lesson closer to where learners are.

    +
      +
    • Start from GitHub instead of on the command line.

    • +
    • Start from an existing repository instead of with an empty one.

    • +
    • Offer several tracks to participate in the lesson (GitHub, VS Code, and command line) and learners can choose which one they want to follow.

    • +
    • Blog post: We have completely changed our Git lessons. Hopefully to the better.

    • +
    +
  • +
  • Next steps?

    +
      +
    • Making the lesson citable following +our blog post.

    • +
    • Improvements based on what we learn from this workshop.

    • +
    +
  • +
+

The overarching trend was to make the lesson simpler and more accessible - to +meet the learners where they are instead of pulling them to the tool choices of +the instructors. Looking back, we learned a lot and the learning process is +not over yet.

+
+
+

Exercise: Discussion about learning objectives and exercise design

+
+

We work in groups but use the shared document as result (20 min)

+
    +
  1. As a group pick a lesson topic. It can be one of the topics listed here but +you can also choose something else that your group is interested in, or a topic +that you have taught before or would like to teach. Some suggestions:

    +
      +
    • Git: Creating a repository and porting your project to Git and GitHub

    • +
    • Git: Basic commands

    • +
    • Git: Branching and merging

    • +
    • Git: Recovering from typical mistakes

    • +
    • Code documentation

    • +
    • Jupyter Notebooks

    • +
    • Collaboration using Git and GitHub/GitLab

    • +
    • Using GitHub without the command line

    • +
    • Project organization

    • +
    • Automated testing

    • +
    • Data transfer

    • +
    • Data management and versioning

    • +
    • Code quality and good practices

    • +
    • Modular code development

    • +
    • How to release and publish your code

    • +
    • How to document and track code dependencies

    • +
    • Recording environments in containers

    • +
    • Profiling memory and CPU usage

    • +
    • Strategies for parallelization

    • +
    • Conda environments

    • +
    • Data processing using workflow managers

    • +
    • Regular expressions

    • +
    • Making papers in LaTeX

    • +
    • Making figures in your favorite programming language

    • +
    • Linux shell basics

    • +
    • Something non-technical, such as painting a room

    • +
    • Introduction to high-performance computing

    • +
    • A lesson you always wanted to teach

    • +
    • +
    +
  2. +
  3. Try to define 2-3 learning objectives for the lesson and write them down. +You can think of these as “three simple enough messages that someone will +remember the next day” - they need to be pretty simple.

  4. +
  5. Can you come up with one or two engaging exercises that could be used to +demonstrate one of those objectives? +They should be simple enough people can actually do them. Creating simple exercises is not easy. +Some standard exercise types:

    +
      +
    • Multiple choice (easy to get feedback via a classroom tool - try to design each wrong answer so that it identifies a specific misconception).

    • +
    • Code yourself (traditional programming)

    • +
    • Code yourself + multiple choice to see what the answer is (allows you to get feedback)

    • +
    • Inverted coding (given code, have to debug)

    • +
    • Parsons problems (working solution but lines in random order, learner must only put in proper order)

    • +
    • Fill in the blank

    • +
    • Discussions, self directed learning exercises

    • +
    +
  6. +
+
+
+
+

Great resources

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/lesson.pdf b/branch/main/lesson.pdf new file mode 100644 index 0000000..eab5b37 Binary files /dev/null and b/branch/main/lesson.pdf differ diff --git a/branch/main/lessons-with-git/index.html b/branch/main/lessons-with-git/index.html new file mode 100644 index 0000000..01601a5 --- /dev/null +++ b/branch/main/lessons-with-git/index.html @@ -0,0 +1,433 @@ + + + + + + + Lessons with version control — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Lessons with version control

+
+

Objectives

+
    +
  • Understand why version control is useful even for teaching material

  • +
  • Understand how version control managed lessons can be modified.

  • +
  • Understand how the CodeRefinery lesson template is used to create new lessons

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 25 min

  • +
  • Exercises or demos: 20 min

  • +
+
+
+

Why version control?

+
    +
  • If you are in CodeRefinery TTT, you probably know what version +control is and why it is important.

  • +
  • The benefits of version control also extend to lessons:

    +
      +
    • Change history

    • +
    • Others can submit contributions

    • +
    • Others can make derived versions and sync up later

    • +
    • Same workflow as everything else

    • +
    • Write it like documentation: probably more reading after than +watching it as a presentation.

    • +
    +
  • +
  • Disadvantages

    +
      +
    • “What you see is what you get” editing is hard

    • +
    • Requires knowing version control

    • +
    +
  • +
+
+

Accepting the smallest contribution

+

Question: if someone wants to make a tiny fix to your material, can they?

+
+
+
+

Tour of lesson templates options

+

There are different ways to make lessons with git. Some dedicated to +teaching:

+ +

Our philosophy is that anything works: it doesn’t have to be just +designed for lessons

+
    +
  • Jupyter Book

    +
      +
    • Example: https://jupyterbook.org/

    • +
    • Note: is based on sphinx, many extensions here are used in CR lessons

    • +
    +
  • +
  • Various ways to make slides out of Markdown

  • +
  • Cicero: GitHub-hosted Markdown to slides easily

    + +
  • +
  • Whatever your existing documentation is.

  • +
+

We like the CodeRefinery format, but think that you should use +whatever fits your needs the most.

+
+
+

Sphinx

+
    +
  • We build all our lesson material with Sphinx

  • +
  • Generate HTML/PDF/LaTeX from RST and Markdown.

  • +
  • Many Python projects use Sphinx for documentation but Sphinx is not limited to Python.

  • +
  • Read the docs hosts public Sphinx documentation for free!

  • +
  • Also hostable anywhere else, like Github pages, like our lesson material

  • +
  • For code a selling point for Sphinx is that also API documentation +is possible.

  • +
+

Sphinx is a doc generator, not HTML generator. It can:

+
    +
  • Markdown, Jupyter, and ReST (and more…) inputs. Executable inputs.

    +
      +
    • jupyter-book is Sphinx, so anything it can do we can do. This was one of the +inspirations for using Sphinx

    • +
    +
  • +
  • Good support for inline code. Much more than static code display, if +you want to look at extensions.

  • +
  • Generate different output formats (html, single-page html, pdf, epub, etc.)

  • +
  • Strong cross-referencing within and between projects

  • +
+
+
+

CodeRefinery lesson template

+

It is “just a normal Sphinx project” - with extensions:

+
    +
  • Sphinx lesson extension

    +
      +
    • adds is various directives (boxes) tuned to lesson purposes

    • +
    • provides a sample organization and template repo you can use so that lessons look consistent

    • +
    +
  • +
  • Sphinx gives us other nice features for free

    +
      +
    • Tabs: they are very important for us and allow us to customize in-place instead of copying everything and fragmenting lessons

    • +
    • Emphasize lines: they make it easier to spot what has changed in longer code snippets

    • +
    • Various input formats

      +
        +
      • Markdown (via the MyST-parser), ReStructured text, Jupyter +Notebooks.

      • +
      +
    • +
    • Many other features designed for presenting and interacting with code

    • +
    +
  • +
  • It’s fine if you use some other static site generator or git-based lesson method.

  • +
+
+

Instructors go through the building and contributing process

+

Depending on the course, instructors will demo what is roughly +exercise 4 below. Or a course might go straight to exercises.

+
    +
  • Instructors decide what change they would want to make

  • +
  • Instructors clone the repository

  • +
  • Instructors make the change

  • +
  • Instructors set up the build environment

  • +
  • Instructors build and preview

  • +
  • Instructors command and send upstream

  • +
+
+
+
+

Exercises

+

Some exercises have prerequisites (Git or Github accounts). Most +instances of this course will have you do 1 and 2 below.

+
+

Lesson-VCS-1: Present and discuss your own lesson formats

+

We don’t want to push everyone towards one format, but as long as you +use Git, it’s easy to share and reuse.

+
    +
  • Discuss what formats you do use

  • +
  • Within your team, show examples of the lessons formats you use +now. Discuss what is good and to-be-improved about them.

  • +
  • Look at how they source is managed and how easy it might be to edit.

  • +
+
+
+

Lesson-VCS-2: Tour a CodeRefinery or Carpentries lesson on Github

+
    +
  • Look at either a CodeRefinery or Carpentries lesson

    + +
  • +
  • Can you find

    +
      +
    • Where is the content of the lessons?

    • +
    • What recent change propsals (pull requests) have been made?

    • +
    • What are the open issues?

    • +
    • How you would contribute something?

    • +
    • How would you use this yourself?

    • +
    +
  • +
+
+
+

Lesson-VCS-3: Modify a CodeRefinery example lesson on Github

+

In this, you will make a change to a lesson on Github, using only the +Github interface. (Github account required, and we assume some +knowledge of Github. Ask for help in your team if it is new to you!)

+
    +
  • Navigate to the example lesson we have set up: +repo, web

  • +
  • Go to some page and follow the link to go to the respective page on +Github. (Alternatively, you can find the page from the Github repo directly).

  • +
  • Follow the Github flow to make a change, and open a Pull Request +with the change proposal:

    +
      +
    • Click on the pencil icon

    • +
    • Make a change

    • +
    • Follow the flow to make a commit and change. You’ll fork the +repository to make your own copy, add a message, and open a pull +request.

    • +
    +
  • +
+

We will look at these together and accept some changes.

+
+
+

Lesson-VCS-4: Clone and build a CodeRefinery lesson locally

+

In this exercise, you will use Git to clone one a CodeRefinery lesson +and try to preview it locally. It assumes installation and knowledge +of Git.

+
    +
  • Use this sample repository: +git-intro (or whatever +else you would like)

  • +
  • Clone the repository to your own computer

  • +
  • Create a virtual environment using the requirements.txt +contained within the repository.

  • +
  • Build the lesson.

    +
      +
    • Most people will probably run: sphinx-build content/ _build/

    • +
    • If you have make installed you can make html

    • +
    • Look in the _build directory for the built HTML files.

    • +
    +
  • +
+

Overall, this is pretty easy and straightforward, if you have a Python +environment set up. The CodeRefinery documentation +lesson teaches +this for every operating system.

+

This same tool can be used to build documentation for other software +projects and is pretty standard.

+
+
+

Lesson-VCS-5: (advanced) Create your own lesson using the CodeRefinery format

+

In this lesson, you’ll copy the CodeRefinery template and do basic +modifications for your own lesson.

+
    +
  • Clone the lesson template: +https://github.com/coderefinery/sphinx-lesson-template

  • +
  • Attempt to build it as it is (see the previous exercise)

  • +
  • How can you do tabs?

  • +
  • How can you highlight lines in code boxes?

  • +
  • How can you change color, logo and fonts?

  • +
  • What directives are available?

  • +
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Version control takes teaching materials to the next level: +shareable and easy to contribute

  • +
  • There are different formats that use version control, but we like +Sphinx with a sphinx-lesson extension.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/notes-archive/index.html b/branch/main/notes-archive/index.html new file mode 100644 index 0000000..084aa0b --- /dev/null +++ b/branch/main/notes-archive/index.html @@ -0,0 +1,2862 @@ + + + + + + + Collaborative notes archives from workshops — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Collaborative notes archives from workshops

+
+

August/September 2024

+
+

Day1: Session 1 (13.08.24) - About lesson design, deployment and iterative improvement

+
+

:calendar: Schedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 10.00

Lesson design and development

10.15 - 11.00

8.15 - 9.00

10.00 - 10.15

Break

11.00 - 11.15

9.00 - 9.15

10.15 - 11.00

Lessons with version control

11.15 - 12.00

9.15 - 10.00

11.00 - 11.15

Break

12.00 - 12.15

10.00 - 10.15

11.15 - 12.00

How we collect feedback and measure impact

12.15 - 13.00

10.15 - 11.00

+
+
+

:icecream: Icebreaker

+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :Decaffed … and going strong …

  • +
  • :coffee: 🤔

  • +
  • :100: (ironically!) :coffee: intake happening

  • +
  • :smile:

  • +
  • :tired_face:

  • +
  • :coffee: :party:

  • +
  • :coffee: :happy:

  • +
  • 😪

  • +
  • just got zoom installed / before my coffee

  • +
  • :smil-

  • +
  • :sweat_smile: (+)

  • +
  • :yawning_face:

  • +
  • :is it morning already?

  • +
  • :smile:

  • +
  • :yawning_face:

  • +
  • :nerded_face:

  • +
  • 🥵

  • +
  • :smile:

  • +
  • :sleeping:

  • +
  • :sleepy: :coffee: :smiley_cat:

  • +
  • 🥳

  • +
  • :coffee:

  • +
  • :coffee:

  • +
+
+
+
Introduction in breakoutrooms.
+
    +
  • Name / Affiliation / Location

  • +
+
+
+
About teaching
+

What is the hardest thing about teaching for you?

+
    +
  • Knowing how “it’s going”, whether learners are happy or not (especially when teaching online) :+1:

  • +
  • The preparation the night before. It is always much more that I would hope, no matter how prepared I want it to be :+1: :+1:

  • +
  • Managing groups with vastly different academic backgrounds

  • +
  • Teaching wide spectrum of skill level at the same time. :+1: :+1: :+1: :+1:

  • +
  • Time management! (Knowing how much can fit in a sessions) :+1: :+1:

  • +
  • General preparation time, how to fit it into the regular work schedule, and estimate how much time is needed for prep.

  • +
  • How to reduce too much text into just the right amount

  • +
  • Preparation of the session material and estimating the right amount of time for each section

  • +
  • Getting learners to take the first step: sign up for and attend a workshop, when they don’t think programming is a skill they can learn

  • +
  • Getting learners to take the second step: translating what they’ve learned in a workshop into something they can apply

  • +
  • preparation and time management

  • +
  • Engaging with the students which was much easier for me when I used to coach

  • +
  • Finding the right depth for an unknown audience for “my topic”

  • +
  • education background of participants and their learning objectives

  • +
+

What is the best thing about teaching for you?

+
    +
  • Seeing when learner gets interested/curious about something and takes inspiration from the course. :+1:

  • +
  • Seeing it works and someone can do something new.

  • +
  • Motivated students grasping new stuff

  • +
  • Students picking up and running with the matertial and skills I give them and using it for their own work. :+1:

  • +
  • The “ah-ha!” moment when a student gets it! :+1::100: :+1:

  • +
  • Learning from students who know about some topic more than you do. :+1:

  • +
  • Being able to help people reach their goals, by showing them something new.

  • +
  • Teaching is optimism acted out in the hope of making a difference both ways I suppose.

  • +
  • The feeling of accomplishment when you see learning grow and implement the learnings :book:

  • +
  • mutual learning and impact on learners :+1:

  • +
  • Results and feedbacks / Mutual interests and interesting discussions

  • +
  • mutual learning and I can also learn lots of things and new ideas from participants

  • +
+
+
+
+

:question: Questions

+
+
General / Practicalities
+
    +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms? I’m not in a place where I can talk, so if we’re going to talk a lot I’ll need to move offices

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    +
  • +
  • +
+
+
+
Episode 1: Lesson design and development
+

Materials: https://coderefinery.github.io/train-the-trainer/lesson-development/ +Discussion:

+
    +
  • When you start preparing a new lesson or training material, where do you start?

    +
      +
    • I look at existing materials on the same topic, but chose/refine topics based on the perceived needs/interests of the presumed audience

    • +
    • Outline of structure and Material collection for a new lesson :+1:

    • +
    • What material I have already? (what other material is already out there?)

    • +
    • Start by looking for related resources (documents, videos, courses, etc) to have a base data and better understanding of what have been done around the topic

    • +
    • Know your audience

    • +
    • Review existing material

    • +
    • Think about learning objectives (to keep focus on essential things)

    • +
    • Think of three things simple enough that they will be remembered the next day. Design around that.

    • +
    • I write down the thoughts that I have and then go back and structure it.

    • +
    +
  • +
  • What tricks help you with “writer’s block” or the empty page problem?

    +
      +
    • Write anything down that comes to mind, sometimes draw something, looking out the window :)

    • +
    • Do a mind map - what concepts do I want to get across?

    • +
    • Starting small, for example a list of headings and then building around it. :+1:

    • +
    • What does one know about the target audience and why should they be spending longer than 1 minute listening to what they will eventually get to hear?

    • +
    • Get some inspiration from another source.

    • +
    • Start with the three things above

    • +
    • Start with the plan and the overview design

    • +
    • Some kind of outline / main message(s)

    • +
    • Start with three things. Three supporting points for each of these.

    • +
    +
  • +
  • Maybe you haven’t designed training material yet. But how do you start when creating a new presentation?

    +
      +
    • Think about the learning objectives and try to break them down into steps

    • +
    • Title, Objectives, target audience and Plan

    • +
    • Some kind of outline / main message(s). Get as many images as I can, instead of words

    • +
    • Draft an outline and use chatgpt to fill in details

    • +
    • Example of how the teaching content is applied in a real-world context

    • +
    +
  • +
  • If your design process has changed over time, please describe what you used to do and what you do now instead.

    +
      +
    • I look more at existing materials and try to get more information about the audience. Unfortunately getting information about the audience before the event is hard

    • +
    • I used to start from the begginning and get from there but that often meant a very polished start and a rushed end. Now I try an overview first, then fil out sparsed details at every section

    • +
    • Updating the data and tweak the presentation

    • +
    • If I am teaching a small group (or one to one) talk to them before hand - find out what they know already, what they want to learn.

    • +
    +
  • +
  • What do you know now about preparing lessons/training/presentations that you wish you knew earlier?

    +
      +
    • less is more. It’s better to have 2-3 main messages rather than trying to show everything in one go :+1: :+1: :+1: :+1:

    • +
    • how much practice time the learners need to master what’s taught

    • +
    • Don’t worry about something going wrong. It often makes the lesson (and thus the material) more presistent in memory. :+1:

    • +
    • Try and remove everything except what you want the person to learn

      +
        +
      • That’s a very tough part for me in the sense that I never know how much of an underlying “black box” is still ok….

      • +
      +
    • +
    • Designing intermediate materials is hard, and requires putting some “gatekeeping” making sure that learners are directed to appropriate courses

    • +
    • When I see a cool graphic, concept, slide, etc., download it and save it in my ‘new-materials’ folder to use later on!

    • +
    • I have come to the conclusion that perhaps a more “agile” approach to developing materials (try to do design/teaching iterations quickly) might be the best way to go, but there are risks with this approach too

    • +
    +
  • +
+

Questions

+
    +
  • From zoom chat: Can you expand on what a learner persona is?

    +
      +
    • A defined example person described in terms of the materials you are preparing, making up a story about the background and interest of t

    • +
    • Answer from chat: A learner persona is a blackbox which has a very simple algorithm inside: GIGO.

    • +
    • Answer from chat: I think it’s the same as ICP (Ideal customer persona) where you describe the learner as a customer

    • +
    • Answer from chat: I’m a big fan of “How Learning Works” by Ambrose et al https://bookshop.org/p/books/how-learning-works-eight-research-based-principles-for-smart-teaching-michele-dipietro/18640868?ean=9781119861690

    • +
    • See also book: Teaching tech together

    • +
    +
  • +
+
+

CodeRefinery lessons: https://coderefinery.org/lessons/

+
+
    +
  • From chat: Do you have an example of an instructor guide?

    + +
  • +
  • From zoom chat: Do you have a “measure” of how better are the new lesson compared to the old ones? Does it make sense to talk about measurements here?

    +
      +
    • So far we only have daily feedback that we collect at the end of the day and we can compare that to earlier daily feedbacks. More about that in the last episode of today. But measuring this is indeed not easy and it also takes time to capture the effect during longer-term surveys. Some of the changes were more leap-of-faith than based on data.

    • +
    • I guess that sometimes one can use “compelling arguments” instead of data to justify a decision

    • +
    +
  • +
  • Software Carpentry does teach using the command line, and gives a session on the command line before. What do you think about this approach? Are you stating that a 3-hour lesson about CLI is not sufficient to make people comfortable enough to use that for version control?

    +
      +
    • Yes, good question. For CR we consider it a more advanced step: we do think people should learn command line, but it’s for a different course. We accept some people might not know it or want to know it so adapt to that.

    • +
    • In general, we’ve found the “you need X, but have to learn A, B, and C first” approach should be avoided if possible: people are busy, try to reach people where they are.

    • +
    +
  • +
+
+

Exercise in breakoutrooms

+
+
    +
  • Room 1

    +
      +
    • Research data management

    • +
    • Objectives

      +
        +
      • Research life cycle

      • +
      • FAIR principles (Findable, Accessible, Interoperable, Reusable)

      • +
      +
    • +
    • Exercise

      +
        +
      • develop a data management plan (DMP) that outlines how their research data will be handled throughout its lifecycle.

      • +
      +
    • +
    +
  • +
  • Room 2: What is the difference between eating breakfast and sitting through a lecture? (Tip: Start by listing the similarities …)

  • +
  • Room2 : Making papers in LaTeX +- What is LaTex and how is it different from editors like Word +- Basic Structures +- How to find and use a template +- Including figure & table +- How to use references and labels +- Exercise: to create a new LaTeX document & edit it +- Excercise: common error messages: can you find the error in this code? +- Exce

  • +
  • Room 3

    +
      +
    • GPU Programming (1 hour intro)

    • +
    • Learning objectives:

      +
        +
      • What is GPU programming.

      • +
      • When is it usable, beneficial to use GPU programming?

      • +
      • What are technologies to do GPU programming?

      • +
      • [What are and how to manage typical issues]

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • Git / Figures / Project management / data cleaning

    • +
    • Chose data cleaning

    • +
    • Three learning objectives:

      +
        +
      1. What do we mean by “clean”? How to identify it?

      2. +
      3. Identify some common problems in a dataset

      4. +
      5. Identifying and handling missing values/fields

      6. +
      +
    • +
    • Exercise

      +
        +
      1. Discuss problems, find the most common ones

        +
          +
        • In small groups

        • +
        • What problems have you run into with datasets you’ve worked with?

        • +
        • What problems can you imagine, or have you heard about from colleagues/news/social media?

        • +
        • Report back, instructor collects all problems into a list

        • +
        +
      2. +
      3. Have a dataset to clean; a clean and a messy example

        +
          +
        • (identifying) Using a visualisation or overviewing tool?

        • +
        +
      4. +
      +
    • +
    +
  • +
  • Room 5

    +
      +
    • Jupyter Notebooks

    • +
    • Learning Objectives

      +
        +
      • Can setup an enviroment you can reuse / can share with others / a project.

      • +
      • The order you run the commands in needs to match the order of the code in the Notebook - otherwise you end up in a pickle.

      • +
      • Why use a Jupyter Notebook? What are the advantages? Easy to use environment.

      • +
      +
    • +
    • Exercise

      +
        +
      • Print variable assignments from different cells - show that the order you run the code is important.

      • +
      • hand out a domain specific notebook that does some calculations and visualization to run and modify, to show that you can share easily

      • +
      • show !pip install to add dependencies/features

      • +
      +
    • +
    +
  • +
  • Room 6

    +
      +
    • Using GitHub without the command line

    • +
    • Learning Outcomes:

      +
        +
      • Be able to discuss changes before merging changes into the main repository.

      • +
      • Publish a personal repository page ( I think its called intro repository)

      • +
      • Share their script/notebook/code/small data on GitHub

      • +
      • Homepage using GitHub pages or the README that becomes the “index page” of the GitHub user account page

      • +
      +
    • +
    • Learner personas:

      +
        +
      • Check the Personas of the learners

        +
          +
        • Somebody who has seen/heard of GitHub but hasn’t used it yet

        • +
        • Someone using it for their own work but struggling with collaboration

        • +
        +
      • +
      +
    • +
    • Exercises:

      +
        +
      • Upload/share an example dataset or script

      • +
      • Review another collaborators pull request.

      • +
      • Take part in the discussion on a pull request.

      • +
      +
    • +
    +
  • +
  • Room 7 +Linux shell basics: why do we want to teach them? +(this took most of the time for the discussion)

    +
      +
    • Learning objectives:

      +
        +
      1. Filesystem: Directory (CLI) - Folder (GUI) analogy

      2. +
      3. Basic commands (which commands are basic? make a survey of shell histories and get the most common ones)

      4. +
      5. Basic constructs (e.g., for loops, pipes, while loops… which ones are basic? See above)

      6. +
      +
    • +
    +
  • +
+
+

Note from chat: Zoom timer: https://support.zoom.com/hc/en/article?id=zm_kb&sysparm_article=KB0068677

+
+
+
+
Episode 2: Lessons with version control
+

Materials: https://coderefinery.github.io/train-the-trainer/lessons-with-git/

+

Poll options: I want to hear about:

+
    +
  • A: Why use version control for teaching materials

  • +
  • B: Different template options

  • +
  • C: How CodeRefinery does it; CodeRefinerys lesson template

  • +
+

Poll vote (multi-select): add a o to your answer +- A: ooo +- B: oooooo +- C: oooooooo :ghost:

+

Question to audience: if someone wants to make a tiny fix to your material, how hard is it?

+
    +
  • If my material is only in pdf format which is not online, then it is hard.

  • +
  • I hope it is easy - my material is in GitHub. Nobody has ever done that though!

  • +
  • Slides: hard to find, easy to edit; Git repos somewhat easy, unless they have to be built locally or with an action; HackMD easiest to edit.

    +
      +
    • if you use something like google slides they are not that difficult to find

    • +
    • known permanent address. Google docs et al fail on that/same for many pads.

    • +
    +
  • +
  • For this material today - very easy! e.g. https://github.com/coderefinery/train-the-trainer/pull/128

  • +
  • Template with an edit button in the HTML pointing to the source-code in the repo.

  • +
+

Questions/Discussion topics

+
+

Upcoming CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/ +Please share with your networks, and let us know if you would like to co-teach a lesson (to support@coderefinery.org or in our Zulip chat)

+
+
    +
  • Changes to the material are sometimes not just tiny fixes. For example, one wants to present a slightly different selection of topics, but maybe some topics are “coupled” (perhaps naturally or perhaps just because of how they are presented), or change the general “theme” (e.g., life sciences vs theoretical physics) while keeping the actual topics the same. How could a lesson be developed to avoid having to do a huge rewrite?

    +
      +
    • You can try to modularize your material and keep non topic specific parts non themed. E.g. where you explain the functionality, don’t make reference to the example (not simple), so the example can be changed depending on the audience.

    • +
    +
  • +
  • What are the pros/cons of renaming a course / changing a repo name in GitHub?

    +
      +
    • It should be relatively unproblematic since GitHub will forward to the new name.

      +
        +
      • How long does Github keep the “old” name linked? Is there a max time it’s blocked, or changed as soon as a new one appears with the name?

        +
          +
        • in my experience it forwards “forever” until I create a new repo with the old name which will break the forward

        • +
        +
      • +
      +
    • +
    +
  • +
  • what should be in the readme for the git repo? (canonical address? contact points? license!)

    +
      +
    • https://coderefinery.github.io/mini-workshop/2/documentation/#often-a-readme-is-enough-checklist

      +
        +
      • I miss the url to the (main) repo in the readme

        +
          +
        • Do you mean the link to the rendered (lesson) page?

        • +
        +
      • +
      +
    • +
    • Link to rendered page: We often have this in the “about” section of the readme (see up right: https://github.com/coderefinery/train-the-trainer)

    • +
    • this gets lost in a fork, doesn’t it? so 20 folks forking and or reuploading the repo somewhere means the url gets lost?

      +
        +
      • True, but they might want to have their own version rendered?

        +
          +
        • yes, I have had issues finding and contributing to the “master” repo so all benefit. Else it gets cluttered. Both is valid

          +
            +
          • Good point though, the link to rendered page should probably also be included in the readme for completeness; ah and the link to the repository too, yes

            +
              +
            • so realistically we need a content folder and some more next to the readme as a best practice. sounds good!

            • +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • Is myst (markdown renderer) enabled by default in sphinx now?

    +
      +
    • to my knowledge no. we add the “myst_parser” extension to conf.py.

    • +
    +
  • +
+
+

Cicero: https://cicero.readthedocs.io/ +Sphinx documentation: https://www.sphinx-doc.org/en/master/ +Carpentries workbench for creating Carpentries lessons: https://carpentries.github.io/workbench/ +This is the testing lesson Richard showed: https://coderefinery.github.io/testing/ +And the corresponding repository: https://github.com/coderefinery/testing +You can lean back and watch, exercise coming in a bit :) +Richard will now edit our train the trainer material repository: https://github.com/coderefinery/train-the-trainer +The Sphinx extension for CodeRefinery lessons: https://github.com/coderefinery/sphinx-lesson +Empty lesson template to build your own lesson: https://github.com/coderefinery/sphinx-lesson-template

+
+

More questions

+
    +
  • Does the coderefinery.org page built on sphinx?

    +
      +
    • It’s built also from markdown but it uses https://www.getzola.org/ (which is more optimized to render websites, but we could do teaching also with Zola or create the project page using Sphinx)

    • +
    +
  • +
  • Is there a way to build and preview CR lessons without the command line?

    +
      +
    • The GitHub workflow we use creates HTML from all branches. This means that one can push a branch to GitHub, preview it there, and then open a pull request. One thing that would be nice but we don’t have yet is if a bot automatically posts the link to the preview to a pull request.

    • +
    +
  • +
  • For VCS-2, for the Carpentries Linux shell example, Lesson, Github repo, to me it seemed as though the Sandpaper setup they have makes a very nice interface, complicates the relationship between source and output. E.g on the soucre page https://github.com/swcarpentry/shell-novice/blob/main/index.md I could only see to ‘Prerequisits’ and not ‘Download files’ on the page https://swcarpentry.github.io/shell-novice/. Perhaps I have missed something?

    +
      +
    • I am sorry I don’t know the new Sandpaper setup well enough to answer this question.

    • +
    +
  • +
  • Do we have the instructions to build the lessons available somewhere to try out later?

    +
      +
    • https://github.com/coderefinery/sphinx-lesson

    • +
    +
  • +
+
+

Exercise VCS-1 (and VCS-2 (if time)) (https://coderefinery.github.io/train-the-trainer/lessons-with-git/#exercises) in breakoutrooms until xx:05

+

then short summary in main room and then break.

+

Use the notes below. Collect a list of lesson formats and discuss what you like about each of them.

+
+
    +
  • PDF slides by a presentation program

  • +
  • pdf slides with beamer in latex under source control.

  • +
  • Markdown slides via Github

  • +
  • CodeRefinery template

  • +
  • Carpentries template

  • +
  • Google Slides

  • +
  • git-book

  • +
  • Jupyter Book - allows creating a structured reference website using RST/Markdown, including Jupyter Notebooks to show result of running code

  • +
  • mdbook - create simple/minimal website using Markdown

  • +
  • Binder - allows learners to run their own live version of a github repository with Jupyter Notebooks, with only a web browser

  • +
  • Jupyter notebooks and jupyterhub platform

  • +
  • Jupyter + Nbviewer and custom css (read only) + Binder link (hands on)

  • +
  • RMarkdown

  • +
  • Quarto Slides

  • +
  • Reveal.js - write slides in HTML (also supports markdown)

    +
      +
    • Example: https://bl-presentations.erambler.co.uk/2024-02-21-idcc24/

    • +
    +
  • +
  • Remark.js - write slides in markdown

    +
      +
    • Example: https://bl-presentations.erambler.co.uk/2024-02-19-idcc-pids-workshop/

    • +
    +
  • +
+

Room discussions:

+
    +
  • Room 1

    +
      +
    • (https://smc-aau-cph.github.io/SPIS/README.html)

    • +
    • CodeRefinery template

    • +
    • Shared notes & blogs

    • +
    +
  • +
  • Room 2

    +
      +
    • demo the exercise

    • +
    +
  • +
  • Room 3

    +
      +
    • Mix of JupyterLab, Terminal within that, and traditional slides

    • +
    • Jupyter + RISE (benefit: slides that are editable and executable live)

    • +
    • Challenges

      +
        +
      • present code in an interactive way

      • +
      • handle lots of images/ figures without too much additional overhead when setting up the material

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • Material and tools depend on instructors

    • +
    • Some slide building tools

      +
        +
      • https://revealjs.com/

      • +
      • https://remarkjs.com/

      • +
      • https://github.com/rust-lang/mdBook

      • +
      +
    • +
    • Using flat git repos without fancy styling to make it easier to edit but still version controlled

    • +
    +
  • +
  • Room 5

    +
      +
    • Using R as a GIS: https://github.com/nickbearman/intro-r-spatial-analysis

      +
        +
      • Workbook: RMarkdown, Slides: Quarto

      • +
      • No continuous intergration

      • +
      +
    • +
    • Having a jupyter nbinder link to test the notebook

    • +
    • repo lives on codeberg in this example

    • +
    +
  • +
  • Room 7

    +
      +
    • Ex 1:

      +
        +
      • Sphinx, similar to CR

      • +
      • Sometimes pdfs generated with beamer package (or from pptx and odt), but blows up repository size if in version control

      • +
      +
    • +
    • Ex 2:

      +
        +
      • Content

        +
          +
        • CR: Content commonly found int the content folder

        • +
        • SC: Mostly under episodes

        • +
        +
      • +
      +
    • +
    • Question that came up:

      +
        +
      • is CR/Sphinx approach mostly for technical topics? What about language.

      • +
      • I guess by our nature it’s focused there. But probably could be used for others (I guess it it’s much easier to use git in a technical audience.)

      • +
      +
    • +
    +
  • +
+
+
+
Episode 3: How we collect feedback and measure impact
+

Materials: https://coderefinery.github.io/train-the-trainer/feedback-and-impact/

+

Questions to audience

+
    +
  • What tricks/techniques have you tried in your teaching or seen in someone else’s teaching that you think have been particularly effective in collecting feedback from learners?

    +
      +
    • preparing a survey and emailing it to participants as soon as the event ends (usually get <50% of answers but it’s a representative enough sample)

    • +
    • do engage with the audience, give them the time to get the courage to speak up

    • +
    • Be the audience yourself

      +
        +
      • yes! some problems/issues I don’t notice as instructor, only as listener

      • +
      +
    • +
    • Have time (e.g. 5 min) in the session to fill out the feedback form

    • +
    • If the course/workshop has several days/sections do a couple questions every change, then a full one afterwards

    • +
    • “Traffic light” feedback (e.g. for pacing or progress on exercises): give each learner two different coloured post-it notes for in-person, or use emoji for online, to indicate a current status

    • +
    +
  • +
  • Can you give tips or share your experiences about how to convert feedback into changes or actionable items?

    +
      +
    • ask questions about things you know you don’t know

    • +
    • “Don’t let the noise of others’ opinions drown out your own inner voice.” — Steve Jobs

    • +
    +
  • +
  • When people ask questions / get stuck with a specific step. Is there a typo I can change there and then in the workbook?

    +
      +
    • Being able to fix small things on the fly helps sometimes, otherwise open issues if working on github

    • +
    • If multiple people have the same question, then this is an indication that I should look at this in more detail

    • +
    +
  • +
  • How do you measure the impact of your teaching? Any tips or experiences about what you have tried or seen other courses do?

    +
      +
    • “How likely are you to recommend this workshop to others? (0/5)”

    • +
    • Check the ‘Garbage Out’ bin, what you find there will be what went across. The rest will be history…

    • +
    +
  • +
  • Anybody knows of good resources on survey design? Please link them here.

    +
      +
    • “Our job is to figure out what they’re going to want before they do… Our task is to read things that are not yet on the page.” - Steve Jobs

    • +
    +
  • +
+

Questions/Discussion points

+
    +
  • Feedback is necessary to design good lessons. Improvement can only be done iteratively. So the faster the iteration (design/teach), the better. But on the other hand, I cannot constantly bomb our community with training event emails. So I would like to try proposing a course many times a year, but I don’t want to spam everybody many times a year.

    +
      +
    • :+1:

    • +
    • With CR we also have a calendar that can be imported to different calendar applications, where we add all workshops: https://github.com/coderefinery/calendar/

    • +
    +
  • +
  • Does an even split of too fast / too slow mean speed is about right?!

    +
      +
    • I take it to mean “it’s roughly where it should be”. Would be better to accomdate the sides better though… (we do try to design for a broad audience: some easy stuff, some advanced stuff, so people can make their own path)

    • +
    • It could also indicate that the prerequisites/scope are not well defined :+1:

      +
        +
      • Based on long term surveys we also know though that even though the workshop might have been to fast, people appreciate having “heard things before and know where to find them later”

      • +
      +
    • +
    • perhaps the even split between too fast/too slow is ok only if the majority of votes goes for “just right” :+1:

    • +
    +
  • +
  • One of the most important disciplines in journalism is to challenge your working premises. (Bill Keller) This applies equally to learning as well.

    +
      +
    • Participants can be encouraged to write some posts on LinkedIn. If it is helpful some blurbs can be created for pre and post-workshop to generate more traction for Code Refinery and future participation.

    • +
    • Ask participants if they use Dev.to, hashnode etc to blog their work or use twitter etc to have a memory of their work.

    • +
    +
  • +
  • Do you have any suggestions for prerequisites? I try to make them clear, but occasionally people attend who clearly do not meet them. :+1:

    +
      +
    • I guess it depends how much it matters for the workshop itself. If you have group exercises etc, it probably matters? , lecture style maybe not so much?; important is that the participants themselves know that prerequisites exist and if they meet them

    • +
    • Sometimese people that do not meet the prerequisites join to get to “know what they don’t know”, find out where to find information on topics they might get interested in future etc

    • +
    • Other suggestions? Viewpoints? :)

    • +
    • Thank you - things for me to think about there :-)

    • +
    • With CR’s latest ideas, we try to make the prerequisites clear, but there is no capicity limit: it’s OK if people drop by and are less than prepared: it’s livestream, anyone can come. We try to have something for these people, too: learn what you are missing, why you might want to study more in the future.

    • +
    • Any thoughts on applying this to a more practical focused course, with a total capacity limit (i.e. not like CodeRefinery).

    • +
    +
  • +
  • Everytime you do a course on CodeRefinery, think of it as trying to bake a new cake with an old recipe with no idea about the individual taste preferences of the one you bake the cake for. Then, you will not experience too many surprises. Fine-tuning the recipe for one cohort still remains the ‘old recipe’ as far as the next ‘new cohort’ will be concerned. C’est la vie.

    +
      +
    • nice analogy!

    • +
    +
  • +
  • Question from chat: For examples 2 & 4, would you also consider using something like a Likert scale? E.g. Rate how well you agree with the statement “My code is more reusable as a result of attending a CodeRefinery workshop” (from 1 Strongly disagree to 5 Strongly agree)

    +
      +
    • Thanks! I am new to Likert scale and will read up on it. In my experience numbered answers can be useful for reporting. But I also like questions where we ask for what actually to change.

    • +
    +
  • +
  • Comment from chat: Richard, your point crowns the point of having CodeRefinery, With Radovan’s and Samantha’s acquiescence assured, I would like to suggest you wear a crown going forward, especially for the CodeRefinery session. Do we have a deal ?

    +
      +
    • I don’t quite understand this

    • +
    • I think it’s a tongue-in-cheek-comment (joke) but I am not sure…..

    • +
    +
  • +
  • What is the ideal way to allow people to interact while course is going on in the main online session, i.e. without a breakout room? Taking a pause or discussion in the background?

    +
      +
    • I’ve had some success with WhatsApp groups for a course - particually ones that run over 4 (or 2) sessions.

    • +
    • A quick survey/quiz

    • +
    • Question to the audience that we take time to answer but it helps to show the answers

    • +
    +
  • +
+
+
+
+
+
+

Wrapup

+
    +
  • Thank you for active participation :)

    +
      +
    • We’ll continue answering questions after the workshop and make the cleaned up (no names etc) available from the materials

    • +
    +
  • +
  • Next session Tuesday August 20, 9 CEST: Tools and techniques adopted in CodeRefinery workshops

    +
      +
    • we will talk about on-boarding, install help, roles, screensharing, sound, collaborative notes

    • +
    +
  • +
  • All workshop materials will stay available (after the full workshop also on Zenodo :tools:)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • If you want to co-teach with us in the upcoming (or next) CodeRefinery workshop (https://coderefinery.github.io/2024-09-10-workshop/); or just want to learn more about this opportunity: Send your name and e-mail address to support@coderefinery.org; we will contact you!

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • Lesson design approach

  • +
  • I liked the backwards lesson design, gives a name to a practice I’ve already been doing :+1: :+1:

  • +
  • Lessons from code refinery on lesson design. Learning about Sphinx.

  • +
  • Collaborative notes and anonymized archive of notes.

  • +
  • it’s nice to have a community to discuss these kinds of problems

  • +
  • Hearing the variety of tools people use for slides (PDF, Quarto, Beamer etc.)

  • +
  • Good intro of the tools, the jargon and the pedagogical philosophy of teaching tech.

  • +
  • The absolute openess in having everything publicly available - materials ofc but also questions, discussions, feedback, …

  • +
  • Thinking about all content being available publicly and as a git repo

  • +
  • Thanks for explaining the HedgeDoc interface, with view and edit options

    +
      +
    • Is there anyway to come back to this document later (e.g. tomorrow) and see what has changed since now? So I can see if any other questions have been asked/answered?

      +
        +
      • There is a “revision” point under “Menu” up right, which shows you different versions of this document

      • +
      +
    • +
    +
  • +
  • Modesty: the gentle art of enhancing your charm by pretending not to be aware of it. - Oliver Herford

  • +
  • +
+

What one thing would you improve about this session?

+
    +
  • Perhaps some more interactivity but can be hard to plan and time

    +
      +
    • We’ll see what we can do.

    • +
    +
  • +
  • Maybe mix the breakout groups up for each breakout session (although there are advantages to consistency too) :+1:

    +
      +
    • yes, pros and cons! For me, having consistency worked well this time.

    • +
    • Likely we will have different participants next week, and a bit of mixing will happen naturally.

    • +
    +
  • +
  • The pace of the presentations could be a little tighter (the pace is good for a discussion though)

  • +
  • Richard’s voice was only 80% audible

    +
      +
    • Sorry to hear that. It seemed fine on my end. Will check better for next session.

    • +
    +
  • +
  • Hands on simulation and collaborative notes

  • +
  • I found it difficult to follow the presentation and the collaborative notes at the same time

    +
      +
    • We will highlight the collaborative notes more in the next session. Our strategy usually is to say to focus on the “teaching part” and use the notes only when needed. Since you can go back and also check the notes later.

      +
        +
      • My problem is that I want to follow both since I don’t want to miss out on anything. As such, I have both windows (zoom and the notes) open side-by-side. Since there is near-constant real-time typing in the editor, and as such visible movement on screen, I get constantly distracted. This makes following the event quite exhausting.

      • +
      +
    • +
    +
  • +
  • Heads up to participants on using the break out rooms on voice interaction and screen sharing.

    +
      +
    • Do you mean that we should have mentioned it more clearly in the pre workshop email?

    • +
    +
  • +
  • I found it hard to follow with so many things going on at once…

    +
      +
    • A collaborative document being changed at the same time as…

    • +
    • Someone speaking and explaining content at the same time as…

    • +
    • Chat in a different application at the same time as…

    • +
    • Content changing in a termin application.

      +
        +
      • Thank you for the feedback. We will remove the Zoom chat out for the next session and explain the use of the collaborative notes more.

      • +
      +
    • +
    +
  • +
  • Make more use of defining and then making sure the learning objectives are met

    +
      +
    • True we did not talk about them much, will pick that up better for next session.

    • +
    +
  • +
  • UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. - Dennis Ritchie. You need to do a lot to prove that to be wrong, simply put.

  • +
  • Allocate some time for learners to type in the answers so that we don’t have to listen and type at the same time.

  • +
+

Any other comments?

+
    +
  • It’s great to hear other people’s experience

    +
      +
    • Good to hear :)

    • +
    +
  • +
  • Looking to meet you onsite if there are any events and get more emails from you :)

    +
      +
    • We will keep you informed :)

    • +
    +
  • +
  • Thanks for putting this together, I got a lot of inspiration for my own courses

    +
      +
    • Good to hear :)

    • +
    +
  • +
  • I didn’t know where to ask questions. It would work best for me to do it in zoom chat as that’s the application that I’m watching in..

    +
      +
    • Sorry for that, just to figure out why: Did you join a bit late?

      +
        +
      • No. Perhaps I just missed that or it was too quick for me or something?

        +
          +
        • Ok, sorry. Will try to make this more clear in next session.

        • +
        +
      • +
      • Perhaps also because there were so many things going on and jumping around. For me, the zoom chat is the constant (and obvious) place to ask questions while watching a shared screen, trying to find the right place in a moving collaborative document is difficult. It tears my attention into too many pieces. :+1:

      • +
      +
    • +
    +
  • +
  • Had a lot of content that assumed extant knowledge that I didn’t have. This wasn’t in the pre-requisites.

    +
      +
    • Do you have examples?

      +
        +
      • Yes! The code refinery templates and even just the way of doing that. I was expecting more on “when designing a lesson you should think about these steps” rather than this is how we do it and this is our tool for doing it. I guess I should have read the pre-workshop content better?

      • +
      • Ok, thank you for your feedback. You are right that we actually had some content that for sure would have been easier to follow for people with background knowledge about a certain topic.

      • +
      • “If you are in CodeRefinery TTT, you probably know what version control is and why it is important.” - extant knowledge, why not just add a sentence or two?

        +
          +
        • Please can you update in preparation for the next workshops so that I can decide whether or not they will be right for me?

          +
            +
          • Yes, we will think more thoroughly about this and send the info in the next email going out Wed/Thu

            +
              +
            • Thank you!

            • +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • Lots of the content was relevant to code refinery but not the wider topic (e.g. it was how to design a code refinery lesson and not how to design a lesson as stated in the session title)

    +
      +
    • We thought of the content of showing one way of doing things, ie “what we have learned”, if you have suggestions on how we could make that more clear on the event page, please let us know :)

      +
        +
      • “in a code refinery lesson” in the lesson/workshop description?

      • +
      +
    • +
    +
  • +
  • When you have pre-written “thank you for your active participation” it feels fake!

    +
      +
    • He, that is true, did not think about that. Thank you for the feedback. I would not have added it if Radovan and Richard would not have provided good feedback from circling the rooms.

    • +
    +
  • +
  • I found it vague and disorganised and difficult to follow. It felt like the instructors were presenting the content for the first time and didn’t know what to do next.

    +
      +
    • Thank you for your feedback. This is not the first time we have this training, but it is the first time in this constellation/way. The way of teaching may also sometimes make it seem new to instructors.

    • +
    +
  • +
  • I really liked the active exchange with other participants, but I also would have enjoyed a bit more technical content in the presentations. In a sense it felt less like a ‘training’ and more like a get-together :+1:.

    +
      +
    • Thank you for your feedback. We thought the name “workshop” would combine the training and exchange nature of this event. But maybe it didn’t do so enough? Do you have suggestions on how to clarify it on the event page?

      +
        +
      • Well, the ‘train the trainer’ title created the anticipation of being trained ;) don’t get me wrong, I liked the exchange, but I felt that the training aspect fell a little short. imho the workshop would benefit from a little more (instructional) content that is presented in a more structured way by the instructors (as opposed to ‘crowd-sourced knowledge’ that is collated in a loose collection of questions, notes and links)

      • +
      • Other than that, you could add another section on the main page, sth like ‘Workshop structure: we aim for a mix of modular presentations and work in small groups. The latter will be done in breakout rooms - be prepared to switch on your camera and have a fruitful exchange with fellow participants!’

        +
          +
        • Thank you for the suggestions, will add something like this :tools:

          +
            +
          • +

            Added : https://github.com/coderefinery/train-the-trainer/commit/03308595436e636b3bb37ed9d1f0dee39eeccd0f

            +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • My understanding (so far) of what (unlike the competition) CodeRefinery DOES NOT seek to exemplify - +https://images.ctfassets.net/rxqefefl3t5b/2k45BFtw4sBMlBfjr1OZ90/5c6ecd3628a43b0cdc79815f665e224a/Screenshot_2023-05-02_at_09.35.23.png?fl=progressive&q=80

  • +
  • My understanding of what (unlike the competition) today’s session of CodeRefinery DID exemplify - Definition of ‘Workshop’ from the Oxford dictionary of the English language “a period of discussion and practical work on a particular subject, in which a group of people share their knowledge and experience”

  • +
  • In my experience, even for the most seasoned Programmer coding, by its very nature, is nothing trivial, this being a simple straightforward fact just like there is no such thing as an egg which is a cube. I mean there is a reason why not just about everybody is a poet either. But, other minds have pointed this out without having to first explain why the universe is what it is in a way that could be understood without effort … https://i.pinimg.com/originals/7b/7e/c4/7b7ec4b91d2cf9d8e1b064678d205467.jpg

  • +
  • The inclusive environment feels very welcoming. Keep up the good work!

  • +
+

Thank you all for your feedback! Highly appreciated!

+
+
+
+

Day 2 : Session 2 (20.08.24)- Tools and techniques adopted in CodeRefinery workshops

+
+

:calendar: Schedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 9.25

About CodeRefinery workshops

10.15 - 10.25

8.15 - 8.25

9.25 - 9.55

Collaborative notes and interaction

10.25 - 10.55

8.25 - 8.55

9.55 - 10.10

Break

10.55 - 11.10

8.55 - 9.10

10.10 - 10.45

Workshop overview, roles, onboarding

11.10 - 11.45

9.10 - 9.45

10.45 - 11.05

Sound

11.45 - 12.05

9.45 - 10.05

11.05 - 11.20

Break

12.05 - 12.20

10.05 - 10.20

11.20 - 11.50

How to prepare a quality screen-share

12.20 - 12.50

10.20 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+

:icecream: Icebreaker

+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :-)

  • +
  • https://media.istockphoto.com/id/148421550/vector/bored-emoticon.jpg?s=612x612&w=0&k=20&c=uo5KBTqdJZbBQb_Xldhzuovx5t08fHfGR7dw7TCk90I=

  • +
  • :saluting_face:

  • +
  • :sleepy:

  • +
  • :coffee:

  • +
  • :umbrella:

  • +
  • :cocktail: :coffee:

  • +
  • :seedling:

  • +
  • :tired_face:

  • +
  • :sun_with_face:

  • +
  • 🥴 (:woozy_face: not converted?)

  • +
  • :coffee:

  • +
  • :sunflower: :book:

  • +
  • :satisfied:

  • +
  • :coffee:

  • +
  • :coffee:

  • +
  • 🥱:tired_face:

  • +
  • :bread: - I am baking bread today so I have been kneading dough while listening!

  • +
+
+
+
Introduction in breakoutrooms
+

Name / Affiliation / Location

+
+
+
Teaching
+
    +
  • Do you teach and organize teaching alone or with others? What would you prefer and why?

    +
      +
    • Coming together is a beginning; keeping together is progress; working together is success. – Edward Everett Hale

    • +
    • These days always with others. Alone is easier to prepare but almost always is harder during it.

    • +
    • Teaching with very diverse partners, it can be challenging to find a common language with people very different than you.

    • +
    • I teach alone, in the future there will be more collaboration with multiple team members. Both approaches have their pros and cons.

    • +
    • Both has its own distinct advantages

    • +
    • Most of my teaching is on my own, as a freelancer its more expensive to work with colleagues than to deliever a course on my own.

    • +
    • Teaching together, learns from each other, feedbacks to improve

    • +
    • Not formally taught yet, only given presentations actually .

    • +
    • collective teaching would benefit the teachers with collaborative curriculumn and experiences sharing.

    • +
    +
  • +
  • If applicable, have you seen any challenges when teaching together and how to overcome them?

    +
      +
    • It actually requires preparation,

    • +
    • Is it about teaching or about inspiring ? Discover the answer and get inspired …

    • +
    • It’s like being in a band: you might be great at improvising and your band-partners might be great at improvising too, but a bit of rehearsing makes even the impro gig much better

    • +
    • Need to plan before session, difficult if people don’t ‘plan’ in the same way, e.g. with the same time frame.

    • +
    • Heterogeneity in learners make it impossible to get the same result from everyone.

      +
        +
      • In fact, the same applies to teachers :D

      • +
      +
    • +
    • Teaching together requires to have similar opinions on how to teach. I share vews only with ~40% of my colleagues I think.

    • +
    +
  • +
  • No Teaching experience but it is good to give the outline of the lessons beforehand and learning goals.

  • +
+
+
+
+
+

:question: Questions

+
+
General / Practicalities
+
    +
  • What is this document for?

    +
      +
    • Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts)

    • +
    +
  • +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms?

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    • BR 1 : The Zoom chat does not work for the breakout room so we should take note of that. No webcam/mic = expect silence.

      +
        +
      • Thanks for notifying! This was not intended. Turned the chat back on.

      • +
      +
    • +
    +
  • +
+
+
+
+
+

Episode 1: CodeRefinery

+

Materials: https://coderefinery.github.io/train-the-trainer/coderefinery-intro/

+
    +
  • (questions continue here)

  • +
  • Is there the plan to build capacity / be paid to deliever courses?

    +
      +
    • We’ve discussed it but right now we don’t have many people who could accept money to do this (and maybe shouldn’t, because of their jobs). But, we would encourage others to use our materials as “independents” to deliver paid courses

    • +
    • One idea we have had is that paid courses could be delivered through the DRA (link below), who we know. Basically, DRA could find instructors and handle the money transfers (If someone wanted a paid course, we could help find someone to do it through DRA or independently)

    • +
    • :smile:

    • +
    +
  • +
  • Have you come across DRA, https://digital-research.academy/, Heidi Seibold, Joyce Kao who are doing similar work? I can connect you if you like.

    +
      +
    • Yes we have been discussing about possible future collaborations and are already sending possible clients their way (we, as a project cannot take money) :+1:

      +
        +
      • Excellent! :-D :smile:

      • +
      +
    • +
    +
  • +
  • .

  • +
+
+
+

Episode 2: Collaborative Notes

+

Materials: https://coderefinery.github.io/train-the-trainer/collaborative-notes/

+
    +
  • So anyone can type anonymously?

    +
      +
    • Yes, as long as you do not log in, you are Guest XXX

    • +
    • And at least in our hedgedoc case you cannot log in so you will always be anonymous. You can do [name=xxx], to add your name to a comment

    • +
    +
  • +
  • Test of +1

    +
      +
    • +1 :+1: :+1:

    • +
    • :-1: a test

    • +
    +
  • +
  • You are hosting your own version of HedgeDoc, and Hackmd.io is a similar (free) option. What are the limitations of the free hackmd.io? Should each center install their own HedgeDoc instance?

    +
      +
    • It seems the free version of HackMD has gotten worse lately. It works still well enough with a few people editing at the same time.

    • +
    +
  • +
  • Have there every been problems with the anonymity and CoC?

    +
      +
    • We haven’t had any issues so far.

    • +
    • With a different anonymous tool in a bachelor course, we had issues with anonymous participants (participants were posting slurs and unsafe links). The course organiser decided to stop allowing anonymous tools.

    • +
    +
  • +
  • Why not google documents?

    +
      +
    • Google documents are actually setting a hard limit for simultaneous writing, no more than 100 concucurrent editors. I am unsure if microsoft onedrive word documents would allow more users writing at the same time.

    • +
    +
  • +
  • What’s the most people you have every had on HackMD / Hedgedoc?

    +
      +
    • I believe about 200 active participants?

    • +
    +
  • +
  • What are your thoughts on using the build-in Zoom Q&A?

    +
      +
    • We haven’t tried this, in part because the way we do streaming now (you’ll see in session 4), participants aren’t in Zoom so don’t have access to that. The doc-format works pretty well though, when we keep it in this limited “write at end” format.

    • +
    +
  • +
  • How do you see what has changed? e.g. if leave the session at the end, can I come back tomorrow and see X has been added? e.g. a diff for this maybe?

    +
      +
    • In the menu up right there is revision, it does show the document and changes at different time step :+1: Thanks!

    • +
    • We recommend people only write at the bottom (and since we answer things live), so as a first level approximation you find where you were and read below that. Think of it more like chat than a full document. (Yes, we do revise questions at the end)

    • +
    +
  • +
  • How about flinga boards or similar tools?

    +
      +
    • My take is that the simplicity of a simple text document wins over free-form in-person-workshop-like tools.

    • +
    • There’s miro, can be a bit confusing though

    • +
    +
  • +
  • How does this work with small groups, e.g. 10-15 people?

    +
      +
    • Good question: it can be hard if people aren’t rigorous about it, people start only using chat/voice. So there seems to be some lower bound in size but we haven’t tested this much

    • +
    • And if the instructors never screenshare it to show what goes on it, then seems to be less used.

    • +
    • And if there aren’t other people to read/answer it during the session (perhaps less likely in a small course), it seems to be less used.

    • +
    +
  • +
+
+

Breakoutrooms until xx:55

+

Exercise/discussion: https://coderefinery.github.io/train-the-trainer/collaborative-notes/#exercise

+
+
    +
  • Breakout room 1:

    +
      +
    • Use of etherpad for collaborative discussion.

    • +
    • Use of slido for polling and quizzing.

    • +
    • Presemo as a slido alternative (https://www.aalto.fi/en/services/presemo-a-fully-web-based-classroom-participation-system)

    • +
    • Use of text based approach for questions rather than live can be helpful if there is a language barrier issue.

    • +
    +
      +
    • A good teaching session which had many questions coming spontaneously to the teacher is a non-entity of sorts. If the overall flow of feedback / questions increases it could indicate that the session will not prove to be a helpful experience. A signal that generates noise is, well, noise, if calling a spade a spade signals anything. Note that the ‘overall’ bit and the ‘to the teacher’ aspect are important. Both the best and the worst teaching session have two things in common: a teacher, and the fact that NO Materials of any kind are used, ie speech is the only channel of communication via a common language. The only difference is that it is not the same teacher, at least not in the same session at the same time.

    • +
    +

    Another less mentioned, but perhaps more relevant indicator of a great session is the simple fact that at the end of the session EVERYONE feels empowered, NOT tired. This is not an easy to quantify thing, but screams out the quality of the experience loud. More often then not, such sessions differ little from each other, apart from in terms of the theme / topic and the participant mix. It ends up being the ‘keep your cake and eat it too,’ of sorts, not quite the far less amusing post-bombardment devastation scenario in the wake of a take it or leave it go at anything.

    +
      +
    • profanity in collaborative documents where people can add content anonymously could be a problem (happens very rarely, fortunately and somewhat surprisingly)

    • +
    +
  • +
  • Breakout Room 2:

    +
      +
    • Good experiences with Zoom polls

    • +
    • Handling questions in hybrid setups: all participants (on-site and online) ask questions in written form

    • +
    • Collaborative notes can be challenging when conducting a course alone (without teaching assistants) :+1:

    • +
    • Providing a method to ask questions anonymously can make asking easier for shy participants

    • +
    • Questions can give valuable feedback on how the course is going

    • +
    • Online collaborative whiteboarding platforms such as Miro

      +
        +
      • Large monitors are useful for this not to have to drag a “periscope” around

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • good experience with whatsapp chat for questions. since most learners have the app already and one thing less to install and set up

      +
        +
      • reply to question is a way to handle multiple questions at the same time but it works well for smaller groups

      • +
      +
    • +
    • experience with collaborative docs in in-person workshops: voice questions might “win” over the document

    • +
    • “seeding” questions may help to not have an empty document

    • +
    • it can help somebody to start and create a structure which helps others to see and follow

    • +
    • we discussed the Carpentries sticky notes system (red sticky note: signal tech issues and use for feedback, green sticky note: signal that exercise worked and for positive feedback)

      +
        +
      • Nice summary of sticky notes system: https://teachtogether.tech/en/#s:classroom-sticky-notes :+1:

      • +
      +
    • +
    • What is the success rate of in-person workshops after COVID? Discussion: Teachers prefer in person and learners prefer remote or recorded to spool back and relearn.

    • +
    +
  • +
  • Room 5

    +
      +
    • Good experience with Collaborative tools as HackMD and HedgeDoc while teaching with no bad feedback

      +
        +
      • When used with smaller groups works best as one-way, like sharing links with students and so on

      • +
      • Needs to be done as a team, quite difficult if teaching alone

      • +
      • Most useful when online/hybrid

      • +
      +
    • +
    • Anonymisity is important for transparent feedback and no biasis in classrooms

    • +
    • Not very collaborative but useful to share history or jupyter notebooks live https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush

    • +
    • Used Flinga before that seems like Figma and also onsite teaching using sticky notes

      +
        +
      • There’s miro.com but can be a bit confusing, more for brainstorming than for teaching

      • +
      +
    • +
    • Using quizzes apps like Kahoot is beneficial while teaching to have more engaging students

    • +
    • +
    +
  • +
  • Room 6

    +
      +
    • teaching teenagers (in presence) but using shared pad becomes quickly very chaotic, so only usable for short moments when answering very precise questions

      +
        +
      • Yeah, I can imagine. For CR we try to keep it in this very limited format (all questions bullet points, only add to the end) and I think that helps.

      • +
      +
    • +
    • using shared notepad for small workshop (5-10 people) to explore common thematic (mainly technical) to keep a shared notes and condense aftwerward (and publish on wiki to archive)

    • +
    • Difference between teaching in person and online. Some people prefer in-person and sometimes you have no option but to organise it online.

    • +
    • There are sometimes cultural differences and learners feel shy to ask / question the knowledge of the Teacher, so shared notes are a good way to safely ask questions.

    • +
    +
  • +
+

Questions continue:

+
    +
  • Have we demonstrated how we do polls in HedgeDoc? Add your vote by adding an o

    +
      +
    • yes: oooo (in session 1)

    • +
    • no:

    • +
    • :smile:

    • +
    • not sure: o

    • +
    +
  • +
+
+
+

Episode 3: One workshop, many perspectives

+

Materials: https://coderefinery.github.io/train-the-trainer/overview/ +Next CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/

+
+

Exercise until xx:39

+

https://coderefinery.github.io/train-the-trainer/overview/#discussion

+
+
    +
  • Room 1

    +
      +
    • Send pre-workshop email with pre-requisite instructions on what should be set-up beforehand.

      +
        +
      • But, also mention that if help is needed for set-up, we will be ready before the session officially starts.

      • +
      +
    • +
    • Discussion on whether we push to work in a pre-ready environment (e.g. Binder, Colab) or in their own environment.

    • +
    • Lots of help needed both before and after.

    • +
    • Installations: as much as we can provide ready made environments for the learners, maybe installations will be something that the learners will face sooner or later. Maybe one should teach more about installations?

    • +
    • My only cherished role in a teaching-learning session is the that of one who is living the moment as if there were no tomorrow. What cuts all ways really is that “By failing to prepare, you are preparing to fail.” ― Benjamin Franklin. A helpful motto: “When one teaches, two learn.” — Robert Heinlein. The best experience cannot be given, it can only be allowed to flow its way, so get out of its way.

    • +
    +
  • +
  • Room 2

    +
      +
    • Frequently, a single person fills all the roles for a single or multi-day workshop

    • +
    • Collaboration with different centers/ universities can be challenging

    • +
    • Preparing participants: it’s essential for the instructor to go through the demos and be sure that they will work (no unpleasant surprises live). This can be extended to advance-prep for participants.

    • +
    • Best experience is to hear (live or in feedback notes) some positive things directed at you :)

    • +
    • Fully prepared environments (eg self-hosted JupyterHub) can make preparation for participants easy

    • +
    +
  • +
  • Room 3

    +
      +
    • Some students have problems with setuping the environment. Maybe having a step by step instructions could help. But some students don’t want to “start” the course before hand.

    • +
    • Preparing the environemnt before hand ensures everyone is onboard from day 1. The same thing happend in CSC training sessions and another session Peng attended.

    • +
    • Had experience in attending as teacher and student in previous workshops

    • +
    +
  • +
  • Room 4

    +
      +
    • knowing the background of the audience is helpful

      +
        +
      • Try and ask in advance of the background of the audience. Do a poll at the start of the workshop. In person one can do it interactive.

      • +
      +
    • +
    • among co-instructors: discuss topics and flow

    • +
    • if more people are involved, it can help changing roles from time to time to see different perspectives

    • +
    • preparation is key

    • +
    • Circulate instructions beforehand

      +
        +
      • Do a poll before session: Have you installed (QGIS) successfully?

      • +
      • Push hard to do this in the welcome email

      • +
      +
    • +
    • communicate clearly to the participants

    • +
    • +
    +
  • +
  • Room 5

    +
      +
    • We’ve all taken most roles

    • +
    • How to prepare in advance?

      +
        +
      • Meet and discuss once or twice

      • +
      • Make a pre-survey to check for interest and background

      • +
      • Going through the materials

      • +
      • Checking the toolkit (zoom)

      • +
      • Agree on the reponsibilities and back-up plans (bit of scenarios planning)

      • +
      +
    • +
    • How to prepare trainings in advance?

      +
        +
      • Collect resources and prepare the workshop plan

      • +
      • Having the material readily available online ans sharing it

      • +
      • Making a pre-survey

      • +
      +
    • +
    • What was the best workshop experience for you as learner, helper or instructor? What made it great?

      +
        +
      • learner

        +
          +
        • Engaging and practical workshop with more exercices and follow-up theoretical part explanations

        • +
        +
      • +
      • helper

        +
          +
        • When the instructor is well prepared and as helper ther’s only typos to fix and interesting questions to answer

        • +
        • Assist the instructor, coordinate the collaborative notes, and make sure that the time is respected

        • +
        +
      • +
      • instructor

        +
          +
        • I have a colleague whom I’ve ran the same workshop a few times already, goes quite smoothly now and we’ve made a few changes. Hard to reach that point with new colleagues but getting there

        • +
        • Students/participants were engaging with the material and many good feedback collected even some of them asked for the next workshop

        • +
        +
      • +
      +
    • +
    +
  • +
  • Room 6

    +
      +
    • What has made a great experience for you as a learner/helper/instructor?

    • +
    • Common ground between learners & teachers

      +
    • +
    • Motivation

      +
        +
      • Teaching is much more enjoyable when the learners want to be there

      • +
      • I spend a lot of time at the start of a workshop making sure learners feel that the content is possible for them to understand and master

      • +
      +
    • +
    +
  • +
+

Poll: I have joined a CodeRefinery workshop before: (add an o for your answer)

+
    +
  • yes (within last 2 years): ooooooo

  • +
  • yes (longer time ago): oo

  • +
  • no: oooooooo

  • +
  • +
+

(questions would continue below:)

+
    +
  • What is the motivation / advantages of streaming workshop versus using zoom?

    +
      +
    • We’ll cover this more in week 4, but roughly: zoom became unmanageable and essentially quiet once things got big. Streaming allowed “one to many” communication with no limit, and collab notes allowed better interaction anyway. By separating the rooms, it was more pleasant to teach. Videos could be released immediately since there was no risk of privacy of participants. There could still be in-person/online small groups who have “watching parties.”

    • +
    +
  • +
  • What are the blue red and green font colors here, does it symbolify anything or just a convention HedgeDoc uses?

    +
      +
    • Visual separation of formatting, mostly. (It helps to quickly realize you’ve missed/ mistyped a control Markdown symbol etc.)

    • +
    • Yeah, it’s bascically “code highlighting” for markdown. No special meaning but quite convenient for us.

    • +
    +
  • +
  • Is this next workshop only for team leads or also open for helpers and coordinators?

    +
      +
    • You mean the next session of this workshop or the upcoming “CodeRefinery workshop”(this one: https://coderefinery.github.io/2024-09-10-workshop/)?

      +
        +
      • The upcoming workshop coordinators are alredy working, but can be joined if you are interested

      • +
      • As helper roles we currently only have “collaborative notes helper”, which is all about helping to answer questions in the collaborative notes

      • +
      • We do have some co-teaching slots open :)

      • +
      • If interested: join the discussion in our chat: https://coderefinery.zulipchat.com/#narrow/stream/316508-coderefinery-tools-workshop/topic/Fall.202024.20CodeRefinery.20workshop

      • +
      +
    • +
    +
  • +
  • Can a person have multiple roles in a workshop as a helper and a teacher?

    +
      +
    • Yes, many teachers also contribute to the rest of the workshop by answering questions in collaborative notes. :+1:

    • +
    • Some teachers also host a local classroom in week one and do their teaching in week two of the workshop

    • +
    • Roles that do not go well together are broadcaster/director/host and instructor (goes well until there is a problem; co-teaching solves that partly)

    • +
    +
  • +
+
+
+

Episode 4: Sound

+

https://coderefinery.github.io/train-the-trainer/sound/

+
    +
  • To me, Richard is a bit quieter than the other two :+1: :+1: :+1:

    +
      +
    • to elaborate: I think that the audio coming from him is missing some mids

    • +
    • Do you have any links about this kind of evaluation and adjustment?

    • +
    +
  • +
  • Do you suggest / recommend a specific headset(s) with mounted microphone?

    +
      +
    • in our experience headsets with a microphone will almost always be better than a separate microphone sitting on the desk or in the monitor

    • +
    • +
    +
  • +
  • Speakers have different tones of voice and speaking styles, is there a recommendation or experience from CR workshops for how this is adjusted and catered to environemnts for listeners?

    +
      +
    • Yeah, people’s voices are different and we haven’t gone as far as voice training or improving.

    • +
    +
  • +
  • How to change the volume for speakers? Tried Zoom settings and system settings and didn’t help.

    +
      +
    • From linux I can use different pulsemixers pavucontrol, pulsemixer to set the gain to above 100%. I’m not sure the equivalent on other OSs but

    • +
    +
  • +
+
+
+

Exercise until xx:10 +https://coderefinery.github.io/train-the-trainer/sound/#exercises

+
+
    +
  • room 1

    +
      +
    • Practically, no typical headset is designed or can capture the technical purity of human voice within its natural environment. But one needs to understand the polar pattern of the (specific) microphone or how much of the signal will be picked up by the microphone from different directions, a sine qua non when it comes to mitigating unwanted sound sources to bleed into the signal.

    • +
    +
  • +
+

For best results, keep the right direction & distance to your (directional) mic. Usually, that’s between 15-30 cm to get get a natural sound. A microphone records everything it can, also silence, so check the headphone output BEFORE adjusting the gain, in some specific cases aim for a dry sound, ie the influence of the room or how audible the room is on the recording ! Finally, adjust the mix between dry and room sound, or change the frequency response in tandem using a compressor to reduce the dynamic range of a signal for a more consistent listening experience = the quietest parts of your signal will appear louder by reducing the loudest parts.

+

It is all about one thing and one thing only - love your voice, let people fall in love with the acoustic quality of your charm. So remember: GIGO, it matters!

+
    +
  • Room 3

    +
      +
    • Had different headsets and we could see the difference (bluetooth low quality)

    • +
    • How to change the volume?

      +
        +
      • It’s surprisingly hard to get more control than the basic slider you see in the apps! You need to look.

      • +
      +
    • +
    +
  • +
  • room 4

    +
      +
    • headset is probably better listening experience but they can be uncomfortable to wear during long meeting days :+1:

      +
        +
      • Yeah. Luckily only instructors

      • +
      • Therefore breaks are non-negotiable

      • +
      +
    • +
    • loud keyboard can be an issue

    • +
    • if one has a silent room that does not echo, it can be ok to teach without headset

    • +
    • on Linux I am using pulsemixer to adjust levels and pavucontrol to change outputs/sources

    • +
    • mic modes on mac

    • +
    • check default microphone for zoom.

    • +
    +
  • +
  • room 5

    +
      +
    • Most tricks help tuning yourself but hard to do it as a group. Perhaps doing a short recording.

      +
        +
      • Yeah. Some independent recording/playing aronud, but also asking for advice. I would do small group/one-on-one things.

      • +
      +
    • +
    • Background noises cancellation tools or wise choice of quiet environments

    • +
    • Audio check with colleagues or through the app with the audience saying numbers for example

    • +
    • Zoom or Teams have sound checks but work different in the app than the browser. They also work different across Operating systems

    • +
    • Some sound issues might be related to network speed or stability, also to RAM available. Worthwhile to try and control those as well

    • +
    • Make it welcoming for the audience to give you feedback on the audio and other settings, give reminders

    • +
    +
  • +
+
+
+

Episode 5: How to prepare a quality screen-share

+

Materials: https://coderefinery.github.io/train-the-trainer/screenshare/

+
    +
  • If your Zoom does not support “share portion of screen”, sharing a tab and resizing it to portrait for yourself is a possible workaround (this at least works when joining the call from Chromium browser)

    +
      +
    • Another workaround is to use an editor/IDE that displays multiple panels in one window and can show a web page, code files and terminal session +10

    • +
    +
  • +
  • Is ‘share a portion of your screen’ where you draw a box in Zoom to share a section?

    +
      +
    • yes :+1:

    • +
    +
  • +
  • When using zsh, one can run something like this in a terminal

    +
    tail -n $NLASTCOMMANDS -f ~/.zsh_history | sed 's/^.............../LAST COMMAND:/g'
    +
    +
    +

    (I place this in a window under the main terminal, I use i3)

    +
  • +
  • I am a bit confused on what platform you are putting this code?

    +
      +
    • Radovan is using Linux with (I think) the “i3 window manager”. It can be quite involved and there is lots of personal customization here.

    • +
    +
  • +
  • When teaching with a custom prompt, is it worth starting with the default (that your learners will see) and explicitly mentioning “I change these things to make it clearer when teaching”

    +
      +
    • One should always comment on what may be different. Thing is “default” may look different for many people :+1:

    • +
    • “I am not going to teach you how to customise your prompt, but here’s an online tutorial, be prepared to lose several days of your life…” :laughing:

    • +
    +
  • +
  • Now I can’t see the last line in the terminal

    +
      +
    • Yep, that’s a problem. It can be good to keep a buffer on the bottom of the screen.

    • +
    • If you move your mouse outside the Zoom window, the controls should go away. But still a good note.

      +
        +
      • My mouse was on another screen.

      • +
      • Ok, thanks.

      • +
      +
    • +
    • I think one can also make the zoom bars not auto-hide (then it won’t display under), but that is annoying also since it wastes space.

    • +
    +
  • +
  • Does anybody still use shellshare? Does it work?

    +
      +
    • We in CR haven’t used it much but we have seen it.

    • +
    +
  • +
  • Does the stacking of the screens work on windows?

    +
      +
    • Don’t know unfortunately

    • +
    +
  • +
+
+

Exercises (done together) +https://coderefinery.github.io/train-the-trainer/screenshare/#exercises

+

Write your cool tips and ideas below. +Stay after xx:00, to

+
+
    +
  • To be safe, I have created on my computer an account that I use only for teaching, so I do not need to do any manual set up

  • +
  • share history or jupyter notebooks live (5-10 secs refresh rate) into a git repo. Share the link with the learners so they can catch up https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush

  • +
+
+
+
+
+

Wrapup

+
    +
  • Next session Tuesday August 27 9 CEST: About teaching & cool things we all would like to share

  • +
  • All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • Cool gems session: If you want to share something, please edit your registration and fill it in there (link to modify in registration confirmation); or e-mail to support@coderefinery.org

  • +
  • If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14:00 (Europe/Stockholm time)

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • Sound and screen share optimization as well as relevant tools and good practices for online instruction. “While you may be unable to control your users’ mindset, you can anticipate it, and make sure that your user experience caters to it.” - Jonathan Cherki

  • +
  • Nice opportunity to (re)think about my online teaching setup :+1: :+1: :+1:

  • +
  • Other ways to display command history :+1:

  • +
  • Did not know that bluetooth gear had so much latency! :+1:

  • +
  • A good reminder about headsets with microphones

  • +
  • Nice and friendly teaching. Thank you!

  • +
  • Screen share with command history and terminal customisation

  • +
  • Really useful tips on sound and screen sharing :+1:

  • +
  • Nice experience share

  • +
  • very useful and practical tips!

  • +
  • Easy to follow along and filled with useful tips on sound, video etc.

  • +
  • +
+

What one thing would you improve about this session?

+
    +
  • Just digging to find something: I have read some of the things you have talked about here already in some blog posts, so perhaps these sessions are not as shokingly full of new content as I imagined (but actually sharing experiences is something I can’t do by reading a blog post)

    +
      +
    • Perhaps: could you link some blog posts or other sources for what you have discussed so far? If it makes sense. Not sure.

    • +
    +
  • +
  • Talking about interface optimization approaches, which applies to sound as much as to visuals or any other aspect either for that matter, it might offer a perspective to bear in mind the concept of introducing asymptotic complexity increment. The latter would mean the goal is measuring how fast the effort of engaging, on one or more of the three parallel levels of interaction, must change to reach higher levels of partial certainty on the correctness of the implementation of the method in question, in this case the pedagogical paradigm. For the former, lower is better I guess, or in this case, in the intended sense, slower is faster. Let us consider an abstract example: People liked using the search engine Google (a Google session to put it in a fancy way) in the early days because it was as simple as it could get, a literally featureless entry point with no bells and whistles. That was the level of its visible complexity, or rather Google set a bar as low as it one could have, and then any higher point of VISIBLE complexity that was to be introduced, such a move would only be on the path of an asymptotic curve curving towards the set bar, never reaching it, as far as the entry point is concerned. We still see the same level of complexity when we fire up google and we never feel distracted to start with, except for the rather forgivable nuisance of the GDPR conformity pop-up notice which appears only AFTER the first move has been made, and thankfully it works plain and simple from there on (unless one starts feeling lucky, pun intended). Now, think about Youtube … the user experience complexity is a totally different matter, the same company today (unfortunately) yet one now has a steadily worsening engagement experience. Good learning sessions tend to be more of the Google search engine experience and a far cry from the current Youtube trend I would opine. Or, to sum it up and keep it sweet and simple, it helps to identify the limits of human-human and human-technology interaction, within the framework of any applicable technology-technology interaction and joy is the result of respecting those limits. Wishful thinking ?

  • +
  • Bring the cat back!

    +
      +
    • I wish it came, but it’s been resting all morning! I don’t bother it or stage apperances…

    • +
    +
  • +
  • Maybe having a digest/ summary of previous iterations of this session might be interesting. I feel a lot of experiences have been exchanged and a lot of techniques/ tools have been mentioned. Spending some time in compiling this into a selected list and adding it as content to the course itself might be worthwhile.

    +
      +
    • Good idea! We will write a blog post about this workshop and will include a summary of all discussions there :)

    • +
    +
  • +
  • Possibly have some command line examples from Windows rather than (just) *nix? I will look at the screenshots after the session. :+1: :+1:

    +
      +
    • Also, a thought if you do do breakout sessions with this work, do one for Unix, one for Windows, one for Mac as an option.

    • +
    +
  • +
  • I could not follow the part Radovan showed codes (Radovan is using Linux with (I think) the “i3 window manager”.)

  • +
  • ..

  • +
+

Any other comments?

+
    +
  • Looking forward to the topics of following sessions.

  • +
  • Looking forward to the next sessions!

  • +
  • Thank you!

  • +
  • Relax, nothing else matters, live a life and have fun ! If you obey all the rules you may end up missing all the fun. ‘The best way to predict your future is to create it.’ - Abraham Lincoln :+1:

  • +
+
+
+

Day 3 : sessiion 3 (27.08.24) - “About teaching and cool things we all would like to share”

+
+

:calendar: Schedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 9.45

Computational thinking

10.15 - 10.45

8.15 - 8.45

9.45 - 10.00

Break

10.25 - 11.00

8.25 - 9.00

10.00 - 10.30

Teaching philosophies

11.00 - 11.30

9.00 - 9.30

10.30 - 11.00

Co-teaching

11.30 - 12.00

9.30 - 10.00

11.00 - 11.15

Break

12.00 - 12.15

10.00 - 10.15

11.15 - 11.50

Sharing teaching gems (voluntary)

12.15 - 12.50

10.15 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+

:icecream: Icebreaker

+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • +
  • :sleeping:

  • +
  • :coffee:+2

  • +
  • :robot:

  • +
  • Still little sleeppy :)

  • +
  • 🥴 (:woozy_face: still not converted 🤷‍♂️)

  • +
  • Our planet could be a cube. It has six sides to it. It must be a cube. A cube it is, this Blue Planet … just wondering …

  • +
  • 🦾

  • +
  • :sweat_smile:

  • +
  • computer says no :-) some network trouble

  • +
  • running late, and participating from a :train2:

  • +
+
+
+
Introduction in breakoutrooms
+

Name / Affiliation / Location

+
+
+
Best classroom experiences
+

As a learner or teacher; what was the best workshop/lesson/seminar you have attended? What made the experience great?

+
    +
  • Room 1

    +
      +
    • First summer HPC streamed workshop (as a teacher). Somehow the first felt the best

    • +
    • CSC HPC summer workshop

    • +
    • story telling teaching approach

    • +
    +
  • +
  • Room 2

    +
      +
    • NVIDIA DLI Course on Deep Learning

      +
        +
      • very enthusiastic instructor

      • +
      • intuitive and very accessible way of showing technical details and fostering deeper understanding

      • +
      • a lot of hands-on material and smaller coding exercises

      • +
      +
    • +
    • Anything as long as its interactive and somehow enjoyable from both teacher and learner sides

    • +
    +
  • +
  • Room 4:

    +
      +
    • EPCC MPI Distributed training workshop.

      +
        +
      • Lots of hand on coding / experience gained.

      • +
      • Very interactive instructor who also discussed ideas for more personalised cases of distributed computing.

      • +
      +
    • +
    • Coderefinery RSE course

      +
        +
      • relevance of topic to my current work.

      • +
      • Dynamic / friendly / positive teaching style.

      • +
      • Modular Code Development; very instructive

      • +
      +
    • +
    • Some CSC courses / LinkedIn learning courses

      +
        +
      • up to date materials and topics.

      • +
      • Good way to merge theory with practicalities without making learner feel bored (Example: Jonathan Reichental)

      • +
      • Challenging information to learn more and research about the topic

      • +
      • Trainers are the experts in the field

      • +
      +
    • +
    +
  • +
+
+

Episode on teaching gems

+

If you want to share or demo something about tools and techniques you have found helpful in your teaching, please add your name/initials and rough topic below for smooth transition.

+
+

Note: It does not have to be your tool or your idea, this episode is meant to share experiences and discover new things. You also do not need any slides or materials, a story will do fine :) +Length of the stories will be depending on interest, but be prepared to fit it into 3 min (shortest possible).

+
+ +
+
+
+
+
+
+

:question: Questions

+
+

General / Practicalities

+
    +
  • What is this document for?

    +
      +
    • Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts)

    • +
    +
  • +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms?

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    +
  • +
+
+
+
+

Episode 1 : Computational thinking

+

Materials: https://coderefinery.github.io/train-the-trainer/computational-thinking/ (Link to slides in the middle of material)

+
+
Questions to audience
+

How might breaking down a complex problem into smaller parts change your approach to problem-solving in your current projects?

+
    +
  • Avoids cognitive overload

  • +
  • I used to give an example about this in workshops of cutting long tree into pieces from top to avoid that it falls and destroy a house bloc.

  • +
  • Easier to start on something small

  • +
  • Each individual part is familiar and can take existing solutions.

  • +
  • Only focus on the new things

  • +
  • One can lose oversight of where is supposed to be getting to due to problems with summation of biases introduced during the solving of the parts.

  • +
  • .

  • +
+

Can you think of a research project where identifying patterns in your data led to new insights or breakthroughs?

+
    +
  • Multi-targeted drug design where you need to identify both chemical and biological pathways/patterns

  • +
  • Distilling complex physics problems into simpler 1D statistics is very often done.

  • +
  • I used to do bioinformatics, pretty much everything in biology is about patterns in strings of charachters (DNA, proteins). Finding those patterns and using them is the way to go

  • +
  • Pattern recognition DOES NOT lead to new insight, it is new insight which allows for the recognition of a ‘pattern’, the latter being an allocation of possible bias.

  • +
  • +
  • ..

  • +
+

What challenges do you face when trying to simplify complex concepts in your field, and how do you decide which details to focus on?

+
    +
  • Absence of a terminology / jargon to describe a new idea. :+1:

  • +
  • Similar to above, when teaching often students know what they want to achive, but don’t have the termonology to express it, so working through what they want is helpful, after teaching them some termonology.

  • +
  • Whatever is most useful to the learner first?

  • +
  • I work with researchers in different fields. I don’t always fully understand their domain knowledge but I can take the basiscs or generalities and get code that works for them

  • +
  • A very practical problem is trying to resist going for a coffee in the midst of taking a shot at a complex concept, in the hope that the true details are to be found in the coffee.

  • +
  • not all information is easy to find or a lot of conflicting information or even sometimes imformation explosion

  • +
+

How do you determine the priority of tasks when designing algorithms for your academic projects, and what criteria do you use to ensure that the most critical tasks are addressed first?

+
    +
  • Working chronologically when going through a problem - start at the beginning.

  • +
  • What gives the more insight with the least effort can be a nice start

  • +
  • Talk to colleagues and Subject matter experts to understand various perspective to decide and prioritize.

  • +
  • Logic will get you from A to B. Imagination will take you everywhere. - Albert Einstein.

  • +
  • ..

  • +
+
+
+
Questions from the audience
+
    +
  • About the 4 core concepts, is this based on the model of how human brain works and perceives vision / abstract ideas?

  • +
  • I don’t know if it’s based on how the brain works, but it’s related to creating a framework for solving programming programs that has been extrapolated to solve any other problem as well.

  • +
  • Devil’s advocate question: cooking (by recipe) actually employs all four principles outlined here and has done so since before the advent of computers. Why then is this concept presented as “computational”?

    +
      +
    • Random aside, this is an interesting connection to our “cooking metaphor to HPC”

    • +
    +
  • +
  • Devil’s answer to the Devil’s advocate: Great question, cooking, as far as the act happens in the Devil’s kitchen, does not employ numerical algorithms. The Devil introduced the computer precisely to make man lose apetite for that what is cooked in the Devil’s kitchen to be served to all. Only then can the Devil eat the cake and keep it too …

    +
      +
    • Well, an algorithm without numbers is still an algorithm, i.e. a set of rules :)

    • +
    +
  • +
  • Are there other names for this technique? I may have missed something crucial, but it strikes me as ‘logical thinking’ in a way.

    +
      +
    • Yes, you could also just see it as problem solving. Most people know how to do it and if you’ve worked with programming, you’ve probably applied it. It can be the case that it’s very obvious to some, but not to others.

    • +
    +
  • +
  • Any chance we can ge a link to the slides?

    +
      +
    • They are in the course material: https://coderefinery.github.io/train-the-trainer/computational-thinking/ :thumbs_up:

    • +
    +
  • +
+
+
+
Exercise questions to discuss
+
    +
  1. Conceptually would the strategies provided by computational thinking help you in completing tasks more efficiently?

  2. +
+
    +
  • Room 1:

    +
      +
    • divide and conquer technique

    • +
    • We discussed what happens if you don’t use these, since they are so natural

    • +
    +
  • +
  • Room 2:

    +
      +
    • in some cases yes, if the task is not too small

    • +
    • not sure if more efficiently but it does help at least getting strted

    • +
    • Computational thinking is an extension of what others have called solutionism: the belief that any given problem can be solved by the application of computation. Whatever the practical or social problem we face, there is an app for it. - James Bridle

    • +
    +
  • +
  • Room 3:

    +
      +
    • Helps in starting the task.

    • +
    • For many it is the normal way to do problem solving. Also in Agile & Scrum methodlogies.

    • +
    +
  • +
  • Room 4:

    +
      +
    • Yes, it helped me during my scientific research to manage multiple projects and research publications simultaneously.

    • +
    • +
    +
  • +
+
    +
  1. Do you think that the effectiveness of computational thinking depends on the person’s personality type?

  2. +
+
    +
  • Room 1:

    +
      +
    • yes, we agree it’s quite different. But good vision and motivation this can be effective

    • +
    +
  • +
  • Room 2:

    +
      +
    • yes, laying out all the steps necessary to achieve an overall goal can be very daunting; some people are not good at/ comfortable with following fine-grained instructions

    • +
    • once the problem is broken down, different personalities might choose different ways to tackle the parts

    • +
    • The degree to which something, that is a result of what one means by ‘Computational Thinking,’ is successful in producing a desired result, that is success, cannot be a function of personality.

    • +
    +
  • +
  • Room 3:

    +
      +
    • Yes. Different people have different ways to communicate.

    • +
    • Online tools vs pen and paper

    • +
    +
  • +
  • Room 4:

    +
      +
    • We are all agree that it depends on the personality type but it could be learned and trained

    • +
    +
  • +
+
    +
  1. Would this type of thinking be an option for you to integrate into your current workflow?

  2. +
+
    +
  • Room 1:

    +
      +
    • Yes; we didn’t know the name explicitly; but we use it

    • +
    • It’s quite important for

    • +
    +
  • +
  • Room 2:

    +
      +
    • I’m already doing it implicitly :smile: :+1: :+1:

    • +
    • Writing a program is like writing a song, its all about the tune, lyrics are merely the necessary nuisance a coder needs to put up with. The latter can, if so written, result in a lot of noise.

    • +
    +
  • +
  • Room 3:

    +
      +
    • Easy if you are working alone. But different team may have their own ways of working (inertia). One way would be then to gradually show the rest of the team its effectiveness.

    • +
    • https://teamtopologies.com/key-concepts

    • +
    +
  • +
  • Room 4:

    +
      +
    • We are using it in our daily life so it’s already an option for us, only the terminologies are a bit new.

    • +
    +
  • +
+
+
+
+

Episode 2 : Teaching philosophies

+

Materials: https://coderefinery.github.io/train-the-trainer/teaching-philosophies/

+

Questions to discuss:

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+

Breakout Room exercise

+
    +
  • Room1

    +
      +
    • Motivation

      +
        +
      • For best practices in teaching, learning from each other, collaboration

      • +
      +
    • +
    • Learning applied tech is like an apprecentiship: there is theory, but real learning happens by co-working with others.

    • +
    • Worse is better: teach what can be used more quickly and it can be improved later

    • +
    • +
    • I think there are two bits of teaching - teach the basics and terminology so people know what they want to know, and then teaching how to find out how to do things like Richard said - how to find answers yourself.

    • +
    • Using Jupyter notebooks - good for learning a technique, but not for learning the basics.

    • +
    • Possibly command line usage has a branding problem - “programming other programs”?

    • +
    • the skills we learn in CR training are expected to stay , it is not exam oriented

    • +
    +
  • +
  • Room 2

    +
      +
    • State objectives clearly and repeat them a few times

    • +
    • Try to keep it informal, interactive, flexible

    • +
    • Helps when having practical tasks in mind for the materials taught

    • +
    • Leave some reasoning to the learner, not always giving full answers

      +
        +
      • How to deal with frustration though: try some personal approaches, more clues…

      • +
      +
    • +
    • The mediocre teacher tells. The good teacher explains. The superior teacher demonstrates. The great teacher inspires. — William Arthur Ward

    • +
    • Teaching kids to count is fine, but teaching them what counts is best. –Bob Talbert

    • +
    +
  • +
  • Room 4

    +
      +
    • Question 1: What is your motivation for taking this training?

      +
        +
      • Currently do instruction, wanting to improve as an instructor and helper when conducting software carpentries.

      • +
      • Planning to start some side hustles providing online courses and why not joining the CR in the near future

      • +
      +
    • +
    • Question 2: How structured or informal are your own teaching needs?

      +
        +
      • More recently, follow software carpentries, but look into what aspects can be tailored to keep to different time slots.

      • +
      • I used to be more informal in the past, repetetive practice sessions. Would like to be more structured given the teaching tools.

      • +
      • I’ve done life-coaching and some teaching but I feel i’m both of them

      • +
      +
    • +
    • Question 3: What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

      +
        +
      • Smaller size, and more targetted.

      • +
      • Collaborative tools and targeted audience working with small groups

      • +
      • Academic probably focuses on an audience with a more focused/narrow background, while this style encompasses a wider audience.

      • +
      • Academic teaching keeps theory and practical lab sessions very separate, whereas carpentries combine both.

      • +
      +
    • +
    • Question 4: What other skills need to be taught, but academic teaching isn’t the right setting?

      +
        +
      • Public speaking, collaborative meeting skills

      • +
      • Industrial cases and related work skills

      • +
      +
    • +
    +
  • +
+
+
+

Episode 3: Co-teaching

+

Materials: https://coderefinery.github.io/train-the-trainer/co-teaching/

+
    +
  • In general: Co-teaching is a beast with at least two personalities each of which

    +
      +
    • demand higher preparation requirements

    • +
    • face remarkable complexity in terms of coteacher coordination

    • +
    • in the virtual component face shortcomings related to the technical equipment and the failure of the human factor

    • +
    +
  • +
+
    +
  • Co-teaching requires the framework of co-operative learning. Team teaching does not by default translate into parallel learning, and vice versa.

  • +
+
    +
  • Re: CodeRefinery in-person beginnings – I agree with the “didn’t work so well in-person”, I’m not sure if it’s that we weren’t as ready for it, or that the different characteristics made it not work so much

  • +
  • How do the downsides compare to a single instructor monologuing?

    +
      +
    • That’s a great question! The main difference is that a single instructor can teach himself to be good (i.e. not just boring monologuing) alone, while for teams of 2+ to work well, everyone needs to be baseline-competent. So the effort to avoid downsides gets reduced if (and only if) all team members share it.

    • +
    +
  • +
+
+

Exercise/Discussion: https://coderefinery.github.io/train-the-trainer/co-teaching/#exercise

+

Questions:

+
    +
  • Have you already tried this or similar model in your teaching?

  • +
  • Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best?

  • +
  • Have you tried or seen a different model for two instructors to present? Please share with us how it works.

  • +
+
+
    +
  • room 1

    +
      +
    • We have tendend to do presenter/interviewer more

    • +
    • challenges are co-teaching with different personalities

    • +
    +
  • +
  • room 2

    +
      +
    • Main challenge: finding enough personell :smile:

    • +
    • It’s not always possible/feasible to have colleagues co-teaching

    • +
    • A combination of both, but presenter and interviewer could be difficult to plan an to follow

    • +
    • Guide and demo-giver with technical / non-technical roles could be nice

      +
        +
      • How to plan the guide and demo-giver

        +
          +
        • First guide, then demo

        • +
        • Demo, then guide describes

        • +
        +
      • +
      +
    • +
    • Alternative model: main presenter + ‘technical expert’

      +
        +
      • main presenter introduces concepts from a birdseye view and passes on to the technical expert for additional details, experiences and answers to questions from the audience

      • +
      +
    • +
    • We frequently do a classical division: on person in presenting, one or more are answering questions in the chat; there is rarely any interaction between them however

    • +
    +
  • +
+
    +
  • As has been pointed out by Paolo Freire, in general, ‘education is suffering from narration sickness’ … ‘The outstanding characteristic of this narrative education, then, is the sonority of words, not their transforming power’. Perhaps one approach could be to rephrase the question after having the answer: It is not apriori about the model implemented, it is about whether that what was implemented was judged aposteriori to have succeeded in becoming, or at least could pretend to have done so, the intended context matched model implementation it probably was computed to be.

  • +
+
    +
  • room 4

    +
      +
    • the co-teaching approach does not seem to be widely practiced

    • +
    • it can be interesting to see “mistakes” which are less likely to happen in solo-teaching?

    • +
    • co-teaching can be nicer for audience but maybe more stress/anxiety for instructors to prepare? more stress in terms of not knowing all the questions in advance. less stress worrying about forgetting something.

    • +
    +
  • +
+
+
+

Teaching gems

+

(scroll up to find the green box “Episode on teaching gems”)

+

What’s your favorite way of teaching? Any nice tools you use?

+

Has anyone found a nice online tool to draw?

+
    +
  • I love this tool suite https://excalideck.com/

    +
      +
    • For drawing https://excalidraw.com/

    • +
    +
  • +
  • I have seen Miro …

  • +
  • I think the Code Refineries use something for their graphics that looks a bit ‘cartoony’ - but I cannot remember what it is called!

    +
      +
    • Drawn on remarkable and then coloured and tidied up in Inkscape. :+1:

    • +
    +
  • +
  • I am a big fan of remarkable. I think sharing option is fairly good. Unfortunately bit expensive tool.

    +
      +
    • true, for me it was worth it already for the pdf annotation for research papers, cannot read on computer screen

    • +
    +
  • +
  • https://webwhiteboard.com/

  • +
  • https://www.youtube.com/watch?v=4-l8MY5kYGc

  • +
  • Figma and Kahoot are useful as well

  • +
+

Screenkey: Screenkey for showing keyboard shortcuts

+
    +
  • Is there a Windows version people can recommend?

    +
      +
    • I found this list of alternative for windows users like me: https://alternativeto.net/software/screenkey/ :+1:

    • +
    +
  • +
  • I sometimes use the on-screen keyboard already provided by the OS :+1:

  • +
+
+
+
+

Wrapup

+
    +
  • Next session Tuesday September 3rd 9 CEST: About teaching & cool things we all would like to share

  • +
  • All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14 CEST

  • +
  • Preparations for next week will be sent out by e-mail

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • The co-teaching lesson and experiences from others

  • +
  • Discussions were quite good, had a nice group

  • +
  • Breakout rooms and collaborative tools

  • +
  • Computational thinking and co-teaching are interesting ideas! I have seen it before, but never knew or even recognized it was a method.

  • +
  • Thanks for group discussions working with my chat only interaction! :smile:

  • +
  • ..

  • +
+

What one thing would you improve about this session?

+
    +
  • Minor point - it would be useful to have the teaching gmes box at the bottom of the document rather than the top - tricky to scroll between! In the end I opened two windows which was easier.

    +
      +
    • Thanks, yes agree. Also had that problem, but did not want to move it in between.

    • +
    +
  • +
  • The meaning of teaching “philosophy” wasn’t very clear, felt more like teaching “styles”

    +
      +
    • Thank you, we will take that into consideration

    • +
    +
  • +
  • Some prepared slides to present for an intro about the topics

    +
      +
    • You mean in addition to the materials? To use in the beginning of each session?

    • +
    +
  • +
  • The instructor views segment could be named as additional material, if it was not meant to be discussed within the course.

    +
      +
    • Thank you, we will take that into consideration

    • +
    +
  • +
+

Any other comments?

+
    +
  • Keeping it short and sweet: If at first you don’t succeed in teaching, try to explain it like you’re talking to a room full of cats. Caveat: In a room full of computational thinkers maybe if you tell students that the brain is a computational device that is forbidden, they might get excited and start using it.

  • +
+
+
+

Day4: Session 4 (3.09.24) - Streaming and video editing

+
+

:calendar: Schedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 10.00

Why we stream & Behind the scenes

10.15 - 11.00

8.15 - 9.00

10.00 - 10.15

Break

11.00 - 11.15

9.00 - 9.15

10.15 - 10.35

Video Editing

11.15 - 11.35

9.15 - 9.35

10.35 - 10.55

Exercise: Video Editing

11.35 - 11.55

9.35 - 9.55

10.55 - 11.10

Break

11.55 - 12.10

9.55 - 10.10

11.10 - 11.30

Open Broadcaster Software(OBS) introduction

12.10 - 12.30

10.10 - 10.30

11:30 - 11:50

OBS setup & what next

12.30 - 12.50

10.30 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+

:icecream: Icebreaker

+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :coffee: +

  • +
  • :runner:

  • +
  • :tired_face: Tired!

  • +
  • :nerd_face:

  • +
  • +
  • :cloud: :tea:

  • +
+
+
+
Introduction in breakoutrooms
+
    +
  • Name / Affiliation / Location

  • +
+

What’s the most number of people you have taught to?

+
    +
  • 20 at a time, with 1 asleep, 2 fidgiting with some silly device and the rest were… well… staring at their good luck… straight ahead it was of course, right before them.

  • +
  • ~35

  • +
  • ~80 in a lecture in a previous (lecturer) role, 26 in a training course setting

  • +
  • ~30

  • +
  • ~50 in training spaces and more than 100 for public audience talk

  • +
  • 35 (software carpentry)

  • +
  • CodeRefinery answer: The biggest ones are maybe 200-300 people. “small” for a stream is ~100 people.

  • +
+

What’s the most number of people you have taught with?

+
    +
  • 5 or so

  • +
  • 2 or 3 in total

  • +
  • 3, as in three, none of them smiling. I wish I could figure out why… it was such fun really…

  • +
  • 7

  • +
  • 2 or 3

  • +
  • 3 (helpers, not really co-teaching)

  • +
  • CodeRefinery answer: our biggest workshops are something like 10-20 people helping out in many different roles.

  • +
+

How can you divide teaching into separate independent tasks?

+
    +
  • By content blocks, having roles like main and assistant…

  • +
  • Having responsibility for different sections of the course.

  • +
  • Wow, now thats what we call a question… bravo… indeed, how does one separate sleeping and snoring into separate independent tasks…

  • +
  • Course, exercices, resources, tools and forms.

  • +
  • Different people teach different topics

  • +
  • CodeRefinery answer: the big logical blocks are instructors, in-person and breakout room helpers, and Notes-questions answers.

  • +
+

What’s the most interesting or useful thing you’ve learned from an online workshop, and how have you applied it/planning to apply in your life or work

+
    +
  • Having breaks every hour or so

  • +
  • New approach to screensharing, using the ‘portrait’ approach

  • +
  • Manage breathing: reduce stress and use silence to let the audience grasp what you’re saying

  • +
  • Well, the most interesting or useful thing I’ve learned from online workshops is how not to conduct a workshop, or at least some elements of the same, and I have applied this understanding by engaging in the global effort to discover more about how not to conduct a workshop, or at least some elements of the same, with the motto: That’s one small step for a man, one giant leap for mankind..

  • +
+
+
+
+

:question: Questions

+
+
+

Why we stream

+
    +
  • If during streaming there is no interaction between the teacher and the audience, why don’t we just record the lectures and stream them? So one can do a better job, perhaps?

    +
      +
    • Streaming it making it a “thing” that’s a group experience. It feels good to be a part of it, so we hope that encourages people to actually attend. All the mass Q&A is fun, and the audience helps to make it easier to present. Still, this is a good question.

    • +
    • I really appriciate it being “a thing”. If it was just recorded, I would say I would watch it tomorrow, and then I never would.

      +
        +
      • But then you can just fake it, and still have all the breakout rooms and collaborative document and so on. I appreciate the value of having a proper “event”.

        +
          +
        • I think I follow you, but if you pre-recorded the talking bits, then the presentors couldn’t change what they do based on the feedback in the shared document.

          +
            +
          • true, but I assumed that the teachers were too busy to actually do that. The more (less )division of labor between the teachers and the helpers (or collaborative document editors), the more (less) sense it makes to pre-record - IMHO

          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • What interaction options do ‘streamers’ use, e.g. on Twitch/YouTube (not Code Refinary)?

    +
      +
    • I’m besides chat and things that happen in chat, I’m not sure. The Notes-doc is definitely unique to us.

    • +
    +
  • +
  • Streaming is a kind of exercise for the movie star type. If you cannot be one, act like one, pretend, fool the listener into thinking you are one, take their brains and emotions under control. And if they don’t leave the session with tears of love for learning running down their chubby cheeks you know who to kick for doing a job just that bit worse than it should have been necessary.

  • +
  • Have you kept track of streming stats? like how many people logged in and stayed troughout, how many interacted?

    +
      +
    • Yes please, it would be good to see the stats

    • +
    • Here is stats repo

    • +
    • Thanks, I get a 404 error, is it private?

    • +
    • No, I don’t think so. https://github.com/coderefinery/workshop-stats

    • +
    • Still get 404. Does it work for anyone else?

      +
        +
      • Yeah I think it’s private. We need to fix this…

      • +
      +
    • +
    +
  • +
  • How big is small (10-15), medium (~30-40)?

    +
      +
    • I would say below 50 is small.

    • +
    +
  • +
  • Have you considered scaling to more events instead of to a larger audience? I mean, this seems the opposite of scaling, but this kind of content would be more useful the more often is it taught (“I need to learn GIT/Python/* in December!”)

    +
      +
    • We would, but right now we simply don’t have enough time and people to do more small events. But yes, “scheduling conflict” is a big problem - the best we can do right now is written material+videos to follow up on (and hope it’s interesting enough)

    • +
    • Python for Scientific Computing 5-7/November/2024

      +
        +
      • This was just an example. I mean, if I am a PHD student that needs to start working on a topic on Month X which happens to be inconveniently placed in the year, I will not benefit as much from having a workshop at Month X+3

        +
          +
        • The materials are open and the videos are publically available on YouTube channel

          +
            +
          • What’s the ratio of people watching videos afterwards vs people attending the event? That ratio can give an idea of the popularity of the two possible approaches.

          • +
          +
        • +
        +
      • +
      +
    • +
    • The more you scale up the less interactive the course / workshop will need to be. It then becomes a question of priorities, and if teaching is a lower priority then learning than I guess there really should be no prizes for guessing which approach should reign the airwaves.

    • +
    +
  • +
  • I guess outside Europe / Africa, time zones could be a problem?

    +
      +
    • yes, that is true

    • +
    • +
    +
  • +
  • Sorry, I might have missed this: have you been rehearsing and/or doing dry runs?

    +
      +
    • With instructors I like to try to do a dry run. I often don’t do a live broadcast dry run these days since I’m confidente enough, but when you are just starting, it’s a good idea.

    • +
    +
  • +
  • Do you always use Zoom for the ‘presenter end’ or have you tried other things? Teams? Jitsi? etc.?

    +
      +
    • we use mostly zoom

    • +
    • It was first pioneered using Jitsi. You can probably use others, too.

    • +
    +
  • +
  • A comment: for deRSE24 we have been using the GWDG streaming service and OBS, it worked quite well (with a 20s delay or so)

    +
      +
    • Cool! Yes, there is plenty of livestreaming options. Twitch+our OBS config gives us 2-3s of latency (which is low enough for live Notes interaction). You might be able to tune this if needed.

    • +
    +
  • +
+
+
+

Behind the stream

+
    +
  • Does OBS take a lot of RAM or CPU? what are the specs on your machine?

    +
      +
    • Richard have a relatively powerful computer with 8 AMD CPUs.

    • +
    • 4 CPUs are relatively enough for a good OBS setup, most important is a stable internet connection (ideally wired).

    • +
    • An extra monitor is recommended for the setup

    • +
    • See the hardware notesrecommendation here

    • +
    +
  • +
  • Do you do a screenshare from Zoom -> OBS or OBS -> Zoom?

    +
      +
    • Instructors share to Zoom, OBS captures Zoom, OBS sends to the world.

    • +
    • When I am using OBS sfor a single-person presentation recording, I go the other way: OBS captures my desktop/camera, OBS generates the preview window, and then Zoom captures and broadcasts the preview window.

    • +
    +
  • +
+
+
+

Video editing

+
+
Poll
+
    +
  • Have you tried video editing? Add ano as answer below

    +
      +
    • yes: ooooo

    • +
    • no :

    • +
    • Video editing makes all the difference. I have never known a way to avoid this sacred of steps, so to speak. In short, no recording can ever be production ready by default in the books of the wiser among the streamers. In fact, during the editing one can considerably refine and improve the learning experience in great ways. But then one would need to invest both time and effort.

    • +
    +
  • +
  • If yes Which are the tools you use?

    +
      +
    • Windows Movie Maker / ClipChamp

    • +
    • (raw stream from Zoom)

    • +
    • I think it was shotcut - I did only basic trimming

    • +
    • Kdenlive

    • +
    • Clipchamp, OpenShot, Sony Vegas

    • +
    • also ffmpeg from command line to cut beginning and end

    • +
    +
  • +
+
+
+
Questions
+
    +
  • What is Whisper?

    +
      +
    • Open-source model from OpenAI that converts speech to text transcripts.

    • +
    • this one? https://openai.com/index/whisper/

    • +
    • curious if anyone has tried it with languages other than english

    • +
    • I heard that one of my spanish colleague try it with another software. I don’t remember the tool. But with AI bloom there are many licensed tools that can do it with fifferent language

    • +
    +
  • +
  • What do you use to crop the videos?

    +
      +
    • I see now, ffmpeg

    • +
    +
  • +
  • how to merge multiple parts in one? I asked because you edited only the icebreaker part?

    +
      +
    • you can manage it in input part, see ffmpeg-editlist readme.

    • +
    +
  • +
  • Do you generate custom thumbnails for the video?

    +
      +
    • no, because of the time, but its good to have. If we had a volunteer to manage that, then we should!

    • +
    +
  • +
  • Does anyone recommend any other (GUI) tools that work well? ffmpeg is very new to me!

    +
      +
    • if you want a basic trimming and editing , you can use Quicktime player/imovies on mac

    • +
    • Clipchamp as the Microsoft video editor

    • +
    • Thanks :smile:

    • +
    +
  • +
  • How do subtitles get uploaded to YouTube?

    +
      +
    • You upload the video and subtitles as part of upload.

    • +
    • :+1:

    • +
    +
  • +
  • How does codewhisperer compare against youtube’s automatically generated subtitles?

    +
      +
    • by experience, whisper was better couple of years ago. We haven’t compared it recently

    • +
    • I guess and advantage is that you can edit whisper subtitles in case something is odd or whatever, probs cannot do that in YouTube

    • +
    +
  • +
+
+
+
+

Open Broadcaster Software (OBS) introduction & setup

+
    +
  • Are the profiles public?

    +
      +
    • Yes, you can see it here

    • +
    +
  • +
  • Does it work in Linux+Wayland?

    +
      +
    • I think everything we do with OBS would.

    • +
    +
  • +
+
+
+
+

Wrapup

+ +
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • ffmpeg seems great, will give a try for fun!

  • +
  • great to see everything in practice!

  • +
  • Very insightful to see what happens behind the scenes.

  • +
+

What one thing would you improve about this session?

+
    +
  • Some more interactivity would’ve been nice but since most the group preferred demo instead of exercise perhaps it’s only a personal opinion

  • +
  • It would have been good to share the OBS profiles repo beforehand in the setup email - so I could have had it to hand. (https://github.com/coderefinery/obs-config)

    +
      +
    • +1 good idea, we should do this next time

    • +
    +
  • +
  • Perhaps a simpler starter OBS setup?

    +
      +
    • Good idea… I should have, but basically ran out of time to prepare.

    • +
    +
  • +
+

Any other comments?

+
    +
  • Cool to see the switch from RSE to trainer to AV guy, impressive!

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/objects.inv b/branch/main/objects.inv new file mode 100644 index 0000000..cba69ae Binary files /dev/null and b/branch/main/objects.inv differ diff --git a/branch/main/obs-config/index.html b/branch/main/obs-config/index.html new file mode 100644 index 0000000..f8717f9 --- /dev/null +++ b/branch/main/obs-config/index.html @@ -0,0 +1,276 @@ + + + + + + + Open Broadcaster Software (OBS) setup — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Open Broadcaster Software (OBS) setup

+
+

Objectives

+
    +
  • See how to configure OBS using the pre-made CodeRefinery scene +collections

  • +
  • Modify the collections to suit your needs.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: ?? min

  • +
  • Hands-on: ?? min

  • +
  • Q&A: ?? min

  • +
+
+ +

In this lesson, we’ll see how to configure OBS from scratch for your +purposes. We’ll do this by deleting the instructor’s configuration +and trying to recreate it

+

This section is short, since it has never been done before: we’ll just +give it a short and update the lesson later.

+
+

CodeRefinery OBS configs

+
    +
  • CodeRefinery configs are shared in a repository: +https://github.com/coderefinery/obs-config

  • +
  • These can be imported to pre-configure some things

  • +
  • There are two types of configs:

    +
      +
    • Profiles

      +
        +
      • Servers, resolutions, audio, video, etc.

      • +
      +
    • +
    • Scene collections

      +
        +
      • The graphical layouts.

      • +
      +
    • +
    +
  • +
+
+
+

Installing the OBS config

+
    +
  • Clone the git repository.

  • +
  • Import the profile and scene collections under their respective +menus.

  • +
+
+
+

Initial setup

+
    +
  • Click through each menu and change anything that is needed

  • +
  • Set the streaming server

  • +
+
+

The instructor will go through the setup.

+
    +
  • Reset configuration: mv .config/obs-studio/ .config/obs-studio-old/

  • +
  • Import profiles/TeachingStreamingv3/

  • +
  • Import scenes/TeachingStreamingZoomv3.json

  • +
+
+
+
+

Set up the remote control

+
    +
  • Create a Python environment and install it: pip install https://github.com/coderefinery/obs-cr/archive/refs/heads/master.zip

  • +
  • Run it: python obs_cr/control.py localhost:4445 TOKEN --broadcaster

  • +
  • There are more options but let’s not cover them yet… and leave +this for a hands-on session.

  • +
+
+
+

Setup before each course

+
    +
  • Re-confirm audio

  • +
  • Re-confirm each scene

  • +
  • Test everything

  • +
  • rkdarst has a rather long +checklist, +but each individual step is short.

  • +
+
+
+

Q&A

+

We’ll answer audience questions.

+
+

Keypoints

+
    +
  • Most of our configuration has been OBS may seem complicated, but it’s a graphical application and most +pieces make sense once you know how it works.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/obs/index.html b/branch/main/obs/index.html new file mode 100644 index 0000000..205a80a --- /dev/null +++ b/branch/main/obs/index.html @@ -0,0 +1,259 @@ + + + + + + + Open Broadcaster Software (OBS) introduction — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Open Broadcaster Software (OBS) introduction

+
+

Objectives

+
    +
  • Understand that OBS is a video mixer.

  • +
  • Understand the basic controls and features of OBS.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 15 min

  • +
  • Q&A 5 min

  • +
+
+ +

In this episode, you’ll get more familiar with the OBS portion of the +streaming setup. You’ll see how it’s used, but not yet how to +configure it from scratch. You’ll learn how to be a “director”.

+
+

What is OBS?

+
    +
  • Formally “OBS Studio”

  • +
  • Most commonly known as a livestreaming application.

  • +
  • Open source, free.

  • +
  • Cross-platform, easy to use screencasting and streaming application.

  • +
  • Real-time video mixer.

  • +
+
+
+

OBS user interface

+
    +
  • We’ll click through each view.

  • +
  • What does each view do?

  • +
  • Let’s click through the buttons.

  • +
  • Let’s see the important config options.

  • +
+
+
+

OBS during a course

+
    +
  • What management is needed.

  • +
  • The control panel.

  • +
  • Audio.

  • +
  • Adjusting windows and so on.

  • +
+
+
+

Hardware requirements

+
    +
  • Reasonably powerful broadcast computer

    +
      +
    • CodeRefinerys streaming computer is 8 CPU AMD, 64GB memory

    • +
    • That is way overkill: a powerful laptop can probably do this.

    • +
    +
  • +
  • Large second monitor for laying out the windows you capture

  • +
  • Stable internet connection (wired preferable)

    +
      +
    • CodeRefinery’s broadcast is the slowest purchasable: 100 Mbit down / +25Mbit up

    • +
    +
  • +
+
+
+

Q&A

+

We’ll answer audience questions.

+
+
+

See also

+ +
+

Keypoints

+
    +
  • OBS may seem complicated, but it’s a graphical application and most +pieces make sense once you know how it works.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/overview/index.html b/branch/main/overview/index.html new file mode 100644 index 0000000..c63b95c --- /dev/null +++ b/branch/main/overview/index.html @@ -0,0 +1,418 @@ + + + + + + + A workshop seen from different perspectives — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

A workshop seen from different perspectives

+
+

Objectives

+
    +
  • Understand the general structure of CodeRefinery workshops and why it is the way it is

  • +
  • Get to know the different roles of a workshop and which ones are the most essential ones

  • +
  • Understand the importance of installation instructions and how they contribute to learners success

  • +
  • Understand the importance of onboarding and a welcoming community for volunteers in a workshop

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 15 min

  • +
  • Roles journeys can be shortened to looking only at instructor role.

  • +
+
+
+

Note

+

This episode focuses on the large scale streamed workshop setup. Some of the features can also be applied to smaller scale workshops though.

+
+
+

Discussion

+
+

Discussion

+

In breakoutrooms: choose one or two questions to talk about your own experiences; summary in collaborative notes:

+
    +
  • What kind of roles have you been in yourself regarding workshops?

  • +
  • How were you prepared for your role?

  • +
  • What are the things you would like to know before a workshop?

  • +
  • How are you preparing your participants for your trainings?

  • +
  • What was the best workshop experience for you as learner, helper or instructor? What made it great?

  • +
+
+
+
+

One workshop - many parts

+
+../_images/CR_workshop_setup.png +
+

Image showing the different phases of a CodeRefinery workshop described below. Also showing that while there is only two people teaching, many people work behind the scenes.

+
+
+
+

Before the workshop

+
    +
  • During winter/summer: “Someone” takes the coordinator role for the next workshop

  • +
  • Coordinator fills other roles:

    +
      +
    • Coordinator: collects necessary lesson updates, supports other coordinators

    • +
    • Registration coordinator: Sets up web page, starts and manages registration

    • +
    • Instructor coordinator: Finds instructors and onboards them

    • +
    • Advertising coordinator: Prepares advertizement texts and finds people to distribute them

    • +
    • Team coordinator: Gathers local organizers/teams

    • +
    • Bring your own code session coordinator: If available, offer BYOC session after main workshop

    • +
    +
  • +
  • Instructor: Onboarding with (instructor-) coordinator and previous instructor of lesson; update of lesson materials (urgent issues and personal touches)

  • +
  • Local organizer/Team lead: Group onboarding ~ week/or two before workshop

  • +
  • Learner: Gets installation instructions, invited to installation help session, workshop info from event page and summary via e-mail

  • +
  • Collaborative notes manager sets up the notes document

  • +
+
+

Note

+

Onboarding manuals

+
    +
  • Outline of what will happen during the workshop

  • +
  • Discussion of different strategies to handle the exercise sessions

  • +
  • Lowering the barrier to ask for support by meeting some organizers

  • +
  • Q&A

  • +
+
+
+

Note

+

Installation instructions

+
    +
  • Instructions for all operating systems

  • +
  • Goal: Learners leave the workshop and are ready to apply the learned tools and techniques to their own work

  • +
  • Support session for installation challenges

  • +
+
+
+
+

During the workshop

+
+../_images/BYOC.png +
+

Image showing the different ways learners can do the exercises. No matter which way they choose, they always watch the stream and interact with instructors and organizers via collaborative notes. Individual learners do the exercises alone, people in online or local classrooms in addition get to discuss with their peers.

+
+
+
    +
  • Everyone watches stream

  • +
  • Co-instructors +- Present content +- Answer questions in collaborative notes

  • +
  • Collaborative notes manager

    +
      +
    • Keeps the collaborative notes clean

    • +
    • Helps answering questions

    • +
    • Adds sections

    • +
    • Archives the document after each day

    • +
    +
  • +
  • Learners do exercises individually or in team

  • +
  • Local organizer / Team lead

    +
      +
    • Guides learners through exercises

    • +
    • Facilitates discussion

    • +
    +
  • +
  • (Registration-) coordinator sends out e-mails to participants after each day (summary + preparation)

  • +
  • Director/Broadcaster manages the streaming (see session 4)

  • +
+
+
+

After the workshop

+
    +
  • Coordinator collects lessons learned based on experience and feedback and turns them into issues

  • +
  • Coordinator organizes debriefing week after the workshop, where anyone can join to give feedback

  • +
  • “Someone” sends out post-workshop survey half a year after workshop

  • +
  • Coordinator organizes “Bring your own code” sessions

  • +
  • Broadcaster prepares and shares recording (see session 4)

  • +
+
+

Note

+

Bring your own code sessions

+

We want to support learners to apply what they have learned in the workshop to their own work by offering one/two sessions where they can drop in, and discuss challenges with CodeRefinery instructors and helpers.

+
+../_images/welcome.png +
+

Image showing a classroom learning about git leading to a discussion between student and teacher to start a welcoming environment for asking for help.

+
+
+
+
+
+
+

This sounds like a lot of people and time investment!

+
    +
  • Many roles can be combined or adjusted as needed

  • +
  • Some roles can be taken on by multiple people

  • +
+

So how many people are needed for this kind of workshop?

+
    +
  • Recommended minimum: 2-3 people

  • +
  • Optimum: ~ 4-5 people +The more people you involve, the more time goes into coordination work.

  • +
+
+
+

How did we get to this setup?

+
    +
  • Collaborative in-person workshops since 2016 around the Nordics

  • +
  • Moved online in 2020

  • +
  • Started with “traditional zoom” workshops, breakoutrooms, volunteer helpers

  • +
  • Thought about scaling and ease of joining -> current setup (More about this in session 4)

  • +
  • Continuous development

  • +
+

We also still do smaller scale local workshops, if instructors are available. +You can offer your own CodeRefinery workshop by inviting other CodeRefinery instructors. +You can also reuse single lessons and integrate them into your own teaching.

+
+
+

Workshop roles and their journeys

+
+

Individual learner journey

+
    +
  • Registration

  • +
  • Installation

  • +
  • (if appicable: Invited to local meetup)

  • +
  • Workshop

    +
      +
    • Watch stream

    • +
    • Q&A in notes

    • +
    • Exercises alone or in team

    • +
    • Daily feedback

    • +
    +
  • +
  • Debrief/ Feedback session

  • +
  • Post workshop survey

  • +
+
+
+

Instructor journey

+
    +
  • Indicate interest in CodeRefinery chat

  • +
  • Onboarding

  • +
  • Lesson material updates

  • +
  • Teaching

  • +
  • (if wished: supports answering questions in notes)

  • +
  • Debrief

  • +
+
+
+

Team lead / Local host journey

+
    +
  • Registration

  • +
  • (if applicable: run own registration)

  • +
  • Onboarding

  • +
  • Workshop

    +
      +
    • Watch stream

    • +
    • Facilitate exercises/discussions

    • +
    • Daily feedback

    • +
    +
  • +
  • Debrief / feedback / survey

  • +
+
+
+

Other roles

+

Director and broadcaster roles will be discussed in Session 4. +For more in-depth descriptions and other roles (host, instructor, registration coordinator, etc), see also our CodeRefinery manuals.

+
+
+
+

Different roles as stepping stones for community involvement

+
+../_images/steps.png +
+

Image showing a person jumping from step to step following learner, helper, expert helper, co-instructor, co-organizer.

+
+
+

There is no “one way” to get involved. Do what feels right. +Interested in teaching with us? Let us know and we can discuss what is a suitable path for you!

+
+

Keypoints

+
    +
  • CodeRefinery workshops are a collaborative effort with many different roles

  • +
  • Onboarding the different roles is one key aspect of our workshops

  • +
  • Everyone has their own path

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/screenshare/index.html b/branch/main/screenshare/index.html new file mode 100644 index 0000000..a16afec --- /dev/null +++ b/branch/main/screenshare/index.html @@ -0,0 +1,565 @@ + + + + + + + How to prepare a quality screen-share — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

How to prepare a quality screen-share

+
+

Objectives

+
    +
  • Discuss the importance of a well planned screen-share.

  • +
  • Learn how to prepare and how to test your screen-share setup.

  • +
  • Know about typical pitfalls and habits to avoid.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 15 min

  • +
  • Exercises: 15 min

  • +
+
+
+

Share portrait layout instead of sharing entire screen when teaching online

+
    +
  • Many learners will have a smaller screen than you.

  • +
  • You should plan for learners with only one small screen.

  • +
  • A learner will need to focus on both your screen share and their +work.

  • +
  • Share a portrait/vertical half of your screen (840 × 1080 is our standard and your +maximum).

  • +
  • Zoom provides a “Share a part of screen” that is good for this.

    +
      +
    • Our latest streaming setup (day 4) can take the portrait part for +you so you can share landscape.

    • +
    • Zoom + Linux + Wayland display manager doesn’t have “Share a +portion of the screen”

      +
        +
      • You can share a single window portrait.

      • +
      • Or you can start your desktop session in “X11” or “Xorg” legacy +mode.

      • +
      • Or possibly other workarounds (does anyone know other solutions?)

      • +
      +
    • +
    +
  • +
+
+../_images/landscape.png +
+

A FullHD 1920x1080 screen shared. Learners have to make this really small if +they want to have something else open.

+
+
+
+../_images/portrait.png +
+

Portrait layout. Allows learners to have something else open in the other half.

+
+
+

Motivation for portrait layout:

+
    +
  • This makes it easier for you to look at some other notes or to coordinate +with other instructors at the same time +without distracting with too much information.

  • +
  • This makes it possible for participants to have something else open in the +other screen half: terminal or browser or notebook.

  • +
+
+

Instructor perspective

+
+../_images/instructor.png +
+

I1: +This is how it can look for the instructor. Zoom is sharing a portion of the left +side, the right side is free for following notes, chat, etc.

+
+
+
+
+

Learner perspective

+

Here are three examples of how it can look for the learner.

+
+../_images/learner-large.png +
+

L1: +Learner with a large screen, Zoom in dual-monitor mode so that the instructor +pictures are not shown. Screen-share is on the left side, collaborative notes +at bottom left, terminal and web browser on the right.

+
+
+
+../_images/learner-normal.png +
+

L2: +A learner with a single large screen (Zoom in “single monitor mode”). +Instructor screen share at right, learner stuff at left.

+
+
+
+../_images/learner-small.png +
+

L3: +A learner with a particularly small screen. Instructor screen-share at left, +your windows at right.

+
+
+
+
+
+

Share the history of your commands

+

Even if you type slowly it is almost impossible to follow every command. We +all get distracted or want to read up on something or while following a command +fails on the learner laptop while instructor gets no error.

+

Add pauses and share the commands that you have typed so that one can catch up.

+

Below are some examples (some more successful than others) of sharing history +of commands.

+
+../_images/history-portrait.png +
+

H1: +A vertical screen layout shared. Note the extra shell history at the top. The +web browser is at the bottom, because the Zoom toolbar can cover the bottom +bit.

+
+
+
+../_images/history-rsh.png +
+

H2: +This isn’t a screen-share from CodeRefinery, but may be instructive. Note the +horizontal layout and shell history at the bottom right.

+
+
+
+../_images/history-landscape-dark.png +
+

H3: +Similar to above, but dark. Includes contents on the right.

+
+
+
+../_images/history-portrait-light.png +
+

H4: +Jupyter + terminal, including the fish shell and the terminal history.

+
+
+
+../_images/history-portrait-dark.png +
+

H5: +Lesson + terminal, tmux plus terminal history and dark background.

+
+
+
+../_images/portrait.png +
+

H6: +HPC Kickstart course. Note the colors contrast of the windows and colors of +the prompt and text. The history is smaller and doesn’t take up primary +working space. The working directory is in the window title bar.

+
+
+
+https://raw.githubusercontent.com/bast/history-window/main/demo.gif +
+

H7: +Show command history “picture-in-picture”, in the same terminal window.

+
+
+
+
+

How to configure history sharing

+

You need to find a way to show the recent commands you have entered, so that +learners can see the recent commands. Below are many solutions. Try them out +and see what works for you.

+
    +
  • prompt-log: +It adds a interesting idea that the command you enter is in color and also +provides terminal history before the command returns.

  • +
  • Simple: The simple way is PROMPT_COMMAND="history -a" and then +tail -f -n0 ~/.bash_history, but this doesn’t capture ssh, +sub-shells, and only shows the command after it is completed.

  • +
  • Better yet still simple: Many Software Carpentry instructors use +this script, +which sets the prompt, splits the terminal window using tmux and displays command history +in the upper panel. Requirement: tmux

  • +
  • Better (bash): This prints the output before the command is run, +instead of after. Tail with tail -f ~/demos.out.

    +
    BASH_LOG=~/demos.out
    +bash_log_commands () {
    +    # https://superuser.com/questions/175799
    +    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    +    [[ "$PROMPT_COMMAND" =~ "$BASH_COMMAND" ]] && return # don't cause a preexec for $PROMPT_COMMAND
    +    local this_command=`HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"`;
    +    echo "$this_command" >> "$BASH_LOG"
    +}
    +trap 'bash_log_commands' DEBUG
    +
    +
    +
  • +
  • Better (zsh): This works like above, with zsh. Tail with tail -f ~/demos.out.

    +
    preexec() { echo $1 >> ~/demos.out }
    +
    +
    +
  • +
  • Better (fish): This works like above, but for fish. Tail with +tail -f ~/demos.out.

    +
    function cmd_log --on-event fish_preexec ; echo "$argv" >> ~/demos.out  ; end
    +
    +
    +
  • +
  • Better (tmuxp): This will save some typing. +TmuxP is a Python program (pip install tmuxp) that gives you programmable tmux sessions. One configuration that +works (in this case for fish shell):

    +
    session_name: demo
    +windows:
    +  - window_name: demo
    +    layout: main-horizontal
    +    options:
    +      main-pane-height: 7
    +    panes:
    +      - shell_command:
    +          - touch /tmp/demo.history
    +          - tail -f /tmp/demo.history
    +      - shell_command:
    +          - function cmd_log --on-event fish_preexec ; echo "$argv" >> /tmp/demo.history  ; end
    +
    +
    +
  • +
  • Windows PowerShell: In Windows Terminal, +a split can be made by pressing CTRL+SHIFT+=. Then, in one of the splits, the following +PowerShell command will start tracking the shell history:

    +
    Get-Content (Get-PSReadlineOption).HistorySavePath -Wait
    +
    +
    +

    Unfortunately, this only shows commands after they have been executed.

    +
  • +
  • Tavatar: shell history mirroring teaching tool can copy recent history to a remote server.

  • +
  • history-window: Show command +history “picture-in-picture” when teaching command line. Requires Bash.

  • +
+
+
+

Font, colors, and prompt

+
+

Terminal color schemes

+
    +
  • Dark text on light background, not dark theme. Research and our +experience says that dark-text-on-light is better in some cases and +similar in others.

  • +
  • You might want to make the background light grey, to avoid +over-saturating people’s eyes and provide some contrast to the pure +white web browser. (this was an accessibility recommendation when +looking for ideal color schemes)

  • +
  • Do you have any yellows or reds in your prompt or program outputs? +Adjust colors if possible.

  • +
+
+
+

Font size

+
    +
  • Font should be large (a separate history terminal can have a smaller +font).

  • +
  • Be prepared to resize the terminal and font as needed. Find out +the keyboard shortcuts to do this since you will need it.

  • +
+
+
+

Prompt

+

At the beginning of the workshop your goal is to have a shell +as easy to follow as possible and as close to what learners will +see on their screens:

+
    +
  • Your prompt should be minimal: few distractions, and not take up many +columns of text.

  • +
  • prompt-log does +this for you.

  • +
  • The minimum to do is is export PS1='\$ '.

  • +
  • Blank line between entries: export PS1='\n\$ '.

  • +
  • Have a space after the $ or % or whatever prompt character you +use.

  • +
  • Strongly consider the Bash shell. This is what most new people will +use, and Bash will be less confusing to them.

  • +
  • Eliminate menu bars and any other decoration that uses valuable +screen space.

  • +
  • Add colors only if it simplifies the reading of the prompt.

  • +
+

Later in the workshop or in more advanced lessons:

+
    +
  • Using other shells and being more adventurous is OK - learners will +know what is essential to the terminal and what is extra for your +environment.

  • +
+

Try to find a good balance between:

+
    +
  • Showing a simple setup and showing a more realistic setup.

  • +
  • Showing a consistent setup among all instructors and showing a +variety of setups.

  • +
+
+
+
+

Habits we need to un-learn

+
    +
  • Do not clear the terminal. Un-learn CTRL-L or clear if possible. +More people will wonder what +just got lost than are helped by seeing a blank screen. Push +ENTER a few times instead to add some white space.

  • +
  • Do not rapidly switch between windows or navigate quickly between multiple +terminals, browser tabs, etc. This is useful during your own work when nobody +is watching, but it is very hard to follow for learners.

  • +
  • Avoid using aliases or shortcuts that are not part of the +standard setup. Learners probably don’t have them, and they will fail +if they try to follow your typing. Consider even to rename corresponding +files (.bashrc, .gitconfig, .ssh/config, .ssh/authorized_keys, .conda/*).

  • +
  • Be careful about using tab completion or reverse history search if these +haven’t been introduced yet.

  • +
+
+
+

Desktop environment and browser

+
    +
  • Try to remove window title bars if they take up lots of space +without adding value to the learner.

  • +
  • Can you easily resize your windows for adjusting during teaching?

  • +
  • Does your web browser have a way to reduce its menu bars and other +decoration size?

    +
      +
    • Firefox-based browsers: go to about:config and set +layout.css.devPixelsPerPx to a value slightly smaller than one, +like 0.75. Be careful you don’t set it too small or large since +it might be hard to recover! When you set it to something smaller +than 1, all window decorations become smaller, and you compensate +by zooming in on the website more (you can set the default zoom to +be greater than 100% to compensate). Overall, you get more +information and less distraction.

    • +
    +
  • +
+
+
+

How to switch between teaching setup and work setup?

+
    +
  • Make a dedicated “demos” profile in your terminal emulator, if +relevant. Or use a different terminal emulator just for demos.

  • +
  • Same idea for the browser: Consider using a different browser profile for +teaching/demos.

  • +
  • Another idea is to containerize the setup for teaching. +We might demonstrate this during the Sharing teaching gems session later.

  • +
+
+
+

Keypoints

+
    +
  • Share portrait layout instead of sharing entire screen

  • +
  • Adjust your prompt to make commands easy to read

  • +
  • Readability and beauty is important: adjust your setup for your audience

  • +
  • Share the history of your commands

  • +
  • Get set up a few days in advance and get feedback from someone else. +Feedback and time to improve is very important to make things clear and accessible. +10 minutes before the session starts is typically too late.

  • +
+
+
+
+

Exercises

+
+

Evaluate screen captures (20 min)

+

Evaluate screenshots on this page. Discuss the trade-offs of each one. Which +one do you prefer? Which are useful in each situation?

+

Please take notes in the collaborative document.

+
+
+

Set up your own environment (20 min)

+

Set up your screen to teach something. Get some feedback from another learner +or your exercise group.

+
+
+
+

Other resources

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/search/index.html b/branch/main/search/index.html new file mode 100644 index 0000000..a394590 --- /dev/null +++ b/branch/main/search/index.html @@ -0,0 +1,184 @@ + + + + + + Search — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/branch/main/searchindex.js b/branch/main/searchindex.js new file mode 100644 index 0000000..2d07286 --- /dev/null +++ b/branch/main/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {":calendar: Schedule": [[10, "calendar-schedule"], [10, "id1"], [10, "id9"], [10, "id17"]], ":icecream: Icebreaker": [[10, "icecream-icebreaker"], [10, "id2"], [10, "id10"], [10, "id18"]], ":question: Questions": [[10, "question-questions"], [10, "id5"], [10, "id13"], [10, "id21"]], "A workshop seen from different perspectives": [[13, null]], "About teaching": [[10, "about-teaching"]], "About the CodeRefinery project and CodeRefinery workshops in general": [[1, null]], "Accepting the smallest contribution": [[9, "discussion-0"]], "After the workshop": [[13, "after-the-workshop"]], "All CodeRefinery lessons are on GitHub": [[8, "discussion-0"]], "Alternatives": [[17, "alternatives"]], "Are there any downsides?": [[0, "are-there-any-downsides"]], "Asking questions": [[2, "asking-questions"]], "Asking questions before the workshop": [[5, "asking-questions-before-the-workshop"]], "August/September 2024": [[10, "august-september-2024"]], "August/September 2024 CodeRefinery train the trainer workshop": [[7, null]], "Balancing and dynamic adjustment": [[16, "balancing-and-dynamic-adjustment"]], "Basic controls": [[2, "basic-controls"]], "Before the workshop": [[2, "before-the-workshop"], [13, "before-the-workshop"]], "Behind the stream": [[10, "behind-the-stream"], [17, null]], "Benefits and disadvantages": [[21, "benefits-and-disadvantages"]], "Best classroom experiences": [[10, "best-classroom-experiences"]], "Better approach": [[8, "better-approach"]], "Bj\u00f8rn Lindi": [[19, "exercise-1"]], "Breakout Room exercise": [[10, "breakout-room-exercise"]], "Carpentries audience": [[1, "carpentries-audience"]], "Challenges related to defining our target audience": [[1, "discussion-1"]], "Check-in": [[10, "check-in"], [10, "id3"], [10, "id11"], [10, "id19"]], "Co-teaching": [[0, null], [0, null]], "Co-teaching and team teaching benefits": [[0, "co-teaching-and-team-teaching-benefits"]], "CodeRefinery OBS configs": [[12, "coderefinery-obs-configs"]], "CodeRefinery audience": [[1, "coderefinery-audience"]], "CodeRefinery control panel": [[17, "coderefinery-control-panel"]], "CodeRefinery lesson template": [[9, "coderefinery-lesson-template"]], "CodeRefinery teaching philosophies": [[19, null]], "Collaborative Document Manager": [[2, "collaborative-document-manager"]], "Collaborative document format example": [[2, "collaborative-document-format-example"]], "Collaborative document mechanics and controls": [[2, "collaborative-document-mechanics-and-controls"]], "Collaborative notes": [[2, null]], "Collaborative notes archives from workshops": [[10, null]], "Collecting feedback as we teach": [[5, "collecting-feedback-as-we-teach"]], "Community": [[1, "community"]], "Competent practitioners": [[1, null]], "Computational thinking": [[3, null]], "Creating new teaching material": [[8, "creating-new-teaching-material"]], "Day 2 : Session 2 (20.08.24)- Tools and techniques adopted in CodeRefinery workshops": [[10, "day-2-session-2-20-08-24-tools-and-techniques-adopted-in-coderefinery-workshops"]], "Day 3 : sessiion 3 (27.08.24) - \u201cAbout teaching and cool things we all would like to share\u201d": [[10, "day-3-sessiion-3-27-08-24-about-teaching-and-cool-things-we-all-would-like-to-share"]], "Day1: Session 1 (13.08.24) - About lesson design, deployment and iterative improvement": [[10, "day1-session-1-13-08-24-about-lesson-design-deployment-and-iterative-improvement"]], "Day4: Session 4 (3.09.24) - Streaming and video editing": [[10, "day4-session-4-3-09-24-streaming-and-video-editing"]], "Desktop environment and browser": [[14, "desktop-environment-and-browser"]], "Different roles as stepping stones for community involvement": [[13, "different-roles-as-stepping-stones-for-community-involvement"]], "Discuss how to collaborate and handle questions (15 min)": [[2, "exercise-0"]], "Discuss the models of team teaching (10 min)": [[0, "exercise-0"]], "Discussion": [[13, "discussion"], [13, "discussion-0"]], "Discussion: how to distribute this?": [[20, null]], "Discussion: what makes a video easy to edit?": [[20, null]], "Don\u2019t get overwhelmed": [[2, "don-t-get-overwhelmed"]], "During the workshop": [[13, "during-the-workshop"]], "Editing-1: Get your sample video": [[20, "exercise-1"]], "Editing-2: Run Whisper to generate raw subtitles and test video.": [[20, "exercise-0"]], "Editing-3: Create the basic editlist.yaml file": [[20, "exercise-2"]], "Editing-4: Run ffmpeg-editlist": [[20, "exercise-3"]], "Editing-5: Add more features": [[20, "exercise-4"]], "Editing-6: Subtitles": [[20, "exercise-5"], [20, "exercise-6"]], "Editing-7: Generate the final output file.": [[20, "exercise-7"]], "Episode 1 : Computational thinking": [[10, "episode-1-computational-thinking"]], "Episode 1: CodeRefinery": [[10, "episode-1-coderefinery"]], "Episode 1: Lesson design and development": [[10, "episode-1-lesson-design-and-development"]], "Episode 2 : Teaching philosophies": [[10, "episode-2-teaching-philosophies"]], "Episode 2: Collaborative Notes": [[10, "episode-2-collaborative-notes"]], "Episode 2: Lessons with version control": [[10, "episode-2-lessons-with-version-control"]], "Episode 3: Co-teaching": [[10, "episode-3-co-teaching"]], "Episode 3: How we collect feedback and measure impact": [[10, "episode-3-how-we-collect-feedback-and-measure-impact"]], "Episode 3: One workshop, many perspectives": [[10, "episode-3-one-workshop-many-perspectives"]], "Episode 4: Sound": [[10, "episode-4-sound"]], "Episode 5: How to prepare a quality screen-share": [[10, "episode-5-how-to-prepare-a-quality-screen-share"]], "Evaluate screen captures (20 min)": [[14, "exercise-0"]], "Example 1": [[5, "example-1"]], "Example 2": [[5, "example-2"]], "Example 3": [[5, "example-3"]], "Example 4": [[5, "example-4"]], "Exercise": [[0, "exercise"], [2, "exercise"]], "Exercise A": [[20, "exercise-a"]], "Exercise B": [[20, "exercise-b"]], "Exercise questions to discuss": [[10, "exercise-questions-to-discuss"]], "Exercise: Discussion about learning objectives and exercise design": [[8, "exercise-discussion-about-learning-objectives-and-exercise-design"]], "Exercise: Group discussion (10 min)": [[5, "exercise-group-discussion-10-min"]], "Exercise: How do you design your teaching material?": [[8, "exercise-how-do-you-design-your-teaching-material"]], "Exercises": [[9, "exercises"], [14, "exercises"], [16, "exercises"], [20, "exercises"]], "Feedback about todays session": [[10, "feedback-about-todays-session"], [10, "id8"], [10, "id16"], [10, "id23"]], "Feedback template": [[2, "feedback-template"]], "Font size": [[14, "font-size"]], "Font, colors, and prompt": [[14, "font-colors-and-prompt"]], "Future prospects (briefly)": [[21, "future-prospects-briefly"]], "General / Practicalities": [[10, "general-practicalities"], [10, "id6"], [10, "id14"]], "General Collaborative Document practices": [[2, "general-collaborative-document-practices"]], "Getting it set up": [[17, "getting-it-set-up"]], "Goals": [[1, "goals"]], "Great resources": [[8, "great-resources"]], "Group discussion using the collaborative notes": [[5, "exercise-0"]], "Guide and demo-giver": [[0, "guide-and-demo-giver"]], "Habits we need to un-learn": [[14, "habits-we-need-to-un-learn"]], "Hardware requirements": [[11, "hardware-requirements"]], "History": [[1, "discussion-0"], [21, "history"]], "How did we get to this setup?": [[13, "how-did-we-get-to-this-setup"]], "How scenes are controlled": [[17, "how-scenes-are-controlled"]], "How this relates to streaming": [[20, "how-this-relates-to-streaming"]], "How to configure history sharing": [[14, "how-to-configure-history-sharing"]], "How to prepare a quality screen-share": [[14, null]], "How to switch between teaching setup and work setup?": [[14, "how-to-switch-between-teaching-setup-and-work-setup"]], "How we collect feedback and measure impact": [[5, null]], "How we do it": [[20, "how-we-do-it"]], "Ice-breaker in groups (20 minutes)": [[19, "exercise-0"]], "Icebreaker questions": [[21, "icebreaker-questions"]], "Improving existing lessons": [[8, "improving-existing-lessons"]], "Individual learner journey": [[13, "individual-learner-journey"]], "Initial setup": [[12, "initial-setup"]], "Installing the OBS config": [[12, "installing-the-obs-config"]], "Instructor guide": [[6, null]], "Instructor journey": [[13, "instructor-journey"]], "Instructor note": [[0, "instructor-note-0"], [2, "instructor-note-0"], [3, "instructor-note-0"], [4, "instructor-note-0"], [5, "instructor-note-0"], [8, "instructor-note-0"], [9, "instructor-note-0"], [11, "instructor-note-0"], [12, "instructor-note-0"], [13, "instructor-note-0"], [14, "instructor-note-0"], [16, "instructor-note-0"], [17, "instructor-note-0"], [18, "instructor-note-0"], [19, "instructor-note-0"], [20, "instructor-note-0"], [21, "instructor-note-0"]], "Instructor perspective": [[14, "instructor-perspective"]], "Instructor views": [[19, "instructor-views"]], "Instructors go through the building and contributing process": [[9, "demo-0"]], "Introduction": [[2, "introduction"], [19, "introduction"]], "Introduction in breakoutrooms": [[10, "id4"], [10, "id12"], [10, "id20"]], "Introduction in breakoutrooms.": [[10, "introduction-in-breakoutrooms"]], "Keypoints": [[0, "keypoints-0"], [2, "keypoints-0"], [3, "keypoints-0"], [9, "keypoints-0"], [11, "keypoints-0"], [12, "keypoints-0"], [13, "keypoints-0"], [14, "keypoints-0"], [16, "keypoints-0"], [17, "keypoints-0"], [18, "keypoints-0"], [19, "keypoints-0"], [20, "keypoints-0"], [21, "keypoints-0"]], "Keypoints: CodeRefinery": [[1, "keypoints-0"]], "Learner perspective": [[14, "learner-perspective"]], "Lesson design and development": [[8, null]], "Lesson-VCS-1: Present and discuss your own lesson formats": [[9, "exercise-0"]], "Lesson-VCS-2: Tour a CodeRefinery or Carpentries lesson on Github": [[9, "exercise-1"]], "Lesson-VCS-3: Modify a CodeRefinery example lesson on Github": [[9, "exercise-2"]], "Lesson-VCS-4: Clone and build a CodeRefinery lesson locally": [[9, "exercise-3"]], "Lesson-VCS-5: (advanced) Create your own lesson using the CodeRefinery format": [[9, "exercise-4"]], "Lessons learned": [[5, "lessons-learned"]], "Lessons with version control": [[9, null]], "Most things to edit (everyone)": [[2, "most-things-to-edit-everyone"]], "Novices": [[1, null]], "OBS during a course": [[11, "obs-during-a-course"]], "OBS user interface": [[11, "obs-user-interface"]], "Objectives": [[0, "objectives-0"], [1, "objectives-0"], [2, "objectives-0"], [3, "objectives-0"], [4, "objectives-0"], [5, "objectives-0"], [8, "objectives-0"], [9, "objectives-0"], [11, "objectives-0"], [12, "objectives-0"], [13, "objectives-0"], [14, "objectives-0"], [16, "objectives-0"], [17, "objectives-0"], [18, "objectives-0"], [19, "objectives-0"], [20, "objectives-0"], [21, "objectives-0"]], "One workshop - many parts": [[13, "one-workshop-many-parts"]], "Open Broadcaster Software (OBS) introduction": [[11, null]], "Open Broadcaster Software (OBS) introduction & setup": [[10, "open-broadcaster-software-obs-introduction-setup"]], "Open Broadcaster Software (OBS) setup": [[12, null]], "Other resources": [[14, "other-resources"]], "Other roles": [[13, "other-roles"]], "Overview": [[0, "overview"]], "Participant preparations for each session": [[6, "participant-preparations-for-each-session"]], "Poll": [[10, "poll"]], "Posting the collaborative document to the website": [[2, "posting-the-collaborative-document-to-the-website"]], "Presenter and interviewer": [[0, "presenter-and-interviewer"]], "Primary articles": [[20, "primary-articles"]], "Privacy": [[2, "privacy"]], "Prompt": [[14, "prompt"]], "Q&A": [[11, "q-a"], [12, "q-a"], [17, "q-a"], [21, "q-a"]], "Questions": [[10, "questions"]], "Questions from the audience": [[10, "questions-from-the-audience"]], "Questions to audience": [[10, "questions-to-audience"]], "Radovan Bast": [[19, "exercise-2"]], "Recommendations": [[16, "recommendations"]], "Resources": [[7, null]], "Richard Darst": [[19, "exercise-4"]], "Sabry Razick": [[19, "exercise-3"]], "See also": [[11, "see-also"], [18, "see-also"], [20, "see-also"]], "Session 1": [[7, null]], "Session 2": [[7, null]], "Session 3": [[7, null]], "Session 4": [[7, null]], "Session 4 intro": [[15, null]], "Set up the remote control": [[12, "set-up-the-remote-control"]], "Set up your own environment (20 min)": [[14, "exercise-1"]], "Setup before each course": [[12, "setup-before-each-course"]], "Share portrait layout instead of sharing entire screen when teaching online": [[14, "share-portrait-layout-instead-of-sharing-entire-screen-when-teaching-online"]], "Share the history of your commands": [[14, "share-the-history-of-your-commands"]], "Sharing teaching gems": [[4, null]], "Solution": [[20, "solution-0"], [20, "solution-1"], [20, "solution-2"], [20, "solution-3"], [20, "solution-4"], [20, "solution-5"]], "Sound": [[16, null]], "Sound-1: Evaluate sound quality": [[16, "exercise-0"]], "Sound-2: Adjust volume up and down": [[16, "exercise-1"]], "Sound-3: Do a balance check": [[16, "exercise-2"]], "Speak up when there are problems": [[16, "speak-up-when-there-are-problems"]], "Sphinx": [[9, "sphinx"]], "Stepas Toliautas": [[19, "exercise-5"]], "Summary": [[0, "summary"], [9, "summary"], [16, "summary"], [19, "summary"], [20, "summary"]], "Take time designing your survey": [[5, "take-time-designing-your-survey"]], "Talking points for each sessions intro": [[6, "talking-points-for-each-sessions-intro"]], "Target audience": [[1, "target-audience"], [6, "target-audience"]], "Teaching": [[10, "teaching"]], "Teaching gems": [[10, "teaching-gems"]], "Team lead / Local host journey": [[13, "team-lead-local-host-journey"]], "Team teaching models": [[0, "team-teaching-models"]], "Team teaching specifics": [[0, "team-teaching-specifics"]], "Terminal color schemes": [[14, "terminal-color-schemes"]], "The importance of audio": [[16, "the-importance-of-audio"]], "The instructor will go through the setup.": [[12, "demo-0"]], "The process of designing a lesson \u201cbackwards\u201d": [[8, "the-process-of-designing-a-lesson-backwards"]], "This sounds like a lot of people and time investment!": [[13, "this-sounds-like-a-lot-of-people-and-time-investment"]], "Timing": [[6, "timing"]], "Tips for good sound quality": [[16, "tips-for-good-sound-quality"]], "Tour of lesson templates options": [[9, "tour-of-lesson-templates-options"]], "Train the trainer workshop": [[7, null]], "Trying to measure impact with longer-term surveys": [[5, "trying-to-measure-impact-with-longer-term-surveys"]], "Typical problems": [[8, "typical-problems"]], "Use case: our lessons": [[8, "use-case-our-lessons"]], "Use ffmpeg-editlist to edit this sample video": [[20, "exercise-8"]], "Video editing": [[10, "video-editing"], [20, null]], "Video recordings": [[19, "prerequisites-0"]], "We collect notes using a shared document (5 min)": [[8, "exercise-0"]], "We work in groups but use the shared document as result (20 min)": [[8, "exercise-1"]], "What can go wrong": [[17, "what-can-go-wrong"]], "What is OBS?": [[11, "what-is-obs"]], "What is streaming and recording?": [[21, "what-is-streaming-and-recording"]], "What\u2019s next?": [[18, null]], "Who does what": [[17, "who-does-what"]], "Why version control?": [[9, "why-version-control"]], "Why we stream": [[10, "why-we-stream"], [21, null]], "Window layouts": [[17, "window-layouts"]], "Workshop roles and their journeys": [[13, "workshop-roles-and-their-journeys"]], "Wrapup": [[10, "wrapup"], [10, "id7"], [10, "id15"], [10, "id22"]]}, "docnames": ["co-teaching", "coderefinery-intro", "collaborative-notes", "computational-thinking", "cool-gems", "feedback-and-impact", "guide", "index", "lesson-development", "lessons-with-git", "notes-archive", "obs", "obs-config", "overview", "screenshare", "session-4-intro", "sound", "streaming", "streaming-whats-next", "teaching-philosophies", "video-editing", "why-we-stream"], "envversion": {"sphinx": 62, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["co-teaching.md", "coderefinery-intro.md", "collaborative-notes.md", "computational-thinking.md", "cool-gems.md", "feedback-and-impact.md", "guide.md", "index.md", "lesson-development.md", "lessons-with-git.md", "notes-archive.md", "obs.md", "obs-config.md", "overview.md", "screenshare.md", "session-4-intro.md", "sound.md", "streaming.md", "streaming-whats-next.md", "teaching-philosophies.md", "video-editing.md", "why-we-stream.md"], "indexentries": {}, "objects": {}, "objnames": {}, "objtypes": {}, "terms": {"": [0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 19, 20], "0": [10, 14, 21], "00": [10, 20], "01": 2, "02": 10, "02_at_09": 10, "03": [5, 20], "03308595436e636b3bb37ed9d1f0dee39eeccd0f": 10, "04": 20, "05": [10, 20], "07": 20, "08": 5, "1": [2, 6, 14, 21], "10": [2, 3, 6, 10, 14, 16, 17, 19, 20, 21], "100": [10, 11, 14, 16, 21], "1080": 14, "11": [10, 20], "12": [5, 10, 20], "128": 10, "13": 7, "13292363": 5, "13th": 7, "14": 10, "148421550": 10, "15": [0, 6, 10, 11, 13, 14, 20], "16": 20, "17": 10, "175799": 14, "180": 19, "18640868": 10, "19": 10, "1920x1080": 14, "1d": 10, "2": [2, 6, 8, 13], "20": [2, 3, 5, 6, 7, 9, 13, 17, 20], "200": 10, "2014": [1, 8], "2015": [1, 8], "2016": [1, 8, 13], "2017": 8, "2019": 8, "2020": 13, "202024": 10, "2021": 5, "2022": [1, 8], "2023": 20, "2024": [5, 8, 15], "2025": 1, "20coderefineri": 10, "20workshop": 10, "21": 10, "23": 10, "24": 20, "25": [6, 9, 10, 20], "25mbit": 11, "26": 10, "2671576": 5, "2671578": 5, "27": 7, "2k45bftw4sbmlbfjr1oz90": 10, "3": [1, 2, 4, 6, 8, 13, 21], "30": [6, 10], "300": [10, 16], "31": 20, "316508": 10, "35": [4, 6, 8, 10, 20], "37": 20, "39": 10, "3rd": [7, 10], "4": [2, 3, 6, 13, 14], "40": 10, "404": 10, "43": 20, "4445": 12, "45": [2, 6, 10, 19, 20], "5": [0, 2, 5, 6, 11, 13, 16, 18, 21], "50": [10, 20], "500m": 16, "5281": 5, "55": 10, "5c6ecd3628a43b0cdc79815f665e224a": 10, "6": 10, "612x612": 10, "64gb": 11, "7": [10, 14], "75": 14, "7b": 10, "7b7ec4b91d2cf9d8e1b064678d205467": 10, "7e": 10, "7nhx": 19, "8": [10, 11], "80": 10, "840": 14, "9": [10, 14], "90": [6, 8], "9781119861690": 10, "A": [1, 2, 7, 8, 10, 14, 18, 19], "And": [2, 10, 16, 19, 20], "As": [2, 8, 10, 15, 16, 20], "At": [2, 14], "BY": 8, "Be": [2, 10, 14, 16, 20], "Being": 10, "But": [2, 6, 8, 10, 16, 19], "By": [1, 10, 20], "For": [0, 1, 2, 6, 8, 9, 10, 13, 19, 20, 21], "If": [2, 6, 7, 8, 9, 10, 13, 15, 16, 19, 20], "In": [0, 1, 6, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21], "It": [0, 1, 2, 6, 8, 9, 10, 14, 15, 16, 17, 19, 20], "NO": 10, "NOT": 10, "No": [5, 10, 13, 20, 21], "Not": [0, 5, 8, 10, 17], "One": [0, 1, 2, 5, 14, 16, 17], "Or": [2, 9, 10, 14], "That": [10, 11, 19], "The": [0, 1, 2, 5, 7, 9, 10, 11, 13, 14, 15, 17, 19, 20, 21], "Then": [6, 10, 14], "There": [1, 2, 6, 9, 10, 12, 13, 15, 17, 20, 21], "These": [6, 10, 12, 15, 16, 18, 20, 21], "To": [6, 10, 20], "Will": 10, "With": [10, 16, 19], "_build": 9, "_cobn": 20, "aaa": 16, "aalto": [10, 20], "aaltoscicomp": 20, "aau": 10, "abl": [2, 6, 8, 10, 16, 19, 20], "about": [0, 2, 5, 6, 7, 9, 11, 13, 14, 15, 17, 18, 19, 20, 21], "abov": [2, 5, 10, 14, 20], "abraham": 10, "absenc": 10, "absolut": 10, "abstract": [3, 10], "academ": [1, 10, 19], "academi": 10, "accept": [1, 10], "access": [8, 10, 14, 20], "accid": 20, "accident": 0, "accomd": 10, "accompani": 8, "accomplish": [2, 10], "account": [2, 6, 9, 10], "accur": 20, "achiev": [5, 10, 16, 19], "achiv": 10, "acoust": [10, 16], "acquiesc": [5, 10], "across": 10, "act": 10, "action": [5, 10], "activ": [0, 1, 8, 10, 15], "actual": [0, 1, 5, 8, 10, 19, 20, 21], "ad": [2, 10, 14], "adapt": [0, 10], "add": [0, 2, 5, 6, 9, 10, 13, 14], "addit": [0, 10, 13, 16, 19], "address": [1, 10], "adjust": [0, 2, 6, 10, 11, 13, 14, 17, 20], "adopt": 7, "advanc": [0, 2, 6, 10, 14], "advantag": [6, 8, 10], "advent": 10, "adventur": 14, "advertis": 13, "advertiz": 13, "advic": 10, "advoc": [8, 10, 20], "affili": 10, "africa": 10, "after": [2, 5, 6, 9, 10, 14, 16, 19, 20], "afternoon": 8, "afterward": [2, 10, 19], "aftwerward": 10, "against": 10, "agil": [10, 19], "ago": [10, 19], "agre": [0, 2, 10], "ah": 10, "aha": 19, "ahead": 10, "ai": 10, "aim": [1, 7, 10, 19], "airwav": 10, "al": 10, "albert": 10, "algorithm": [3, 10], "alias": 14, "align": 20, "all": [0, 1, 2, 5, 6, 7, 9, 13, 14, 16, 17, 19, 20, 21], "alloc": 10, "allow": [0, 2, 8, 9, 10, 14, 19, 20, 21], "almost": [10, 14, 19], "alon": [2, 10, 13], "along": [2, 10, 19, 20], "alreadi": [0, 1, 5, 8, 10, 19], "alredi": 10, "also": [0, 1, 2, 6, 7, 8, 9, 10, 13, 14, 15, 16, 17, 19], "altern": [0, 2, 9, 10], "alternativeto": 10, "although": 10, "alwai": [1, 2, 8, 10, 13, 19], "am": [8, 10, 16, 19], "amazingli": 8, "ambassador": 1, "ambros": 10, "amd": [10, 11], "among": [10, 14, 16], "amount": [2, 10], "amus": 10, "an": [0, 1, 2, 5, 6, 7, 8, 10, 14, 15, 16, 17, 19, 20], "analogi": 10, "analysi": 10, "analyz": 8, "ani": [1, 2, 5, 7, 10, 14, 16, 19, 20], "annoi": 10, "annot": 10, "anomali": 15, "anonym": [5, 10], "anonymis": 10, "anoth": [0, 8, 10, 14], "answer": [2, 5, 8, 10, 11, 12, 13, 19], "anticip": [0, 10], "anwser": 2, "anxieti": 10, "anybodi": [5, 10], "anymor": 19, "anyon": [2, 10, 13, 14, 20], "anyth": [2, 5, 9, 10, 12, 17, 20, 21], "anywai": 10, "anywher": 9, "apart": 10, "apetit": 10, "api": 9, "aposteriori": 10, "app": 10, "appear": [10, 19, 20], "apper": 10, "appic": 13, "appli": [0, 1, 8, 10, 13, 20], "applic": [0, 10, 11, 12, 13, 17, 19], "apprecentiship": 10, "appreci": [10, 19], "apprici": 10, "approach": [0, 1, 10, 19], "appropri": 10, "approxim": 10, "apriori": 10, "ar": [1, 2, 5, 6, 7, 9, 10, 12, 13, 14, 15, 19, 20, 21], "archiv": [2, 7, 12, 13], "area": [0, 1, 10, 20], "aren": [2, 10, 16, 20], "argument": 10, "argv": 14, "aronud": 10, "around": [10, 13], "arrang": 2, "art": 10, "arthur": 10, "articl": 10, "artifact": 16, "asc": 20, "asid": 10, "ask": [0, 8, 9, 10, 13, 15, 16, 19], "asleep": 10, "aspect": [6, 10, 13], "assess": [0, 8], "assign": [6, 10], "assist": 10, "assum": [1, 2, 5, 9, 10], "assur": 10, "asymptot": 10, "async": 21, "attempt": 9, "attend": [5, 8, 10, 20], "attent": [0, 10], "audibl": 10, "audienc": [0, 5, 7, 8, 11, 12, 14, 16, 17, 19, 20, 21], "audio": [6, 7, 10, 11, 12, 15, 20], "aug": 7, "authorized_kei": 14, "auto": 10, "autom": 8, "automat": [2, 10], "av": 10, "avail": [0, 3, 5, 9, 10, 13, 16, 19, 20], "avm": 10, "avoid": [1, 2, 5, 10, 14, 19], "awai": [2, 10, 16, 17], "awar": [1, 10, 19], "awkward": 0, "b": 10, "bachelor": 10, "back": [2, 8, 10, 19, 20], "background": [8, 10, 14, 16, 19], "backup": [2, 18], "backward": 10, "bad": [10, 16], "bake": 10, "balanc": [2, 5, 14], "band": 10, "bandwidth": 16, "bar": [10, 14], "barrier": [6, 10, 13], "bascic": 10, "base": [1, 8, 9, 10, 13, 14, 17, 20], "baselin": 10, "bash": 14, "bash_command": 14, "bash_histori": 14, "bash_log": 14, "bash_log_command": 14, "bashrc": 14, "basic": [0, 6, 8, 9, 10, 11, 15, 16, 19], "basisc": 10, "bast": 7, "bbb": 16, "beamer": 10, "bear": 10, "beast": 10, "beat": 16, "beauti": 14, "becam": 10, "becaus": [1, 5, 10, 14, 16, 19, 20], "becom": [0, 5, 7, 8, 10, 14, 19, 20], "been": [5, 6, 8, 9, 10, 12, 13, 14, 16, 18, 19, 20], "befor": [1, 6, 8, 10, 14, 19, 20], "beforehand": 10, "beggin": 10, "begin": [5, 10, 14, 19, 20], "beginn": 7, "behind": [2, 5, 6, 7, 13], "being": [0, 10, 14, 19], "belief": 10, "believ": 10, "bell": 10, "below": [0, 2, 5, 7, 9, 10, 13, 14, 16, 19, 20], "benefici": [1, 10, 19], "benefit": [9, 10, 20], "benjamin": 10, "besid": 10, "best": [0, 1, 6, 13, 19], "better": [5, 10, 14, 19], "between": [0, 2, 6, 7, 9, 10, 13, 19], "beyond": [1, 2, 6, 16], "bia": [5, 10], "bias": 10, "biasi": 10, "big": [0, 8, 10, 21], "bigger": 5, "biggest": 10, "bill": 10, "bin": 10, "binari": 19, "binder": 10, "bioinformat": 10, "biolog": 10, "biologi": 10, "birdsey": 10, "bit": [10, 14, 16, 17, 19], "bj\u00f8rn": 7, "bl": 10, "black": [10, 20], "blackbox": 10, "blank": [2, 8, 14], "bleed": 10, "blob": [6, 10, 19], "bloc": 10, "block": [8, 10, 19], "blog": [5, 8, 10], "bloom": [8, 10], "blow": 10, "blue": 10, "bluetooth": [10, 16], "blurb": 10, "board": 10, "bob": 10, "bomb": 10, "bombard": 10, "book": [8, 9, 10], "bookshop": 10, "bore": [10, 15], "bot": 10, "both": [10, 14, 19], "bother": 10, "bottom": [2, 5, 10, 14], "bound": 10, "box": [9, 10], "br": 10, "brain": [6, 10], "brainstorm": [8, 10], "branch": [8, 10], "brand": 10, "bravo": 10, "bread": 10, "break": [2, 6, 10, 16, 17, 19, 20], "breaker": 10, "breakfast": 10, "breakout": [0, 2, 20], "breakoutroom": [6, 7, 13, 19], "breakthrough": 10, "breath": 10, "bridl": 10, "brief": 6, "bring": [2, 8, 10, 13, 16], "broad": [6, 10], "broadcast": [7, 13, 17], "broaden": 19, "broken": 10, "browser": [10, 19], "bst": 10, "budget": 20, "buffer": 10, "build": [1, 6, 10], "built": [9, 10], "bullet": [2, 10, 19], "busi": [10, 19], "button": [10, 11], "byoc": 13, "c": 10, "c4": 10, "cake": 10, "calcul": 10, "call": [10, 16, 17], "came": [10, 16], "camera": [7, 10, 19], "can": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 19, 20, 21], "cancel": [10, 16], "cannot": [6, 10], "canon": 10, "capac": 10, "capic": 10, "captur": [5, 10, 11, 15], "care": [1, 14], "carpentri": [8, 10, 14, 19], "cartooni": 10, "case": [0, 1, 2, 10, 14, 19], "cat": 10, "catch": [0, 10, 14, 20], "cater": 10, "caus": 14, "caveat": 10, "cc": 8, "cell": 10, "center": 10, "centric": 19, "certain": [10, 17, 19, 21], "certainti": 10, "certif": 10, "cest": 10, "challeng": [10, 13], "chanc": [7, 10], "chang": [0, 2, 5, 6, 8, 9, 10, 12, 17, 19], "channel": [1, 10], "chao": 0, "chaotic": [0, 10], "chapter": 20, "characht": 10, "charact": 14, "characterist": 10, "charg": 7, "charm": 10, "chat": [1, 2, 6, 10, 13, 14, 16], "chatgpt": 10, "cheat": 10, "check": [2, 5, 6, 19, 20], "checklist": [10, 12], "cheek": 10, "chemic": 10, "cherish": 10, "cherki": 10, "choic": [8, 10, 20], "choos": [8, 10, 13], "chose": 10, "chromium": 10, "chronolog": 10, "chubbi": 10, "chunk": 20, "cicero": [9, 10], "circl": 10, "circul": 10, "citabl": [5, 8], "clarifi": 10, "clariti": 16, "class": 19, "classic": [0, 10], "classroom": [0, 8, 13], "clean": [10, 13], "cleanli": 20, "clear": [0, 10, 14, 19, 20], "clearer": 10, "clearli": [10, 20], "cli": 10, "click": [9, 11, 12], "client": 10, "clipchamp": 10, "clock": 10, "clone": 12, "close": [2, 5, 7, 8, 14, 16], "closer": [0, 8], "cloud": 10, "clue": 10, "clutter": 10, "cm": 10, "cmd_log": 14, "co": [1, 6, 7, 13, 19], "coach": 10, "coc": 10, "cocktail": 10, "code": [1, 5, 6, 8, 9, 10, 13, 20], "codeberg": 10, "coder": 10, "coderefineri": [0, 2, 5, 6, 11, 13, 14, 20, 21], "codewhisper": 10, "coffe": 10, "cognit": 10, "cohort": 10, "colab": 10, "collab": 10, "collabor": [0, 1, 6, 7, 8, 13, 14, 19], "collat": 10, "colleagu": [5, 8, 10], "collect": [6, 7, 12, 13, 19, 20], "color": [9, 10], "colour": 10, "column": 14, "com": [5, 6, 8, 9, 10, 12, 14, 19, 20], "combin": [10, 13, 19, 20], "come": [2, 6, 8, 10, 18, 19, 20], "comfort": 10, "command": [6, 8, 9, 10, 20], "comment": [0, 1, 2, 5, 6, 10], "commit": [9, 10], "common": [0, 1, 10, 19], "commonli": [10, 11], "commun": [2, 6, 10, 21], "comp_lin": 14, "compani": 10, "compar": 10, "compel": 10, "compens": [14, 21], "compet": 10, "competit": 10, "compil": 10, "complement": [0, 19], "complet": [2, 8, 10, 14], "complex": 10, "complic": [10, 11, 12, 19], "compon": 10, "comprehens": 15, "compressor": 10, "compromis": 19, "comput": [1, 6, 7, 8, 9, 11, 19, 20], "con": 10, "concept": [0, 10, 19], "conceptu": [1, 10], "concern": 10, "conclus": [2, 10], "concucurr": 10, "conda": [8, 14], "condens": 10, "condition_on_previous_text": 20, "conduct": [6, 10], "conf": 10, "confer": 21, "confid": [1, 19], "confident": 10, "config": [10, 11, 14], "configur": [11, 12], "confirm": [6, 10, 12], "conflict": 10, "conform": 10, "confus": [10, 14, 19], "connect": [10, 11, 17], "conquer": 10, "consciou": 19, "consid": [2, 5, 10, 14, 16, 19], "consider": 10, "consist": [2, 3, 7, 9, 10, 14], "constant": [0, 10], "constantli": 10, "constel": 10, "construct": [8, 10, 16], "consum": 21, "contact": [10, 15], "contain": [7, 8, 9, 20], "container": [10, 14], "content": [0, 7, 9, 10, 13, 14, 19, 20], "context": [0, 2, 10, 19], "continu": [1, 10, 13], "continuum": 0, "contrast": 14, "contribut": [10, 13], "contributor": 1, "control": [0, 1, 7, 8, 11, 16], "convei": 19, "conveni": 10, "convent": 10, "convers": [0, 2], "convert": [5, 8, 10], "cook": 10, "cool": [6, 7, 8], "coordin": [0, 10, 13, 14, 17, 21], "copi": [6, 9, 14, 20], "core": 10, "correct": [10, 19], "correspond": [10, 14], "coteach": 10, "could": [0, 2, 8, 10, 17, 19, 20], "couldn": 10, "count": [10, 16], "countri": 1, "coupl": 10, "courag": 10, "cours": [0, 1, 2, 4, 5, 6, 8, 9, 10, 14, 16, 17, 18, 20, 21], "cover": [6, 8, 10, 12, 14, 15], "covid": [10, 21], "cph": 10, "cpu": [8, 10, 11], "cr": [2, 9, 10, 12], "creat": [0, 2, 7, 10, 12, 19], "creator": 1, "criteria": 10, "critic": 10, "crop": 10, "cross": [9, 11], "crowd": 10, "crowdsourc": 20, "crown": 10, "crucial": 10, "cry": 10, "csc": 10, "css": [10, 14], "ctfasset": 10, "ctrl": 14, "cube": 10, "cuda": 20, "cultur": [10, 16], "curios": 19, "curiou": [7, 10], "current": [1, 8, 10, 13, 20], "curriculum": 8, "curriculumn": 10, "cursor": 20, "curv": 10, "custom": [9, 10, 17, 19], "customis": 10, "cut": [10, 20], "cycl": 10, "d": [10, 19], "dai": [2, 5, 6, 8, 13, 14, 20, 21], "daili": [6, 8, 10, 13], "danger": 2, "dark": 14, "darst": 7, "darstr1": 20, "data": [2, 5, 8, 10, 20], "dataset": 10, "date": 10, "daunt": 10, "day1": 20, "deactiv": 10, "dead": 20, "deal": [2, 10], "debrief": 13, "debug": [8, 14], "decaf": 10, "decemb": 10, "decid": [9, 10, 16], "decis": 10, "declar": 2, "decomposit": 3, "decor": 14, "dedic": [0, 2, 9, 14], "deep": [2, 10], "deeper": [6, 10], "deepli": 2, "default": [10, 14], "defin": [0, 8, 10, 20], "definit": [10, 17, 20], "degre": [10, 19], "delai": [2, 10], "delet": 12, "deliev": 10, "deliv": 10, "deliveri": 0, "demand": [2, 10], "demo": [2, 9, 10, 14, 15, 19, 20], "demonstr": [4, 8, 10, 14, 16, 18, 20], "demystifi": 19, "denni": 10, "depend": [2, 6, 8, 9, 10, 20], "deploy": 7, "depth": [10, 13], "deriv": 9, "derse24": 10, "describ": [1, 8, 10, 13, 17], "descript": [10, 13, 20], "design": [1, 3, 6, 7, 9], "desir": [10, 20], "desk": 10, "desktop": 10, "destroi": 10, "detail": [0, 2, 6, 7, 10, 17], "detect": 19, "determin": 10, "dev": 10, "devast": 10, "develop": [1, 5, 6, 7, 13, 19], "deviat": [0, 19], "devic": [2, 10, 16, 20], "devil": 10, "devpixelsperpx": 14, "dhanya": 7, "diagram": 19, "dictionari": 10, "did": [5, 10, 16, 19], "didn": [10, 20], "diff": 10, "differ": [0, 1, 2, 6, 7, 9, 10, 14, 15, 16, 18, 19, 21], "difficult": [1, 5, 10, 19], "difficulti": [1, 21], "dig": 10, "digest": 10, "digit": 10, "dipietro": 10, "dir": 10, "direct": [1, 2, 8, 9, 10, 16, 17], "directli": [9, 17, 20], "director": [0, 10, 11, 13, 17], "directori": [9, 10, 14, 20], "disadvantag": [6, 9], "disagre": 10, "disciplin": [1, 10], "disclaim": 20, "discov": 10, "discret": 1, "discuss": [1, 4, 6, 14, 16, 19, 21], "disorganis": 10, "disori": 0, "displai": [2, 6, 9, 10, 14], "dissoci": 5, "distanc": 10, "distil": [10, 19], "distinct": [10, 21], "distract": [2, 10, 14], "distribut": [10, 13], "divers": [8, 10], "divid": 10, "divis": [0, 10], "dli": 10, "dmp": 10, "dna": 10, "do": [0, 1, 2, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 21], "doc": [2, 9, 10], "document": [0, 1, 5, 9, 10, 13, 14, 19], "doe": [0, 1, 5, 6, 10, 11, 14, 16, 20], "doesn": [2, 9, 10, 14, 16], "doi": 5, "domain": 10, "don": [0, 5, 6, 8, 9, 10, 14, 16, 17, 19, 20, 21], "done": [2, 7, 10, 12, 17, 19, 20, 21], "doubli": 19, "dough": 10, "down": [2, 8, 10, 11], "download": [2, 10, 20], "downsid": [10, 21], "dra": 10, "draft": [8, 10], "drag": 10, "draw": 10, "drawn": 10, "driven": 1, "drop": [0, 10, 13], "drown": 10, "drug": 10, "dry": 10, "dual": 14, "duck": 16, "due": [0, 10, 16], "durat": 2, "dure": [0, 2, 5, 6, 8, 10, 14, 16, 17, 19], "dynam": 10, "e": [0, 1, 6, 10, 13, 14, 17, 20], "each": [0, 2, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20], "ean": 10, "earli": [5, 8, 10], "earlier": [1, 5, 8, 10], "eas": 13, "easi": [2, 8, 9, 10, 11, 14, 19], "easier": [2, 5, 8, 9, 10, 14], "easiest": 10, "easili": [1, 2, 9, 10, 14, 19], "eat": 10, "echo": [10, 14], "edit": [6, 7, 9, 21], "editlist": 10, "editor": [2, 10, 20], "educ": [0, 8, 10], "edward": 10, "eest": 10, "effect": [5, 8, 10], "effici": 10, "effort": [10, 13, 19], "eg": [1, 10], "egg": 10, "eight": 10, "einstein": 10, "either": [0, 4, 9, 10, 16], "elabor": 10, "element": 10, "elimin": 14, "els": [2, 5, 8, 9, 10, 14, 16, 17, 20], "email": 10, "embrac": 19, "emoji": 10, "emot": 10, "emoticon": 10, "emphas": [9, 19], "emphasi": [8, 21], "emploi": 10, "empow": 10, "empti": [8, 10], "emul": 14, "en": [10, 20], "enabl": [2, 10], "encod": 20, "encompass": 10, "encourag": [4, 8, 10, 19], "end": [0, 2, 8, 10, 14, 16, 17, 19, 20], "energi": 2, "engag": [0, 7, 8, 10, 19, 21], "engin": 10, "english": 10, "enhanc": [7, 10], "enjoi": 10, "enjoy": [10, 16], "enough": [1, 8, 10, 20], "ensur": [0, 2, 10, 16], "enter": 14, "enthusiast": 10, "entiti": 10, "entri": [10, 14], "enviro": 10, "environ": [2, 6, 8, 9, 10, 12, 13, 19, 20], "environemnt": 10, "epcc": 10, "episod": [2, 6, 8, 11, 12, 13, 17, 19, 20], "epsisod": 10, "epub": 9, "equal": [2, 10, 20], "equip": [10, 16], "equival": 10, "erambl": 10, "error": [5, 10, 14, 19], "especi": [0, 10, 19, 20], "essenc": 19, "essenti": [8, 10, 13, 14], "est": 10, "estim": 10, "et": 10, "etc": [1, 2, 6, 7, 9, 10, 12, 13, 14, 16, 17, 20, 21], "etern": 5, "etherpad": 10, "europ": 10, "evalu": [8, 10], "even": [0, 2, 6, 9, 10, 14, 16, 19, 20, 21], "event": [6, 10, 13, 14, 16, 21], "eventu": 10, "ever": [10, 16], "everett": 10, "everi": [0, 2, 7, 9, 10, 14], "everybodi": 10, "everyon": [6, 7, 9, 10, 13, 16, 20], "everyth": [0, 9, 10, 12, 19, 20], "everytim": 10, "everywher": 10, "evolv": 1, "ex": 10, "exam": 10, "exampl": [0, 1, 8, 10, 14, 16, 19, 20], "exc": 10, "excalideck": 10, "excalidraw": 10, "excel": 10, "except": 10, "excercis": 10, "excerpt": 20, "exchang": [7, 10], "excit": [10, 16], "execut": [9, 10, 14], "exemplifi": 10, "exercic": 10, "exercis": [1, 3, 6, 13, 19, 21], "exhaust": 10, "exist": [1, 9, 10], "expand": 10, "expect": [5, 8, 10, 20], "expens": [10, 16], "experi": [1, 2, 5, 7, 13, 14, 19], "experienc": [0, 8, 19], "expert": [1, 5, 10, 13, 19], "explain": [0, 1, 3, 10, 19], "explan": [10, 17, 20], "explicit": 19, "explicitli": 10, "explor": [6, 10], "explos": 10, "export": 14, "expos": 8, "express": [8, 10], "extant": 10, "extend": [9, 10], "extens": [8, 9, 10], "extern": [16, 20], "extra": [9, 10, 14], "extrapol": 10, "extrem": 16, "ey": [2, 14], "f": [10, 14], "face": 10, "facilit": [7, 13], "fact": [10, 19], "factor": [10, 20], "fail": [10, 14], "failur": 10, "fair": 10, "fairli": 10, "faith": 10, "fake": 10, "fall": 10, "fals": 20, "familar": 6, "familiar": [10, 11], "fan": 10, "fanci": 10, "far": [5, 6, 10], "fashion": 19, "fast": [2, 5, 10, 19, 20, 21], "faster": 10, "favor": 1, "favorit": [8, 10], "feasibl": 10, "featur": [9, 10, 11, 13], "featureless": 10, "februari": 1, "feedback": [0, 1, 6, 7, 8, 13, 14, 15, 19], "feel": [0, 1, 10, 13, 19, 21], "fell": 10, "fellow": [7, 10], "felt": [10, 19], "few": [2, 5, 10, 14, 19, 20], "ffmpeg": [6, 10], "fi": [10, 20], "fidgit": 10, "field": [5, 10], "fiffer": 10, "figma": 10, "figur": [2, 5, 8, 10, 15, 16, 17], "fil": 10, "file": [9, 10, 14], "filesystem": 10, "fill": [0, 8, 10, 13], "final": [6, 10], "find": [1, 2, 9, 10, 13, 14, 19, 20], "findabl": [8, 10], "fine": [9, 10], "fire": 10, "firefox": 14, "first": [0, 1, 2, 5, 6, 8, 10, 15, 16, 17, 20], "fish": 14, "fish_preexec": 14, "fit": [0, 9, 10], "fix": [2, 5, 9, 10, 16, 20], "fl": 10, "flat": 10, "flexibl": 10, "flinga": 10, "flood": 2, "flow": [0, 2, 9, 10], "flowchat": 20, "fly": 10, "focu": [0, 2, 10, 14, 17, 21], "focus": [0, 10, 13, 21], "folder": 10, "folk": 10, "follow": [1, 2, 5, 8, 9, 10, 13, 14, 20], "font": [9, 10], "fool": 10, "forbidden": 10, "forc": 0, "forev": 10, "forget": [10, 20], "forgiv": 10, "fork": [9, 10], "form": [0, 1, 2, 5, 8, 10, 20, 21], "formal": [10, 11], "format": [1, 8, 10], "former": 10, "formul": 5, "fortun": 10, "forward": [0, 10], "foster": 10, "found": [4, 6, 10], "four": [7, 10, 19, 20], "fragment": 9, "frame": [10, 20], "framework": [3, 10], "franklin": 10, "free": [1, 5, 7, 9, 10, 11, 14, 21], "freelanc": 10, "freir": 10, "frequenc": 10, "frequent": 10, "friend": 19, "friendli": [7, 10], "from": [0, 1, 2, 4, 5, 6, 7, 8, 9, 11, 12, 14, 17, 19, 20, 21], "fruit": [7, 10], "frustrat": 10, "full": [10, 16, 20, 21], "fullhd": 14, "fulli": [1, 10, 19], "fun": [10, 19], "function": [9, 10, 14], "fund": 1, "funder": 5, "further": 6, "fuse": 0, "futur": [1, 5, 6, 7, 10, 19, 20], "g": [0, 10, 17, 20], "gain": 10, "game": 16, "gap": 0, "garbag": 10, "garbl": 20, "gatekeep": 10, "gather": 13, "gave": 18, "gcjexwc8cf": 19, "gdpr": 10, "ge": 10, "gear": 10, "gem": [6, 7, 14], "gener": [0, 6, 7, 8, 9, 13, 21], "geniu": 10, "gentl": 10, "get": [0, 1, 3, 5, 6, 7, 8, 9, 10, 11, 14, 16, 19], "getzola": 10, "ghost": 10, "gi": 10, "giant": 10, "gig": 10, "gigo": 10, "git": [1, 8, 9, 10, 12, 13], "gitautopush": 10, "gitconfig": 14, "github": [2, 5, 6, 10, 12, 14, 20], "gitlab": 8, "give": [1, 2, 5, 9, 10, 12, 13, 14, 19, 20, 21], "given": [1, 8, 10], "giver": 10, "global": 10, "gme": 10, "go": [0, 2, 6, 8, 10, 14, 16, 19, 20], "goal": [2, 4, 5, 8, 10, 13, 14, 19], "goe": [2, 10, 13], "gone": 10, "good": [0, 1, 2, 5, 7, 8, 9, 10, 14, 19, 20, 21], "googl": [2, 10], "got": [1, 6, 10, 14, 19, 21], "gotten": 10, "gpu": 10, "grade": 21, "gradual": 10, "grain": 10, "graphic": [10, 11, 12], "grasp": 10, "great": [7, 10, 13, 19], "greater": 14, "greatest": 19, "green": 10, "grei": 14, "grew": 1, "gritti": 19, "ground": [10, 19], "group": [0, 6, 7, 10, 13, 14], "grow": 10, "guarante": 20, "guess": 10, "guest": 10, "gui": 10, "guid": [7, 8, 10, 13, 17, 19], "gwdg": 10, "h1": 14, "h2": 14, "h3": 14, "h4": 14, "h5": 14, "h6": 14, "h7": 14, "ha": [1, 5, 8, 9, 10, 12, 13, 16, 17, 19], "habit": 0, "hackathon": 10, "hackmd": [0, 2, 10, 20], "had": [5, 10, 19], "hale": 10, "half": [13, 14], "hand": [0, 1, 6, 10, 12, 18], "handbook": 8, "handl": [10, 13], "happen": [2, 10, 13, 17, 20], "happend": 10, "happi": 10, "hard": [9, 10, 14, 16, 17, 19, 20, 21], "harder": [10, 21], "hardest": 10, "hardwar": [10, 19], "hashnod": 10, "hasn": 10, "have": [0, 1, 2, 5, 6, 7, 8, 9, 10, 13, 14, 15, 16, 17, 18, 19, 20, 21], "haven": [8, 10, 14], "hc": 10, "he": 10, "head": [2, 10, 12, 17, 19], "headphon": [10, 16], "headset": [10, 16], "hear": [10, 16], "heard": [10, 16], "hedgedoc": [0, 2, 10], "heidi": 10, "height": 14, "heinlein": 10, "held": 0, "help": [0, 1, 2, 5, 6, 8, 9, 10, 13, 14, 15, 16, 19, 20, 21], "helper": [2, 6, 7, 10, 13], "here": [0, 1, 2, 4, 6, 8, 9, 10, 14, 19, 20, 21], "herford": 10, "heterogen": 10, "hide": 10, "high": [1, 8, 16, 20], "higher": 10, "highli": [2, 10], "highlight": [2, 8, 9, 10], "him": 10, "himself": 10, "hint": [2, 20], "histori": [9, 10], "historysavepath": 14, "histtimeformat": 14, "hole": 19, "home": [10, 19], "homepag": 10, "hope": 10, "hopefulli": [2, 8], "horizont": 14, "horribl": 2, "host": [1, 9, 10], "hostabl": 9, "hour": [2, 5, 10, 20, 21], "hous": 10, "hover": 20, "how": [0, 1, 3, 6, 7, 9, 11, 12, 16, 19, 21], "howev": [0, 1, 10], "hpc": [10, 14, 20, 21], "html": [9, 10], "http": [2, 5, 6, 8, 9, 10, 12, 14, 19, 20], "huge": [10, 21], "human": 10, "humour": 19, "hustl": 10, "hybrid": 10, "hypothesi": 20, "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20], "i1": 14, "i3": 10, "ic": 10, "icebreak": [2, 6], "icon": 9, "icp": 10, "id": 10, "idcc": 10, "idcc24": 10, "idea": [1, 5, 8, 10, 14], "ideal": [10, 14], "identifi": [8, 10], "ie": 10, "imag": [1, 10, 13], "imagin": 10, "imbalanc": 16, "imform": 10, "imho": 10, "immedi": [2, 10, 19, 20], "imovi": 10, "impact": [6, 7], "imperfect": 8, "implement": 10, "implicitli": 10, "import": [0, 1, 2, 8, 9, 10, 11, 12, 13, 14, 19, 20], "imposs": [10, 14], "impress": 10, "impro": 10, "improv": [1, 2, 5, 7, 9, 14, 16, 20], "improvis": 10, "incent": 20, "inclin": 19, "includ": [0, 2, 10, 14, 19, 20], "inclus": 10, "inconveni": 10, "incorpor": 5, "increas": 10, "increment": 10, "inde": 10, "independ": [1, 10, 19], "index": 10, "indic": [2, 10, 13, 20], "individu": [0, 10, 12, 16, 17, 19], "industri": 10, "inertia": 10, "influenc": 10, "info": [2, 10, 13, 20], "inform": [1, 2, 6, 7, 10, 14, 19, 20], "infrastructur": [1, 19], "infrequ": 21, "initi": [2, 8, 10, 20], "initial_prompt": 20, "inkscap": 10, "inlcud": 1, "inlin": 9, "inner": 10, "input": [9, 10, 16, 20], "insid": 10, "insight": 10, "inspir": [5, 9, 10], "instal": [0, 6, 9, 10, 13, 14, 20], "instanc": [0, 9, 10], "instant": [2, 21], "instead": [2, 5, 8, 9, 10, 19, 20], "institut": [1, 5], "instruct": [0, 2, 10, 13, 14, 20], "instructor": [1, 7, 10], "int": 10, "intak": 10, "integr": [10, 13], "intend": [10, 19], "intens": 2, "intent": 19, "interact": [0, 2, 6, 7, 9, 10, 13, 16, 19, 20, 21], "interest": [1, 6, 7, 8, 10, 13, 14, 19], "interfac": [9, 10], "intergr": 10, "intermedi": [1, 10], "intern": 15, "internet": [10, 11], "interoper": 10, "interpret": 2, "interrupt": [0, 2], "interview": 10, "intro": [7, 9, 10, 20], "introduc": [10, 14], "introduct": [6, 7, 8, 12, 15, 20], "introductori": [2, 15], "intuit": 10, "invent": 20, "invert": 8, "invest": 10, "invit": 13, "involv": [1, 10], "io": [2, 5, 6, 8, 9, 10, 14, 20], "iron": 10, "isn": [2, 6, 10, 14, 16, 17, 19, 21], "isol": [8, 10], "issu": [1, 5, 6, 8, 9, 10, 13, 16, 19], "istockphoto": 10, "item": [2, 5, 10], "iter": [1, 7], "its": [0, 1, 10, 14, 20], "itself": [0, 1, 5, 9, 10], "j": 10, "jame": 10, "jargon": [10, 19], "jarno": 7, "jekyl": 8, "jitsi": 10, "job": [10, 19], "joi": 10, "join": [0, 1, 2, 6, 7, 10, 13], "jointli": 0, "joke": 10, "jonathan": 10, "journal": 10, "joyc": 10, "jpg": 10, "json": 12, "judg": [5, 10], "jump": [10, 13, 20], "jupyt": [1, 8, 9, 10, 14], "jupyterbook": 9, "jupyterhub": 10, "jupyterlab": 10, "just": [1, 2, 5, 7, 8, 9, 10, 12, 14, 15, 19, 20], "justifi": 10, "k": 10, "kahoot": 10, "kao": 10, "kb0068677": 10, "kdenliv": 10, "keep": [0, 1, 2, 10, 13, 17, 19], "kei": [1, 10, 13, 20], "keller": 10, "kept": 10, "keyboard": [10, 14], "kick": 10, "kickstart": [14, 20, 21], "kid": 10, "kind": [2, 10, 13, 15, 16], "kitchen": 10, "knead": 10, "knew": [8, 10], "know": [0, 1, 3, 5, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20], "knowledg": [9, 10, 19], "known": [1, 10, 11, 19], "kth": 1, "l": 14, "l1": 14, "l2": 14, "l3": 14, "l8my5kygc": 10, "la": 10, "lab": 10, "label": 10, "labor": [0, 10], "lai": [10, 11], "landscap": 14, "lang": [10, 20], "languag": [1, 8, 10, 19], "laptop": [11, 14], "larg": [2, 7, 10, 11, 13, 14, 19, 20], "larger": [0, 8, 10, 21], "largest": 21, "last": [6, 10], "late": [10, 14, 20], "latenc": [10, 16], "later": [2, 5, 7, 8, 9, 10, 12, 14, 17, 20], "latest": [2, 10, 14, 19], "latex": [8, 9, 10], "latter": [7, 10], "laugh": 10, "layout": 12, "lead": [0, 5, 10, 20], "leader": 16, "lean": 10, "leap": 10, "learn": [0, 1, 6, 7, 10, 11, 13, 17, 19, 20, 21], "learner": [0, 1, 2, 5, 8, 10, 19, 20], "least": 10, "leav": [2, 10, 12, 13, 20], "lectur": [0, 2, 10, 19], "led": 10, "left": [2, 14, 20], "legaci": 14, "length": [6, 10], "less": [0, 10, 14, 16, 19, 21], "lesson": [0, 1, 2, 6, 7, 12, 13, 14, 15, 17, 18, 19, 20], "let": [1, 2, 10, 11, 12, 13, 16, 20], "level": [1, 2, 6, 8, 9, 10], "licens": [8, 10], "life": [10, 15, 19], "lifecycl": 10, "light": [10, 14], "lightn": 6, "like": [0, 1, 2, 4, 6, 7, 8, 9, 14, 16, 19, 20], "likert": 10, "limit": [9, 10, 16, 20, 21], "lincoln": 10, "lindi": 7, "line": [2, 6, 8, 9, 10, 14, 20], "link": [2, 5, 6, 7, 9, 10, 19], "linkedin": 10, "linux": [2, 8, 9, 10, 14, 20], "list": [8, 10, 19, 20], "listen": [10, 16, 19], "liter": [0, 10], "littl": 10, "live": [2, 8, 10, 19], "livestream": [6, 10, 11, 20, 21], "ll": [9, 10, 11, 12, 17], "local": [0, 1, 6, 8, 10, 14], "localhost": 12, "locat": [10, 16], "log": [10, 14], "logic": [2, 10], "login": 2, "logo": 9, "long": [2, 5, 9, 10, 12, 16, 19, 20, 21], "longer": [9, 10], "look": [0, 2, 6, 8, 9, 10, 13, 14, 16, 17, 19, 20], "loop": 10, "loos": 10, "lose": [2, 10], "lost": [8, 10, 14, 20], "lot": [5, 7, 8, 10, 14, 15, 16, 17, 18, 19], "loud": [10, 16], "louder": [10, 16], "loudest": 10, "love": 10, "low": [6, 10, 16], "lower": [10, 13, 16], "luck": 10, "lucki": 10, "luckili": 10, "lyric": 10, "m": [10, 19], "mac": 10, "machin": 10, "made": [9, 10, 12, 13, 14], "magic": 19, "mai": [0, 1, 2, 6, 8, 10, 11, 12, 14, 15, 16, 19, 20], "mail": [6, 10, 13], "main": [0, 1, 2, 3, 6, 8, 10, 13, 14, 17, 19, 20], "mainli": 10, "maintain": [0, 1, 21], "major": [1, 5, 10], "make": [0, 1, 2, 5, 6, 8, 9, 10, 11, 12, 14, 16, 19, 21], "maker": 10, "man": 10, "manag": [8, 9, 10, 11, 13, 14, 17], "mani": [0, 1, 6, 9, 14, 15, 19, 21], "mankind": 10, "manual": [0, 8, 10, 11, 12, 13, 14, 20], "map": [10, 19], "markdown": [2, 8, 9, 10], "mass": [10, 21], "master": [10, 12], "match": [5, 10, 16], "materi": [0, 1, 2, 3, 5, 7, 9, 10, 13, 19], "materti": 10, "matter": [10, 13, 16], "max": 10, "maximum": 14, "mayb": [2, 8, 10], "mbit": 11, "md": 10, "mdbook": 10, "me": [10, 19], "mean": [10, 19, 20], "meant": 10, "measur": [6, 7], "mechan": 5, "media": 10, "mediocr": 10, "medium": [10, 16, 21], "meet": [1, 8, 10, 13, 16], "meetup": 13, "mega": 21, "member": 10, "memor": 19, "memori": [8, 10, 11], "mental": [2, 7], "mention": 10, "mentor": 15, "mentorship": 19, "menu": [10, 12, 14], "mere": 10, "merg": [8, 10], "messag": [8, 9, 10], "messi": 10, "met": 10, "meta": 2, "metaphor": 10, "method": [9, 10], "methodlogi": 10, "mic": 10, "michel": 10, "microphon": [6, 10, 16], "microsoft": 10, "mid": 10, "middl": [5, 10], "midst": 10, "might": [0, 6, 9, 10, 14, 16, 19, 20], "min": [3, 4, 6, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21], "mind": [0, 2, 10, 19], "mindset": 10, "mini": 10, "minim": [2, 9, 10, 14, 19, 20], "minimum": [13, 14], "minor": 10, "minut": [0, 2, 4, 8, 10, 14], "miro": 10, "mirror": 14, "misconcept": 8, "miss": [6, 10, 16, 19, 20], "mistak": [8, 10, 19, 20], "mistyp": 10, "mitig": 10, "mix": [0, 7, 10], "mixer": 11, "mkv": 20, "mobil": 2, "mode": [2, 10, 14, 20], "model": 10, "modesti": 10, "modif": [8, 9], "modifi": [10, 12, 20], "modular": [1, 5, 7, 8, 10], "moment": [10, 19], "mondai": 10, "monei": 10, "monitor": [10, 11, 14], "monologu": 10, "month": 10, "more": [0, 1, 2, 5, 7, 8, 9, 10, 11, 12, 13, 14, 16, 19, 21], "morn": 10, "most": [0, 6, 9, 10, 11, 12, 13, 14, 16, 19, 20, 21], "mostli": [0, 1, 10], "motiv": [1, 5, 10, 14, 19, 20], "motto": 10, "mount": [10, 16], "mous": [10, 20], "move": [0, 8, 10, 13, 20], "movement": 10, "movi": 10, "mpi": 10, "much": [0, 1, 2, 6, 8, 9, 10, 14, 16, 19, 20, 21], "multi": [2, 10], "multipl": [0, 2, 8, 10, 13, 14], "must": [6, 8, 10, 20], "mutual": 10, "mv": 12, "mwakok": 10, "my": [5, 8, 10, 19, 21], "mynam": 2, "myst": [9, 10], "myst_pars": 10, "mysteri": 19, "n": [2, 10, 14], "n0": 14, "n2ak": 20, "name": [2, 5, 10, 16, 20], "narr": 10, "narrat": 10, "narrow": 10, "natur": [0, 10, 19], "navig": [9, 14], "nbinder": 10, "nbviewer": 10, "necessari": [2, 10, 13, 19, 20], "need": [0, 1, 2, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 19, 20], "negoti": 10, "neic": [1, 6], "nerd_fac": 10, "nerded_fac": 10, "nest": 2, "net": 10, "network": [1, 10], "neutral": 5, "never": [2, 6, 10, 12, 19, 20], "new": [0, 2, 7, 9, 10, 14, 15, 17, 19, 20], "next": [2, 5, 6, 7, 8, 9, 10, 11, 13, 16, 19, 20], "nice": [2, 9, 10], "nicer": [10, 21], "nickbearman": 10, "night": 10, "nitti": 19, "nix": 10, "nlastcommand": 10, "nobodi": [10, 14], "nois": [10, 16], "non": [2, 8, 10, 16], "none": [5, 10], "nordic": [1, 13], "norepli": 6, "normal": [6, 9, 10, 16, 21], "notabl": 16, "note": [6, 7, 15], "notebook": [1, 5, 8, 9, 10, 14], "notepad": 10, "notesrecommend": 10, "noth": [10, 14], "notic": [10, 16, 19, 20], "notif": 2, "notifi": 10, "notion": 19, "novemb": 10, "novic": [10, 19], "now": [0, 2, 5, 7, 8, 9, 10, 20, 21], "nuisanc": 10, "number": [0, 6, 8, 10], "numer": 10, "nvidia": 10, "o": [5, 10, 20], "ob": [6, 7, 17, 20], "obei": 10, "object": [6, 7, 10], "obs_cr": 12, "obviou": [2, 10, 20], "occasion": [0, 1, 10, 19], "octob": 1, "odd": 10, "odt": 10, "ofc": 10, "off": [0, 14, 19, 20], "offens": 19, "offer": [6, 7, 8, 10, 13, 19], "offic": 10, "offici": 10, "often": [0, 1, 2, 10, 19], "ok": [10, 14, 20], "old": [10, 12], "older": [2, 20], "oliv": 10, "onboard": [0, 6, 10, 13], "onc": [10, 11, 12, 16, 19], "one": [0, 1, 2, 5, 8, 9, 10, 13, 14, 16, 19, 20, 21], "onedr": 10, "ones": [2, 7, 10, 13, 17], "onli": [0, 2, 6, 7, 8, 9, 10, 13, 14, 15, 19, 20], "onlin": [0, 1, 2, 6, 7, 10, 13, 15, 19], "onsit": 10, "oo": 10, "ooo": [5, 10], "oooo": 10, "ooooo": 10, "oooooo": [5, 10], "ooooooo": 10, "oooooooo": 10, "ooooooooooooooooooo": 5, "op": 10, "open": [0, 1, 2, 6, 7, 8, 9, 14, 19], "openai": 10, "openshot": 10, "oper": [9, 10, 13], "opin": 10, "opinion": [10, 16], "opportun": [1, 2, 10], "oppos": 10, "opposit": [10, 19], "optim": [10, 21], "optimum": 13, "option": [2, 5, 6, 10, 11, 12, 14, 20], "order": [8, 10, 16], "org": [1, 5, 6, 7, 8, 9, 10], "organ": [0, 1, 7, 8, 9, 10, 13], "organis": 10, "orient": 10, "origin": [10, 20], "oss": 10, "other": [0, 1, 2, 5, 6, 7, 8, 9, 10, 16, 19, 20, 21], "otherwis": [10, 15, 20], "our": [0, 4, 5, 9, 10, 12, 13, 14, 15, 16, 17, 20, 21], "out": [1, 2, 5, 6, 9, 10, 11, 13, 14, 15, 16, 17, 20], "outcom": [10, 19], "outlin": [10, 13, 15], "output": [9, 10, 14], "output_format": 20, "outro": [6, 10], "outsid": [7, 10, 20], "outstand": 10, "ov": 10, "over": [0, 5, 7, 8, 10, 14, 16, 19, 20], "overal": [8, 9, 10, 14, 20], "overarch": 8, "overcom": 10, "overhead": 10, "overkil": 11, "overload": [2, 10], "oversight": 10, "overview": [1, 6, 8, 10], "overwhelm": 19, "own": [1, 2, 8, 10, 13, 19, 21], "oxford": 10, "p": 10, "pace": [5, 10], "packag": 10, "pad": 10, "page": [2, 8, 9, 10, 13, 14, 16, 20], "paid": 10, "paint": 8, "pane": 14, "panel": [10, 11, 14], "panick": 16, "paolo": 10, "paper": [8, 10], "paradigm": 10, "parallel": [0, 8, 10, 20], "parser": 9, "parson": 8, "part": [0, 1, 2, 3, 6, 8, 10, 14, 16, 17, 18, 20, 21], "part1": 20, "parti": 10, "partial": 10, "particip": [2, 4, 5, 7, 8, 10, 13, 14, 19, 20], "particu": 10, "particular": [0, 10], "particularli": [5, 10, 14], "partli": 10, "partner": [7, 10], "pass": [6, 10], "past": [8, 10, 20], "path": [10, 13, 20], "pathwai": 10, "pattern": [3, 10], "paus": [10, 14], "pavucontrol": 10, "pdf": [9, 10], "pedagog": 10, "peer": 13, "pen": 10, "pencil": 9, "peng": 10, "peopl": [1, 2, 8, 9, 10, 14, 16, 19, 20, 21], "per": [10, 20], "perceiv": 10, "perfect": [2, 8, 20], "perfectli": 19, "perform": [1, 8], "perhap": [10, 20], "period": [2, 10, 19], "periscop": 10, "perman": 10, "permiss": 2, "persist": 5, "person": [0, 2, 10, 13, 16, 17, 19, 21], "persona": [8, 10, 19], "personalis": 10, "personel": 10, "perspect": [7, 19], "phase": 13, "phd": 10, "philosohi": 6, "philosophi": [7, 9], "phrase": 19, "physic": 10, "pick": [8, 10, 16], "pickl": 10, "pickup": 16, "pictur": [0, 5, 8, 14], "pid": 10, "piec": [10, 11, 12], "pinimg": 10, "pioneer": 10, "pip": [10, 12, 14, 20], "pipe": 10, "pitfal": 14, "place": [2, 5, 9, 10, 19, 20, 21], "plai": 10, "plain": 10, "plan": [0, 1, 2, 5, 8, 10, 14, 18], "planet": 10, "platform": [10, 11, 17], "player": 10, "playlist": [19, 20], "pleas": [2, 5, 6, 7, 8, 10, 14, 15, 16, 19], "pleasant": 10, "plenti": [6, 10], "plplblyhczjaahf89p": 19, "plu": 14, "plug": 16, "plzlvms9rf3nmkr2jmglan4su3ojwtwmvw": 20, "png": 10, "poet": 10, "point": [2, 8, 9, 10, 17, 19, 20], "polar": 10, "polish": 10, "pop": 10, "popular": 10, "port": [1, 8], "portion": [10, 11, 14], "portrait": 10, "posit": 10, "possibl": [1, 2, 9, 10, 14, 16, 19, 21], "possibli": [0, 10, 14, 20], "post": [5, 7, 8, 10, 13], "potenti": [0, 16], "power": [10, 11], "powershel": 14, "pptx": 10, "pr": 2, "practic": [0, 1, 3, 7, 8, 15, 16, 18], "pre": [5, 10, 12], "precis": [10, 19], "predict": 10, "preexec": 14, "prefer": [2, 10, 11, 14], "premis": 10, "prep": 10, "prepar": [0, 7, 8, 13, 15, 16, 19], "prerequisit": [7, 9, 10, 20], "presemo": 10, "presenc": 10, "present": [1, 4, 6, 7, 8, 10, 13, 19, 20, 21], "presentor": 10, "presist": 10, "press": [8, 14], "presum": 10, "pretend": 10, "pretti": [8, 9, 10, 16], "preview": [8, 9, 10], "previou": [0, 6, 7, 9, 10, 12, 13, 19, 20], "price": 16, "primari": 14, "principl": [0, 10, 20], "print": [10, 14], "prior": 1, "priorit": 10, "prioriti": [10, 20], "privaci": [10, 20, 21], "privat": [2, 10], "prize": 10, "pro": 10, "prob": 10, "probabl": [8, 9, 10, 11, 14, 16, 20, 21], "problem": [1, 2, 3, 5, 10, 19], "procedur": [0, 16], "process": [0, 10, 20], "procur": 16, "produc": [10, 20], "product": [6, 10, 15, 19], "profan": 10, "profession": [16, 19], "profil": [8, 10, 12, 14], "program": [1, 8, 10, 14, 19], "programm": [10, 14], "progress": [2, 10], "project": [6, 7, 8, 9, 10], "prompt": [10, 20], "prompt_command": 14, "proper": [6, 8, 10], "propos": [0, 1, 6, 9, 10], "propsal": 9, "protein": 10, "prove": 10, "proven": 7, "provid": [1, 2, 5, 6, 9, 10, 14, 20], "ps1": 14, "psreadlineopt": 14, "public": [2, 5, 9, 10], "publicli": [1, 10], "publish": [2, 5, 8, 10], "pull": [8, 9, 10, 19, 20], "pulsemix": 10, "pun": 10, "punctuat": 20, "purchas": 11, "pure": 14, "puriti": 10, "purpos": [9, 12], "push": [9, 10, 14], "pushpada": 7, "put": [2, 8, 10, 18], "py": [10, 12], "python": [6, 8, 9, 10, 12, 14, 20], "pyyaml": 20, "q": [2, 10, 13, 18], "qgi": 10, "qua": 10, "qualifi": 1, "qualiti": [7, 8, 20], "quantifi": [5, 10], "quarto": 10, "question": [0, 1, 7, 8, 9, 11, 12, 13, 14, 15, 19], "quick": [2, 8, 10, 20], "quickli": [2, 6, 10, 14, 16, 20], "quicktim": 10, "quiet": [10, 16], "quieter": 10, "quietest": 10, "quit": [2, 10, 19], "quiz": 10, "quizz": 10, "r": [9, 10], "rabbit": 19, "radovan": [7, 10], "rais": [1, 2, 19], "ram": 10, "ran": 10, "random": [6, 8, 10], "rang": [10, 16], "rantaharju": 7, "rapid": 21, "rapidli": 14, "rare": [10, 19], "rate": 10, "rather": [2, 10, 12], "ratio": 10, "raw": 10, "rb": 10, "rd": 10, "re": [10, 12, 15, 16, 19, 20], "reach": [5, 10, 21], "read": [0, 2, 6, 9, 10, 14, 19], "readabl": 14, "reader": 20, "readi": [7, 10, 13, 20], "readili": 10, "readm": 10, "readthedoc": [8, 10], "real": [2, 10, 11, 15, 19, 20], "realist": [10, 14], "realiti": 0, "realiz": [10, 16, 19], "realli": [2, 8, 10, 14], "reason": [2, 5, 8, 10, 11, 16], "recent": [9, 10, 14], "recip": 10, "recogn": 10, "recognit": [3, 10], "recommend": [2, 6, 10, 13, 14, 18, 19, 21], "record": [8, 10, 13, 15, 20], "recov": [8, 14], "recreat": 12, "red": [10, 14], "redesign": 8, "reduc": [0, 2, 10, 14], "reencod": 20, "ref": 12, "refer": [2, 10], "referenc": 9, "refin": [10, 15], "refinari": 10, "refineri": 10, "reformul": 5, "refresh": 10, "regard": 13, "regist": 7, "registr": [5, 6, 7, 10, 13, 21], "regular": [8, 10], "rehears": 10, "reichent": 10, "reign": 10, "rel": 10, "relat": [10, 19], "relationship": 10, "relax": 10, "relearn": 10, "releas": [6, 8, 10, 20], "relev": [0, 8, 10, 14], "reli": 0, "remain": [2, 10], "remark": [0, 10], "remarkj": 10, "rememb": [8, 10, 20], "remind": [2, 10], "remot": [0, 10, 14, 17, 20, 21], "remov": [2, 5, 10, 14, 20], "renam": [10, 14], "render": 10, "repeat": [10, 19], "repetet": 10, "rephras": 10, "repli": 10, "repo": [9, 10], "repons": 10, "report": [5, 10], "repositori": [1, 8, 9, 10, 12], "repres": 10, "reproduc": [1, 5, 10], "request": [8, 9, 10, 19], "requir": [0, 2, 6, 9, 10, 14, 16, 21], "requisit": 10, "research": [1, 5, 10, 14, 19, 21], "reset": 12, "resist": 10, "resiz": [10, 14], "resolut": 12, "resourc": [5, 10], "respect": [9, 10, 12, 16], "respond": 5, "respons": [0, 5, 10], "rest": [9, 10, 20], "restructur": 9, "result": [5, 10, 20], "resus": 10, "return": 14, "reupload": 10, "reus": [7, 8, 9, 10, 13, 15], "reusabl": [5, 10, 21], "reveal": 10, "revealj": 10, "revers": 14, "review": [10, 20, 21], "revis": [0, 10], "revisit": 1, "rewrit": [8, 10], "richard": [7, 10], "right": [2, 5, 10, 13, 14, 16, 19, 20], "rigor": [2, 10], "rise": [5, 10], "risk": [2, 5, 10, 20, 21], "ritchi": 10, "rkdarst": 12, "rmarkdown": [9, 10], "robert": 10, "robot": 10, "role": [0, 2, 6, 10, 17, 20], "room": [0, 2, 8, 16, 19, 20], "room1": 10, "room2": 10, "root": 2, "rough": [8, 10], "roughli": [9, 10], "rse": 10, "rst": [9, 10], "rubi": 8, "rule": 10, "run": [1, 5, 9, 10, 12, 13, 14], "runner": 10, "rush": 10, "rust": 10, "rxqefefl3t5b": 10, "sacr": 10, "safe": 10, "sai": [0, 2, 10, 14, 16, 20], "said": [2, 10, 20], "saluting_fac": 10, "samantha": [7, 10], "same": [0, 6, 9, 10, 14, 16, 17, 19, 20], "sampl": [9, 10], "sandpap": 10, "satisfi": 10, "satur": 14, "save": [0, 5, 10, 14], "sc": 10, "scale": [5, 7, 10, 13, 21], "scan": 2, "scari": 17, "scenario": 10, "scene": [10, 12, 13], "schedul": [6, 20], "scicomp": 20, "scicompintro": 20, "scienc": [10, 20], "scientif": [10, 20], "scip": 20, "scisoft": 8, "scope": [2, 10], "scratch": [11, 12], "scream": 10, "screen": [4, 7, 17, 20], "screencast": 11, "screenkei": 10, "screenshar": [2, 6, 7, 10], "screenshot": [10, 14], "screenshot_2023": 10, "script": [1, 10, 14, 19], "scroll": [10, 20], "scrum": 10, "search": [2, 10, 14], "season": 10, "sec": 10, "second": [10, 11, 20], "section": [1, 2, 10, 12, 13, 20], "secur": 2, "sed": [10, 14], "see": [0, 1, 2, 6, 8, 9, 10, 12, 13, 14, 17, 19], "seed": 10, "seedl": 10, "seek": 10, "seem": [0, 1, 10, 11, 12, 16, 19], "seen": [0, 2, 5, 7, 10], "segment": [10, 20], "seibold": 10, "select": [2, 10], "self": [7, 8, 10, 19], "sell": 9, "seminar": 10, "send": [2, 9, 10, 13, 19], "sens": [1, 2, 10, 11, 12], "sensit": 19, "sent": [6, 10], "sentenc": [10, 19, 20], "sep": 7, "separ": [8, 10, 14, 19, 20, 21], "sequenc": 20, "serial": 19, "serv": [0, 10], "server": [12, 14], "servic": [1, 10], "sese": 1, "session": [0, 1, 2, 8, 12, 13, 14, 17, 19, 20], "session_nam": 14, "set": [6, 9, 10, 13, 15, 16, 19, 20], "setup": [6, 7, 8, 11, 16], "sever": [8, 10, 16, 20, 21], "sfor": 10, "share": [2, 5, 6, 7, 9, 12, 13, 15, 17, 19, 20], "shareabl": 9, "sheet": 10, "shell": [8, 9, 10, 14], "shell_command": 14, "shellshar": 10, "shift": 14, "shokingli": 10, "short": [3, 4, 10, 12, 20], "shortcom": 10, "shortcut": [10, 14], "shorten": 13, "shortest": 10, "shot": [10, 21], "shotcut": 10, "should": [2, 5, 8, 9, 10, 14, 16, 19, 20], "shouldn": [2, 10, 16, 17], "show": [0, 1, 5, 6, 8, 9, 10, 13, 14, 16, 18, 19], "shown": 14, "shy": 10, "sick": 10, "side": [6, 10, 14], "sign": [10, 19], "signal": [8, 10, 19], "silenc": 10, "silent": 10, "silli": 10, "similar": [0, 2, 10, 14, 16, 19], "simpl": [8, 10, 14, 19, 20], "simpler": [8, 10], "simpli": [10, 19], "simplic": 10, "simplifi": [10, 14], "simul": [10, 20], "simultan": 10, "sinc": [2, 5, 10, 12, 13, 14, 15, 19, 20], "sine": 10, "singl": [0, 9, 10, 13, 14, 21], "sit": 10, "site": [2, 9, 10], "situat": [0, 14], "six": 10, "size": [10, 21], "skill": [0, 7, 10, 19], "skip": 19, "sleep": 10, "sleepi": 10, "sleeppi": 10, "slice": 20, "slide": [3, 8, 9, 10, 19], "slider": 10, "slido": 10, "slightli": [2, 10, 14], "slot": 10, "slow": [2, 5, 10, 20], "slower": 10, "slowest": 11, "slowli": 14, "slur": 10, "small": [2, 6, 7, 8, 10, 14, 16, 21], "smaller": [10, 13, 14, 18], "smart": 10, "smc": 10, "smil": 10, "smile": 10, "smiley_cat": 10, "smooth": 10, "smoothli": 10, "smut": 7, "snippet": 9, "snore": 10, "so": [0, 1, 2, 5, 6, 8, 9, 10, 11, 13, 14, 16, 17, 19, 20], "social": 10, "softer": 16, "softwar": [1, 5, 7, 9, 14, 16, 19, 21], "software_carpentri": 10, "solidifi": 8, "solo": [0, 10], "solut": [8, 10, 14, 19], "solution": 10, "solv": [1, 3, 10, 19], "some": [0, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, 16, 19, 20], "somebodi": [8, 10], "somehow": 10, "someon": [0, 2, 5, 8, 9, 10, 13, 14, 16, 17, 18, 19, 20], "someth": [1, 2, 4, 5, 6, 8, 9, 10, 14, 16, 17, 19, 20], "sometim": [0, 5, 6, 10, 19], "sometimes": 10, "somewhat": 10, "somewher": 10, "song": 10, "soni": 10, "sonor": 10, "soon": [2, 10, 16], "sooner": [2, 10, 19], "sorri": 10, "sort": 10, "soucr": 10, "sound": [0, 6, 7, 19], "sourc": [0, 5, 8, 9, 10, 11, 19], "space": [10, 14], "spade": 10, "spam": 10, "spanish": 10, "spark": 19, "spars": 10, "spatial": 10, "speak": [0, 10, 20], "speaker": 10, "spec": 10, "special": 10, "specif": [1, 8, 10, 19], "specifi": 16, "spectrum": 10, "speech": 10, "speed": [1, 5, 10], "spend": 10, "spent": 19, "sphinx": [6, 8, 10], "spi": 10, "split": [2, 10, 14, 19, 20], "spontan": 10, "spool": 10, "spot": [9, 20], "spotter": 0, "spread": 1, "sprinkl": 8, "srt": 20, "ssh": 14, "stabil": 10, "stabl": [10, 11], "stack": 10, "staff": [2, 20], "stage": 10, "stai": [8, 10, 19, 21], "standard": [8, 9, 14], "star": 10, "stare": 10, "start": [1, 2, 6, 8, 10, 13, 14, 16, 17, 19, 20], "starter": 10, "stat": 10, "state": 10, "statement": [2, 10], "static": 9, "statist": 10, "statu": [2, 10], "steadili": 10, "step": [1, 2, 8, 10, 12, 18, 20], "stepa": 7, "stephan": 7, "steve": 10, "sth": 10, "stick": 20, "sticki": 10, "still": [2, 6, 8, 10, 13, 14], "stockholm": [1, 10], "stop": [10, 19, 20], "storag": 20, "stori": [10, 19], "straight": [9, 10, 17], "straightforward": [9, 10], "strategi": [8, 10, 13], "stream": [0, 6, 7, 11, 12, 13, 14, 15, 18], "streamer": 10, "streamyard": 17, "streme": 10, "strength": 0, "stress": [0, 10], "strike": 10, "string": 10, "strip": 2, "strong": [0, 9, 10], "strongli": [10, 14], "strted": 10, "structur": [0, 2, 7, 10, 13, 19], "struggl": 10, "stuck": 10, "student": [0, 10, 13], "studi": [10, 19], "studio": [6, 11, 12], "stuff": [10, 14], "style": [0, 1, 6, 10, 19], "sub": 14, "subject": [0, 10], "submit": [1, 9], "subtitl": 10, "subtleti": 0, "succe": 10, "succeed": 10, "success": [0, 5, 10, 13, 14, 19], "successfulli": 10, "suffer": [10, 16], "suffici": [1, 10, 19], "suggest": [5, 8, 10], "suit": [10, 12], "suitabl": 13, "sum": [10, 19], "summ": 8, "summari": [8, 10, 13], "summat": 10, "summer": [10, 13, 20], "sun_with_fac": 10, "sunflow": 10, "supercomput": 9, "superior": 10, "superus": 14, "support": [0, 1, 6, 7, 9, 10, 13, 19], "suppos": 10, "sure": [2, 5, 10, 16, 20], "surpris": [10, 19], "surprisingli": 10, "survei": [10, 13], "swap": 16, "swcarpentri": 10, "sweat_smil": 10, "sweden": 5, "sweet": 10, "switch": [2, 7, 10], "symbol": 10, "symbolifi": 10, "sync": 9, "synergi": 0, "syntax": 2, "synthet": 20, "sysparm_articl": 10, "system": [9, 10, 13], "systemat": 16, "t": [0, 5, 6, 8, 9, 10, 14, 16, 17, 19, 20, 21], "tab": [8, 9, 10, 14], "tabl": [10, 20], "tackl": 10, "tag": 2, "tail": [10, 14], "tailor": [0, 10], "take": [0, 2, 4, 9, 10, 13, 14, 16, 17, 19, 20], "taken": [10, 13], "talbert": 10, "talk": [0, 2, 8, 10, 13, 15, 18, 20, 21], "tandem": 10, "target": [7, 10], "task": [7, 10], "tast": 10, "taught": [0, 8, 10, 19, 21], "tavatar": 14, "taxonomi": 8, "tea": 10, "teach": [1, 2, 3, 6, 7, 9, 11, 12, 13, 15, 16, 17, 18, 20, 21], "teacher": [0, 10, 13, 19], "teachingstreamingv3": 12, "teachingstreamingzoomv3": 12, "teachtogeth": 10, "team": [9, 10, 16, 21], "teamtopologi": 10, "tear": 10, "tech": [8, 10, 14], "technic": [6, 8, 10, 15], "techniqu": [5, 6, 7, 13, 19], "technologi": [2, 8, 10, 19], "teenag": 10, "tell": [0, 10], "templat": [6, 8, 10], "ten": 8, "tend": [5, 10, 19], "tendend": 10, "term": [10, 17], "termin": 10, "terminologi": 10, "termonologi": 10, "test": [7, 8, 10, 12, 14, 16], "text": [2, 5, 9, 10, 13, 14, 20], "than": [2, 5, 8, 9, 10, 14, 16, 19, 20, 21], "thank": 10, "thankfulli": 10, "thats": 10, "thee": 15, "thei": [0, 1, 2, 4, 5, 8, 9, 10, 13, 14, 16, 17, 19, 20, 21], "them": [1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, 16, 17, 19, 21], "themat": 10, "theme": [10, 14], "themselv": [10, 16], "theoret": [1, 10, 18], "theori": [3, 10, 11, 12, 18], "ther": 10, "therefor": [0, 5, 10], "thi": [0, 1, 2, 3, 6, 8, 9, 10, 11, 12, 14, 15, 16, 17, 19, 21], "thing": [0, 5, 6, 7, 8, 12, 13, 14, 15, 16, 17, 19, 20, 21], "think": [2, 5, 6, 7, 8, 9, 16], "thinker": 10, "this_command": 14, "thoroughli": 10, "those": [0, 2, 6, 8, 10], "though": [2, 10, 13, 19], "thought": [8, 10, 13], "thread": 2, "three": [8, 10, 14, 16, 19, 20], "through": [0, 1, 2, 10, 11, 13, 19, 20], "throughout": 10, "throw": 0, "thrown": 19, "thu": [10, 20], "thumbnail": 10, "thumbs_up": 10, "thvmntbjg2y": 20, "tidi": 10, "tighter": 10, "time": [0, 2, 7, 8, 10, 11, 14, 16, 19, 20, 21], "timer": 10, "timestamp": 20, "tini": [9, 10], "tip": [5, 6, 8, 10], "tire": 10, "tired_fac": 10, "titl": [2, 10, 14, 20], "tmp": 14, "tmux": 14, "tmuxp": 14, "todai": [2, 5, 19], "togeth": [0, 8, 9, 10, 21], "token": 12, "toliauta": 7, "tomorrow": 10, "tone": 10, "tongu": 10, "too": [0, 1, 2, 5, 8, 10, 14, 16, 19, 20, 21], "took": 10, "tool": [1, 4, 6, 7, 8, 9, 13, 14, 16, 19, 20, 21], "toolbar": 14, "toolbox": 8, "toolkit": 10, "top": [2, 10, 14], "topic": [1, 6, 7, 8, 10, 19, 20, 21], "total": 10, "touch": [13, 14], "tough": 10, "tour": 17, "toward": [1, 8, 9, 10], "track": [0, 2, 5, 8, 10, 14], "traction": 10, "trade": 14, "tradit": [8, 10, 13, 19, 21], "traffic": 10, "train": [1, 8, 10, 13, 18, 19, 20, 21], "train2": 10, "trainer": 10, "transcript": [10, 20], "transfer": [8, 10], "transform": 10, "transit": [1, 10, 20], "translat": [10, 20], "transmiss": 19, "transpar": 10, "trap": 14, "travel": 21, "tree": 10, "trend": [8, 10], "tri": [0, 1, 5, 10, 16], "trick": [4, 5, 6, 8, 10, 16, 19], "tricki": 10, "trim": 10, "trivial": 10, "troubl": 10, "troughout": 10, "true": 10, "try": [0, 1, 2, 6, 8, 9, 10, 12, 14, 19, 20], "ttt": [9, 10], "tuesdai": [7, 10], "tune": [9, 10], "turn": [10, 13, 16], "tutori": [10, 17, 19], "tweak": 10, "twice": 10, "twist": 19, "twitch": [10, 17, 21], "twitter": 10, "two": [0, 1, 2, 8, 10, 12, 13, 16, 19, 20], "txt": [6, 9, 20], "type": [0, 8, 10, 12, 14, 16, 19], "typic": [1, 10, 14], "typo": [10, 19], "u": [1, 2, 5, 7, 9, 10, 13, 15, 16, 19, 20, 21], "uk": 10, "umbrella": 10, "unabl": 10, "unclear": [2, 19], "uncomfort": [10, 19], "under": [8, 10, 12], "underli": 10, "understand": [0, 1, 5, 8, 9, 10, 11, 13, 16, 19], "understood": 10, "unexpect": 0, "unexpectedli": 17, "unfortun": [10, 14], "uniqu": 10, "univers": [1, 10, 19], "unix": 10, "unknown": 10, "unless": 10, "unlik": 10, "unmanag": 10, "unnecessari": [1, 5], "unpleas": 10, "unprepar": 0, "unprepared": 0, "unproblemat": 10, "unprocess": 20, "unsaf": 10, "unspecifi": 5, "unsur": 10, "until": [1, 2, 5, 10], "unwant": 10, "uo5kbtqdjzbbqb_xldhzuovx5t08fhfgr7dw7tck90i": 10, "up": [0, 1, 2, 5, 6, 8, 9, 10, 11, 13, 15, 19, 20], "upcom": [6, 10], "updat": [2, 5, 6, 10, 12, 13], "upload": 10, "upper": 14, "upstream": 9, "urgent": [13, 16], "url": [2, 10], "us": [0, 1, 2, 3, 4, 6, 7, 10, 11, 12, 14, 15, 16, 18, 19, 21], "usabl": 10, "usag": [1, 8, 10], "usb": 16, "user": [10, 20], "usernam": 2, "usual": [1, 6, 10, 16], "utc": 10, "v": [8, 10, 17, 20], "vagu": 10, "valid": 10, "valu": [10, 14, 19], "valuabl": [2, 5, 10, 14], "variabl": 10, "varieti": [10, 14], "variou": [0, 9, 10], "vastli": 10, "vc": 10, "ve": [10, 19, 21], "vector": 10, "vega": 10, "veri": [0, 1, 2, 4, 6, 9, 10, 14, 16, 18, 19, 20], "versa": 10, "version": [1, 5, 7, 8, 19, 20], "versu": 10, "vertic": 14, "vew": 10, "via": [2, 8, 9, 10, 13], "vice": 10, "video": [6, 7, 11, 12, 15, 21], "vie": 10, "view": [2, 10, 11, 17], "viewpoint": [10, 19], "virtual": [9, 10, 20], "visibl": 10, "vision": 10, "visual": 10, "visualis": 10, "voic": [0, 2, 10, 16], "volum": [2, 10], "volunt": [10, 13], "voluntari": 10, "vote": 10, "w": 10, "wa": [1, 2, 8, 9, 10, 13, 14, 17, 19, 20], "wai": [0, 9, 10, 11, 13, 14, 18, 19, 20], "wait": [2, 14, 19], "wake": 10, "walk": 17, "wall": 2, "want": [0, 1, 6, 8, 9, 10, 13, 14, 15, 18, 19, 20, 21], "war": 19, "ward": 10, "wasn": 10, "wast": 10, "watch": [0, 9, 10, 13, 14, 19, 20], "wayland": [10, 14], "we": [0, 1, 2, 4, 6, 7, 9, 11, 12, 15, 17, 18, 19], "wear": 10, "web": [2, 8, 9, 10, 13, 14], "webcam": 10, "webpag": [2, 20], "websit": [10, 14], "websocket": 17, "webwhiteboard": 10, "wed": 10, "week": [6, 10, 13, 19], "weird": 15, "welcom": [10, 13, 20], "well": [0, 2, 10, 14, 15, 16, 19], "went": 10, "were": [2, 8, 10, 13, 16, 20], "weren": [10, 19], "what": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 13, 14, 15, 16, 19], "whatev": [9, 10, 14], "whatsapp": 10, "when": [0, 1, 2, 5, 8, 10, 17, 19, 20, 21], "whenev": [1, 7, 19], "where": [0, 1, 6, 8, 9, 10, 13, 16, 19, 20], "wherea": 10, "wherev": 16, "whether": [0, 10, 19, 20], "which": [0, 1, 2, 6, 8, 10, 11, 13, 14, 17, 19, 20], "while": [0, 2, 10, 13, 14, 19, 20], "whisper": 10, "whistl": 10, "white": 14, "whiteboard": 10, "who": [0, 1, 2, 5, 6, 10, 16, 18, 20], "whole": [6, 20], "whom": 10, "why": [2, 5, 6, 7, 13, 19], "wide": 10, "wider": 10, "wiki": 10, "william": 10, "win": 10, "window": [2, 10, 11, 14], "window_nam": 14, "winter": 13, "wire": [10, 11, 16, 19], "wireless": 16, "wise": 10, "wiser": 10, "wish": [1, 8, 10, 13], "within": [0, 2, 9, 10, 16, 20], "without": [0, 2, 8, 10, 14, 16, 21], "wittk": 7, "won": [2, 10, 16, 20, 21], "wonder": [10, 14, 19], "woozy_fac": 10, "word": [1, 5, 10, 16, 19, 20], "work": [0, 1, 7, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20], "workaround": [10, 14], "workbench": 10, "workbook": 10, "workflow": [1, 8, 9, 10, 20], "workload": 0, "workplac": 16, "workshop": [0, 6, 8, 14, 16, 17, 19, 20, 21], "world": [10, 19], "worri": [2, 6, 10], "wors": 10, "worsen": 10, "worst": [10, 17], "worth": [10, 20, 21], "worthwhil": [10, 19], "would": [1, 2, 5, 6, 7, 8, 9, 13, 19, 20, 21], "wouldn": 2, "wow": 10, "write": [0, 1, 2, 5, 7, 8, 9, 10], "writer": [8, 10], "written": 10, "wrong": [8, 10, 16], "www": [10, 19, 20], "x": [1, 8, 10, 19], "x11": 14, "xorg": 14, "xx": [2, 10], "xxx": [2, 10], "yawning_fac": 10, "ye": [0, 5, 10, 21], "yeah": 10, "year": [5, 10, 13], "yellow": 14, "yep": 10, "yet": [1, 8, 10, 11, 12, 14, 17, 20], "you": [0, 1, 2, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21], "your": [0, 1, 2, 6, 7, 10, 12, 13, 16, 17, 19], "yournam": 2, "yourself": [2, 6, 8, 9, 10, 13], "yourselv": 16, "youtub": [10, 17, 19, 20, 21], "zenodo": [5, 10], "zip": 12, "zm_kb": 10, "zola": 10, "zone": 10, "zoom": [6, 7, 10, 13, 14, 17, 21], "zsh": [10, 14], "zsh_histori": 10, "zulip": [1, 10], "zulipchat": 10}, "titles": ["Co-teaching", "About the CodeRefinery project and CodeRefinery workshops in general", "Collaborative notes", "Computational thinking", "Sharing teaching gems", "How we collect feedback and measure impact", "Instructor guide", "Train the trainer workshop", "Lesson design and development", "Lessons with version control", "Collaborative notes archives from workshops", "Open Broadcaster Software (OBS) introduction", "Open Broadcaster Software (OBS) setup", "A workshop seen from different perspectives", "How to prepare a quality screen-share", "Session 4 intro", "Sound", "Behind the stream", "What\u2019s next?", "CodeRefinery teaching philosophies", "Video editing", "Why we stream"], "titleterms": {"": 18, "08": 10, "09": 10, "1": [5, 7, 9, 10, 16, 20], "10": [0, 5], "13": 10, "15": 2, "2": [5, 7, 9, 10, 16, 20], "20": [8, 10, 14, 19], "2024": [7, 10], "24": 10, "27": 10, "3": [5, 7, 9, 10, 16, 20], "4": [5, 7, 9, 10, 15, 20], "5": [8, 9, 10, 20], "6": 20, "7": 20, "A": [11, 12, 13, 17, 20, 21], "One": [10, 13], "The": [8, 12, 16], "about": [1, 8, 10], "accept": 9, "add": 20, "adjust": 16, "adopt": 10, "advanc": 9, "after": 13, "all": [8, 10], "also": [11, 18, 20], "altern": 17, "ani": 0, "approach": 8, "ar": [0, 8, 16, 17], "archiv": 10, "articl": 20, "ask": [2, 5], "audienc": [1, 6, 10], "audio": 16, "august": [7, 10], "b": 20, "backward": 8, "balanc": 16, "basic": [2, 20], "bast": 19, "befor": [2, 5, 12, 13], "behind": [10, 17], "benefit": [0, 21], "best": 10, "better": 8, "between": 14, "bj\u00f8rn": 19, "breaker": 19, "breakout": 10, "breakoutroom": 10, "briefli": 21, "broadcast": [10, 11, 12], "browser": 14, "build": 9, "calendar": 10, "can": 17, "captur": 14, "carpentri": [1, 9], "case": 8, "challeng": 1, "check": [10, 16], "classroom": 10, "clone": 9, "co": [0, 10], "coderefineri": [1, 7, 8, 9, 10, 12, 17, 19], "collabor": [2, 5, 10], "collect": [5, 8, 10], "color": 14, "command": 14, "commun": [1, 13], "compet": 1, "comput": [3, 10], "config": 12, "configur": 14, "contribut": 9, "control": [2, 9, 10, 12, 17], "cool": 10, "cours": [11, 12], "creat": [8, 9, 20], "dai": 10, "darst": 19, "day1": 10, "day4": 10, "defin": 1, "demo": 0, "deploy": 10, "design": [5, 8, 10], "desktop": 14, "develop": [8, 10], "did": 13, "differ": 13, "disadvantag": 21, "discuss": [0, 2, 5, 8, 9, 10, 13, 20], "distribut": 20, "do": [8, 16, 20], "document": [2, 8], "doe": 17, "don": 2, "down": 16, "downsid": 0, "dure": [11, 13], "dynam": 16, "each": [6, 12], "easi": 20, "edit": [2, 10, 20], "editlist": 20, "entir": 14, "environ": 14, "episod": 10, "evalu": [14, 16], "everyon": 2, "exampl": [2, 5, 9], "exercis": [0, 2, 5, 8, 9, 10, 14, 16, 20], "exist": 8, "experi": 10, "featur": 20, "feedback": [2, 5, 10], "ffmpeg": 20, "file": 20, "final": 20, "font": 14, "format": [2, 9], "from": [10, 13], "futur": 21, "gem": [4, 10], "gener": [1, 2, 10, 20], "get": [2, 13, 17, 20], "github": [8, 9], "giver": 0, "go": [9, 12, 17], "goal": 1, "good": 16, "great": 8, "group": [5, 8, 19], "guid": [0, 6], "habit": 14, "handl": 2, "hardwar": 11, "histori": [1, 14, 21], "host": 13, "how": [2, 5, 8, 10, 13, 14, 17, 20], "i": [11, 21], "ic": 19, "icebreak": [10, 21], "icecream": 10, "impact": [5, 10], "import": 16, "improv": [8, 10], "individu": 13, "initi": 12, "instal": 12, "instead": 14, "instructor": [0, 2, 3, 4, 5, 6, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21], "interfac": 11, "interview": 0, "intro": [6, 15], "introduct": [2, 10, 11, 19], "invest": 13, "involv": 13, "iter": 10, "journei": 13, "keypoint": [0, 1, 2, 3, 9, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21], "layout": [14, 17], "lead": 13, "learn": [5, 8, 14], "learner": [13, 14], "lesson": [5, 8, 9, 10], "like": [10, 13], "lindi": 19, "local": [9, 13], "longer": 5, "lot": 13, "make": 20, "manag": 2, "mani": [10, 13], "materi": 8, "measur": [5, 10], "mechan": 2, "min": [0, 2, 5, 8, 14], "minut": 19, "model": 0, "modifi": 9, "more": 20, "most": 2, "need": 14, "new": 8, "next": 18, "note": [0, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21], "novic": 1, "ob": [10, 11, 12], "object": [0, 1, 2, 3, 4, 5, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21], "onlin": 14, "open": [10, 11, 12], "option": 9, "other": [13, 14], "our": [1, 8], "output": 20, "overview": 0, "overwhelm": 2, "own": [9, 14], "panel": 17, "part": 13, "particip": 6, "peopl": 13, "perspect": [10, 13, 14], "philosophi": [10, 19], "point": 6, "poll": 10, "portrait": 14, "post": 2, "practic": [2, 10], "practition": 1, "prepar": [6, 10, 14], "present": [0, 9], "primari": 20, "privaci": 2, "problem": [8, 16], "process": [8, 9], "project": 1, "prompt": 14, "prospect": 21, "q": [11, 12, 17, 21], "qualiti": [10, 14, 16], "question": [2, 5, 10, 21], "radovan": 19, "raw": 20, "razick": 19, "recommend": 16, "record": [19, 21], "relat": [1, 20], "remot": 12, "requir": 11, "resourc": [7, 8, 14], "result": 8, "richard": 19, "role": 13, "room": 10, "run": 20, "sabri": 19, "sampl": 20, "scene": 17, "schedul": 10, "scheme": 14, "screen": [10, 14], "see": [11, 18, 20], "seen": 13, "septemb": [7, 10], "sessiion": 10, "session": [6, 7, 10, 15], "set": [12, 14, 17], "setup": [10, 12, 13, 14], "share": [4, 8, 10, 14], "size": 14, "smallest": 9, "softwar": [10, 11, 12], "solut": 20, "sound": [10, 13, 16], "speak": 16, "specif": 0, "sphinx": 9, "step": 13, "stepa": 19, "stone": 13, "stream": [10, 17, 20, 21], "subtitl": 20, "summari": [0, 9, 16, 19, 20], "survei": 5, "switch": 14, "t": 2, "take": 5, "talk": 6, "target": [1, 6], "teach": [0, 4, 5, 8, 10, 14, 19], "team": [0, 13], "techniqu": 10, "templat": [2, 9], "term": 5, "termin": 14, "test": 20, "thi": [13, 20], "thing": [2, 10], "think": [3, 10], "through": [9, 12], "time": [5, 6, 13], "tip": 16, "todai": 10, "toliauta": 19, "tool": 10, "tour": 9, "train": 7, "trainer": 7, "try": 5, "typic": 8, "un": 14, "up": [12, 14, 16, 17], "us": [5, 8, 9, 20], "user": 11, "vc": 9, "version": [9, 10], "video": [10, 19, 20], "view": 19, "volum": 16, "we": [5, 8, 10, 13, 14, 20, 21], "websit": 2, "what": [11, 17, 18, 20, 21], "when": [14, 16], "whisper": 20, "who": 17, "why": [9, 10, 21], "window": 17, "work": [8, 14], "workshop": [1, 2, 5, 7, 10, 13], "would": 10, "wrapup": 10, "wrong": 17, "yaml": 20, "you": 8, "your": [5, 8, 9, 14, 20]}}) \ No newline at end of file diff --git a/branch/main/session-4-intro/index.html b/branch/main/session-4-intro/index.html new file mode 100644 index 0000000..ac8cde9 --- /dev/null +++ b/branch/main/session-4-intro/index.html @@ -0,0 +1,190 @@ + + + + + + + Session 4 intro — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Session 4 intro

+

This session covers streaming and technical production. Some +introductory notes:

+
    +
  • (As of 2024) This is the first and only comprehensive introduction +to our online streaming.

  • +
  • These practices are new and well-refined internally, but a +different kind of refinement is needed to teach and reuse them.

  • +
  • The lessons have outlines of what to talk about, but it’s just an +outline. It is not refined, since thees things are new. Many +things will have to be figured out as we talk.

  • +
  • This session is a demo of lots of basics.

    +
      +
    • Ask questions - otherwise it will be boring

    • +
    • If you want to use this in real life: you will need mentoring +sessions and active help. Contact us to do that.

    • +
    +
  • +
+
+

Warning

+

Audio and video weirdness

+

We are setting up video and audio recording, but also capturing that +for re-sharing it. There may be anomalies as video or audio +feedback. Please be prepared.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/singlehtml/_images/BYOC.png b/branch/main/singlehtml/_images/BYOC.png new file mode 100644 index 0000000..94702a1 Binary files /dev/null and b/branch/main/singlehtml/_images/BYOC.png differ diff --git a/branch/main/singlehtml/_images/CR_workshop_setup.png b/branch/main/singlehtml/_images/CR_workshop_setup.png new file mode 100644 index 0000000..47b4502 Binary files /dev/null and b/branch/main/singlehtml/_images/CR_workshop_setup.png differ diff --git a/branch/main/singlehtml/_images/community.png b/branch/main/singlehtml/_images/community.png new file mode 100644 index 0000000..ddd9a62 Binary files /dev/null and b/branch/main/singlehtml/_images/community.png differ diff --git a/branch/main/singlehtml/_images/hackmd--controls.png b/branch/main/singlehtml/_images/hackmd--controls.png new file mode 100644 index 0000000..46a74c7 Binary files /dev/null and b/branch/main/singlehtml/_images/hackmd--controls.png differ diff --git a/branch/main/singlehtml/_images/hackmd--full-demo.png b/branch/main/singlehtml/_images/hackmd--full-demo.png new file mode 100644 index 0000000..0988b6f Binary files /dev/null and b/branch/main/singlehtml/_images/hackmd--full-demo.png differ diff --git a/branch/main/singlehtml/_images/hackmd--questions2.png b/branch/main/singlehtml/_images/hackmd--questions2.png new file mode 100644 index 0000000..a609199 Binary files /dev/null and b/branch/main/singlehtml/_images/hackmd--questions2.png differ diff --git a/branch/main/singlehtml/_images/history-landscape-dark.png b/branch/main/singlehtml/_images/history-landscape-dark.png new file mode 100644 index 0000000..a1aef3c Binary files /dev/null and b/branch/main/singlehtml/_images/history-landscape-dark.png differ diff --git a/branch/main/singlehtml/_images/history-portrait-dark.png b/branch/main/singlehtml/_images/history-portrait-dark.png new file mode 100644 index 0000000..2fc1fa6 Binary files /dev/null and b/branch/main/singlehtml/_images/history-portrait-dark.png differ diff --git a/branch/main/singlehtml/_images/history-portrait-light.png b/branch/main/singlehtml/_images/history-portrait-light.png new file mode 100644 index 0000000..5f4361c Binary files /dev/null and b/branch/main/singlehtml/_images/history-portrait-light.png differ diff --git a/branch/main/singlehtml/_images/history-portrait.png b/branch/main/singlehtml/_images/history-portrait.png new file mode 100644 index 0000000..28e18b0 Binary files /dev/null and b/branch/main/singlehtml/_images/history-portrait.png differ diff --git a/branch/main/singlehtml/_images/history-rsh.png b/branch/main/singlehtml/_images/history-rsh.png new file mode 100644 index 0000000..1bbb1cc Binary files /dev/null and b/branch/main/singlehtml/_images/history-rsh.png differ diff --git a/branch/main/singlehtml/_images/instructor.png b/branch/main/singlehtml/_images/instructor.png new file mode 100644 index 0000000..718f2a8 Binary files /dev/null and b/branch/main/singlehtml/_images/instructor.png differ diff --git a/branch/main/singlehtml/_images/landscape.png b/branch/main/singlehtml/_images/landscape.png new file mode 100644 index 0000000..eda9d42 Binary files /dev/null and b/branch/main/singlehtml/_images/landscape.png differ diff --git a/branch/main/singlehtml/_images/learner-large.png b/branch/main/singlehtml/_images/learner-large.png new file mode 100644 index 0000000..3b6d2cd Binary files /dev/null and b/branch/main/singlehtml/_images/learner-large.png differ diff --git a/branch/main/singlehtml/_images/learner-normal.png b/branch/main/singlehtml/_images/learner-normal.png new file mode 100644 index 0000000..590135e Binary files /dev/null and b/branch/main/singlehtml/_images/learner-normal.png differ diff --git a/branch/main/singlehtml/_images/learner-small.png b/branch/main/singlehtml/_images/learner-small.png new file mode 100644 index 0000000..5d5f421 Binary files /dev/null and b/branch/main/singlehtml/_images/learner-small.png differ diff --git a/branch/main/singlehtml/_images/portrait.png b/branch/main/singlehtml/_images/portrait.png new file mode 100644 index 0000000..415799f Binary files /dev/null and b/branch/main/singlehtml/_images/portrait.png differ diff --git a/branch/main/singlehtml/_images/steps.png b/branch/main/singlehtml/_images/steps.png new file mode 100644 index 0000000..6c978b5 Binary files /dev/null and b/branch/main/singlehtml/_images/steps.png differ diff --git a/branch/main/singlehtml/_images/survey-impact1.png b/branch/main/singlehtml/_images/survey-impact1.png new file mode 100644 index 0000000..7dd0ddc Binary files /dev/null and b/branch/main/singlehtml/_images/survey-impact1.png differ diff --git a/branch/main/singlehtml/_images/survey-impact2.png b/branch/main/singlehtml/_images/survey-impact2.png new file mode 100644 index 0000000..8771bff Binary files /dev/null and b/branch/main/singlehtml/_images/survey-impact2.png differ diff --git a/branch/main/singlehtml/_images/welcome.png b/branch/main/singlehtml/_images/welcome.png new file mode 100644 index 0000000..302082c Binary files /dev/null and b/branch/main/singlehtml/_images/welcome.png differ diff --git a/branch/main/singlehtml/_sphinx_design_static/design-tabs.js b/branch/main/singlehtml/_sphinx_design_static/design-tabs.js new file mode 100644 index 0000000..b25bd6a --- /dev/null +++ b/branch/main/singlehtml/_sphinx_design_static/design-tabs.js @@ -0,0 +1,101 @@ +// @ts-check + +// Extra JS capability for selected tabs to be synced +// The selection is stored in local storage so that it persists across page loads. + +/** + * @type {Record} + */ +let sd_id_to_elements = {}; +const storageKeyPrefix = "sphinx-design-tab-id-"; + +/** + * Create a key for a tab element. + * @param {HTMLElement} el - The tab element. + * @returns {[string, string, string] | null} - The key. + * + */ +function create_key(el) { + let syncId = el.getAttribute("data-sync-id"); + let syncGroup = el.getAttribute("data-sync-group"); + if (!syncId || !syncGroup) return null; + return [syncGroup, syncId, syncGroup + "--" + syncId]; +} + +/** + * Initialize the tab selection. + * + */ +function ready() { + // Find all tabs with sync data + + /** @type {string[]} */ + let groups = []; + + document.querySelectorAll(".sd-tab-label").forEach((label) => { + if (label instanceof HTMLElement) { + let data = create_key(label); + if (data) { + let [group, id, key] = data; + + // add click event listener + // @ts-ignore + label.onclick = onSDLabelClick; + + // store map of key to elements + if (!sd_id_to_elements[key]) { + sd_id_to_elements[key] = []; + } + sd_id_to_elements[key].push(label); + + if (groups.indexOf(group) === -1) { + groups.push(group); + // Check if a specific tab has been selected via URL parameter + const tabParam = new URLSearchParams(window.location.search).get( + group + ); + if (tabParam) { + console.log( + "sphinx-design: Selecting tab id for group '" + + group + + "' from URL parameter: " + + tabParam + ); + window.sessionStorage.setItem(storageKeyPrefix + group, tabParam); + } + } + + // Check is a specific tab has been selected previously + let previousId = window.sessionStorage.getItem( + storageKeyPrefix + group + ); + if (previousId === id) { + // console.log( + // "sphinx-design: Selecting tab from session storage: " + id + // ); + // @ts-ignore + label.previousElementSibling.checked = true; + } + } + } + }); +} + +/** + * Activate other tabs with the same sync id. + * + * @this {HTMLElement} - The element that was clicked. + */ +function onSDLabelClick() { + let data = create_key(this); + if (!data) return; + let [group, id, key] = data; + for (const label of sd_id_to_elements[key]) { + if (label === this) continue; + // @ts-ignore + label.previousElementSibling.checked = true; + } + window.sessionStorage.setItem(storageKeyPrefix + group, id); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/branch/main/singlehtml/_sphinx_design_static/sphinx-design.min.css b/branch/main/singlehtml/_sphinx_design_static/sphinx-design.min.css new file mode 100644 index 0000000..860c36d --- /dev/null +++ b/branch/main/singlehtml/_sphinx_design_static/sphinx-design.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative;font-size:var(--sd-fontsize-dropdown)}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary.sd-summary-title{padding:.5em .6em .5em 1em;font-size:var(--sd-fontsize-dropdown-title);font-weight:var(--sd-fontweight-dropdown-title);user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;list-style:none;display:inline-flex;justify-content:space-between}details.sd-dropdown summary.sd-summary-title::-webkit-details-marker{display:none}details.sd-dropdown summary.sd-summary-title:focus{outline:none}details.sd-dropdown summary.sd-summary-title .sd-summary-icon{margin-right:.6em;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary.sd-summary-title .sd-summary-text{flex-grow:1;line-height:1.5;padding-right:.5rem}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker{pointer-events:none;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker svg{opacity:.6}details.sd-dropdown summary.sd-summary-title:hover .sd-summary-state-marker svg{opacity:1;transform:scale(1.1)}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown .sd-summary-chevron-right{transition:.25s}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-right{transform:rotate(90deg)}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-down{transform:rotate(180deg)}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-bg: rgba(0, 113, 188, 0.2);--sd-color-secondary-bg: rgba(108, 117, 125, 0.2);--sd-color-success-bg: rgba(40, 167, 69, 0.2);--sd-color-info-bg: rgba(23, 162, 184, 0.2);--sd-color-warning-bg: rgba(240, 179, 126, 0.2);--sd-color-danger-bg: rgba(220, 53, 69, 0.2);--sd-color-light-bg: rgba(248, 249, 250, 0.2);--sd-color-muted-bg: rgba(108, 117, 125, 0.2);--sd-color-dark-bg: rgba(33, 37, 41, 0.2);--sd-color-black-bg: rgba(0, 0, 0, 0.2);--sd-color-white-bg: rgba(255, 255, 255, 0.2);--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem;--sd-fontsize-dropdown: inherit;--sd-fontsize-dropdown-title: 1rem;--sd-fontweight-dropdown-title: 700} diff --git a/branch/main/singlehtml/_static/_sphinx_javascript_frameworks_compat.js b/branch/main/singlehtml/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 0000000..8141580 --- /dev/null +++ b/branch/main/singlehtml/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/branch/main/singlehtml/_static/basic.css b/branch/main/singlehtml/_static/basic.css new file mode 100644 index 0000000..f316efc --- /dev/null +++ b/branch/main/singlehtml/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/branch/main/singlehtml/_static/check-solid.svg b/branch/main/singlehtml/_static/check-solid.svg new file mode 100644 index 0000000..92fad4b --- /dev/null +++ b/branch/main/singlehtml/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/branch/main/singlehtml/_static/clipboard.min.js b/branch/main/singlehtml/_static/clipboard.min.js new file mode 100644 index 0000000..54b3c46 --- /dev/null +++ b/branch/main/singlehtml/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/branch/main/singlehtml/_static/copybutton.css b/branch/main/singlehtml/_static/copybutton.css new file mode 100644 index 0000000..f1916ec --- /dev/null +++ b/branch/main/singlehtml/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/branch/main/singlehtml/_static/copybutton.js b/branch/main/singlehtml/_static/copybutton.js new file mode 100644 index 0000000..2ea7ff3 --- /dev/null +++ b/branch/main/singlehtml/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/branch/main/singlehtml/_static/copybutton_funcs.js b/branch/main/singlehtml/_static/copybutton_funcs.js new file mode 100644 index 0000000..dbe1aaa --- /dev/null +++ b/branch/main/singlehtml/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/branch/main/singlehtml/_static/css/badge_only.css b/branch/main/singlehtml/_static/css/badge_only.css new file mode 100644 index 0000000..c718cee --- /dev/null +++ b/branch/main/singlehtml/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/branch/main/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff b/branch/main/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/branch/main/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/branch/main/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff2 b/branch/main/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/branch/main/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/branch/main/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff b/branch/main/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/branch/main/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/branch/main/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff2 b/branch/main/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/branch/main/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/branch/main/singlehtml/_static/css/fonts/fontawesome-webfont.eot b/branch/main/singlehtml/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/branch/main/singlehtml/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/branch/main/singlehtml/_static/css/fonts/fontawesome-webfont.svg b/branch/main/singlehtml/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/branch/main/singlehtml/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/branch/main/singlehtml/_static/css/fonts/fontawesome-webfont.ttf b/branch/main/singlehtml/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/branch/main/singlehtml/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/branch/main/singlehtml/_static/css/fonts/fontawesome-webfont.woff b/branch/main/singlehtml/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/branch/main/singlehtml/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/branch/main/singlehtml/_static/css/fonts/fontawesome-webfont.woff2 b/branch/main/singlehtml/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/branch/main/singlehtml/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/branch/main/singlehtml/_static/css/fonts/lato-bold-italic.woff b/branch/main/singlehtml/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/branch/main/singlehtml/_static/css/fonts/lato-bold-italic.woff differ diff --git a/branch/main/singlehtml/_static/css/fonts/lato-bold-italic.woff2 b/branch/main/singlehtml/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/branch/main/singlehtml/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/branch/main/singlehtml/_static/css/fonts/lato-bold.woff b/branch/main/singlehtml/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/branch/main/singlehtml/_static/css/fonts/lato-bold.woff differ diff --git a/branch/main/singlehtml/_static/css/fonts/lato-bold.woff2 b/branch/main/singlehtml/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/branch/main/singlehtml/_static/css/fonts/lato-bold.woff2 differ diff --git a/branch/main/singlehtml/_static/css/fonts/lato-normal-italic.woff b/branch/main/singlehtml/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/branch/main/singlehtml/_static/css/fonts/lato-normal-italic.woff differ diff --git a/branch/main/singlehtml/_static/css/fonts/lato-normal-italic.woff2 b/branch/main/singlehtml/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/branch/main/singlehtml/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/branch/main/singlehtml/_static/css/fonts/lato-normal.woff b/branch/main/singlehtml/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/branch/main/singlehtml/_static/css/fonts/lato-normal.woff differ diff --git a/branch/main/singlehtml/_static/css/fonts/lato-normal.woff2 b/branch/main/singlehtml/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/branch/main/singlehtml/_static/css/fonts/lato-normal.woff2 differ diff --git a/branch/main/singlehtml/_static/css/theme.css b/branch/main/singlehtml/_static/css/theme.css new file mode 100644 index 0000000..19a446a --- /dev/null +++ b/branch/main/singlehtml/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/branch/main/singlehtml/_static/design-tabs.js b/branch/main/singlehtml/_static/design-tabs.js new file mode 100644 index 0000000..b25bd6a --- /dev/null +++ b/branch/main/singlehtml/_static/design-tabs.js @@ -0,0 +1,101 @@ +// @ts-check + +// Extra JS capability for selected tabs to be synced +// The selection is stored in local storage so that it persists across page loads. + +/** + * @type {Record} + */ +let sd_id_to_elements = {}; +const storageKeyPrefix = "sphinx-design-tab-id-"; + +/** + * Create a key for a tab element. + * @param {HTMLElement} el - The tab element. + * @returns {[string, string, string] | null} - The key. + * + */ +function create_key(el) { + let syncId = el.getAttribute("data-sync-id"); + let syncGroup = el.getAttribute("data-sync-group"); + if (!syncId || !syncGroup) return null; + return [syncGroup, syncId, syncGroup + "--" + syncId]; +} + +/** + * Initialize the tab selection. + * + */ +function ready() { + // Find all tabs with sync data + + /** @type {string[]} */ + let groups = []; + + document.querySelectorAll(".sd-tab-label").forEach((label) => { + if (label instanceof HTMLElement) { + let data = create_key(label); + if (data) { + let [group, id, key] = data; + + // add click event listener + // @ts-ignore + label.onclick = onSDLabelClick; + + // store map of key to elements + if (!sd_id_to_elements[key]) { + sd_id_to_elements[key] = []; + } + sd_id_to_elements[key].push(label); + + if (groups.indexOf(group) === -1) { + groups.push(group); + // Check if a specific tab has been selected via URL parameter + const tabParam = new URLSearchParams(window.location.search).get( + group + ); + if (tabParam) { + console.log( + "sphinx-design: Selecting tab id for group '" + + group + + "' from URL parameter: " + + tabParam + ); + window.sessionStorage.setItem(storageKeyPrefix + group, tabParam); + } + } + + // Check is a specific tab has been selected previously + let previousId = window.sessionStorage.getItem( + storageKeyPrefix + group + ); + if (previousId === id) { + // console.log( + // "sphinx-design: Selecting tab from session storage: " + id + // ); + // @ts-ignore + label.previousElementSibling.checked = true; + } + } + } + }); +} + +/** + * Activate other tabs with the same sync id. + * + * @this {HTMLElement} - The element that was clicked. + */ +function onSDLabelClick() { + let data = create_key(this); + if (!data) return; + let [group, id, key] = data; + for (const label of sd_id_to_elements[key]) { + if (label === this) continue; + // @ts-ignore + label.previousElementSibling.checked = true; + } + window.sessionStorage.setItem(storageKeyPrefix + group, id); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/branch/main/singlehtml/_static/doctools.js b/branch/main/singlehtml/_static/doctools.js new file mode 100644 index 0000000..4d67807 --- /dev/null +++ b/branch/main/singlehtml/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/branch/main/singlehtml/_static/documentation_options.js b/branch/main/singlehtml/_static/documentation_options.js new file mode 100644 index 0000000..89003c6 --- /dev/null +++ b/branch/main/singlehtml/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'singlehtml', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/branch/main/singlehtml/_static/file.png b/branch/main/singlehtml/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/branch/main/singlehtml/_static/file.png differ diff --git a/branch/main/singlehtml/_static/jquery.js b/branch/main/singlehtml/_static/jquery.js new file mode 100644 index 0000000..c4c6022 --- /dev/null +++ b/branch/main/singlehtml/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!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(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=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,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).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 w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\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(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.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,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){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 H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.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--)b.attrHandle[n[r]]=t}function pe(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 de(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 d=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")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.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}},b.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[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.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},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),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(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.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},j=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)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(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==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(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?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{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 G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.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("(^|"+M+")"+e+"("+M+"|$)"))&&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:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.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 S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(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").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.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),m(t)&&(t=t.call(e,n,S.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)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.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"===S.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"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.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)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.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?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.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)}}),S.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){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/main/singlehtml/_static/js/html5shiv.min.js b/branch/main/singlehtml/_static/js/html5shiv.min.js new file mode 100644 index 0000000..cd1c674 --- /dev/null +++ b/branch/main/singlehtml/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/branch/main/singlehtml/_static/js/theme.js b/branch/main/singlehtml/_static/js/theme.js new file mode 100644 index 0000000..1fddb6e --- /dev/null +++ b/branch/main/singlehtml/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/branch/main/singlehtml/_static/minipres.js b/branch/main/singlehtml/_static/minipres.js new file mode 100644 index 0000000..ad11c87 --- /dev/null +++ b/branch/main/singlehtml/_static/minipres.js @@ -0,0 +1,223 @@ +// Add goTo method to elements +// http://stackoverflow.com/questions/4801655/how-to-go-to-a-specific-element-on-page +(function($) { + $.fn.goTo = function() { + $('html, body').animate({ + scrollTop: $(this).offset().top //+ 'px' + }, 'fast'); + return this; // for chaining... + } +})(jQuery); + +// NO good way to do this!. Copy a hack from here +// https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript +// https://stackoverflow.com/a/2880929 +var urlParams; +(window.onpopstate = function () { + var match, + pl = /\+/g, // Regex for replacing addition symbol with a space + search = /([^&=]+)=?([^&]*)/g, + decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, + query = window.location.search.substring(1); + urlParams = {}; + while (match = search.exec(query)) + urlParams[decode(match[1])] = decode(match[2]); +})(); + +// Select heading levels +var maxHeading = urlParams['h'] +if (maxHeading === undefined) maxHeading = 2 +var headingLevels = []; +for (h=2 ; h (sections.length-1) ) { + // if we would scroll past bottom, or above top, do nothing + return; + } + + console.log('xxxxxx'); + var targetSection = sections[targetPos]; + console.log(targetSection, typeof(targetSection)); + + // Return targetSection top and height + var secProperties = section_top_and_height(targetSection); + var top = secProperties['top']; + var height = secProperties['height'] + var win_height = window.innerHeight; + //console.info(top, height, win_height) + + var scroll_to = 0; + if (height >= win_height || height == 0) { + scroll_to = top; + } else { + scroll_to = top - (win_height-height)/3.; + } + //console.info(top, height, win_height, scroll_to) + + $('html, body').animate({ + scrollTop: scroll_to //+ 'px' + }, 'fast'); + +} + + +function minipres() { + /* Enable the minipres mode: + - call the hide() function + - set up the scrolling listener + */ + document.addEventListener('keydown', function (event) { + switch(event.which) { + case 37: // left + switch_slide(-1); + event.preventDefault(); + return false; + break; + //case 38: // up + case 39: // right + switch_slide(+1); + event.preventDefault(); + return false; + break; + //case 40: // down + default: + return; // exit this handler for other keys + } + }, true) + + hide() + + // Increase space between sections + //$("div .section").css('margin-bottom', '50%'); + $(sectionSelector).css('margin-top', '50%'); + + // Reduce size/color of other sections + if (hiddenSectionSelector.length > 0) { + var hideNodes = $(hiddenSectionSelector); + console.log(typeof hideNodes, hideNodes); + for (node in hideNodes) { + console.log("a", typeof node, node); + node = hideNodes[node]; // what's right way to iterate values? + console.log("b", typeof node, node); + if (node.parentNode && node.parentNode.className == "section") { + node = node.parentNode; + console.log("c", typeof node, node); + //node.css['transform'] = 'scale(.5)'; + //node.css['transform-origin'] = 'top center'; + $(node).css('color', 'lightgrey'); + //$(node).css('font-size', '20%'); + //$(node).css('visibility', 'collapse'); + //ntahousnatouhasno; + } + } + } +} + +function hide() { + /* Hide all non-essential elements on the page + */ + + // This is for sphinx_rst_theme and readthedocs + $(".wy-nav-side").remove(); + $(".wy-nav-content-wrap").css('margin-left', 0); + $('.rst-versions').remove(); // readthedocs version selector + + // Add other formats here. +} + + +var slideshow = minipres; + +if (window.location.search.match(/[?&](minipres|slideshow|pres)([=&]|$)/) ) { + //minipres() + window.addEventListener("load", minipres); +} else if (window.location.search.match(/[?&](plain)([=&]|$)/) ) { + window.addEventListener("load", hide); +} diff --git a/branch/main/singlehtml/_static/minus.png b/branch/main/singlehtml/_static/minus.png new file mode 100644 index 0000000..d96755f Binary files /dev/null and b/branch/main/singlehtml/_static/minus.png differ diff --git a/branch/main/singlehtml/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css b/branch/main/singlehtml/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css new file mode 100644 index 0000000..3356631 --- /dev/null +++ b/branch/main/singlehtml/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css @@ -0,0 +1,2342 @@ +/* Variables */ +:root { + --mystnb-source-bg-color: #f7f7f7; + --mystnb-stdout-bg-color: #fcfcfc; + --mystnb-stderr-bg-color: #fdd; + --mystnb-traceback-bg-color: #fcfcfc; + --mystnb-source-border-color: #ccc; + --mystnb-source-margin-color: green; + --mystnb-stdout-border-color: #f7f7f7; + --mystnb-stderr-border-color: #f7f7f7; + --mystnb-traceback-border-color: #ffd6d6; + --mystnb-hide-prompt-opacity: 70%; + --mystnb-source-border-radius: .4em; + --mystnb-source-border-width: 1px; +} + +/* Whole cell */ +div.container.cell { + padding-left: 0; + margin-bottom: 1em; +} + +/* Removing all background formatting so we can control at the div level */ +.cell_input div.highlight, +.cell_output pre, +.cell_input pre, +.cell_output .output { + border: none; + box-shadow: none; +} + +.cell_output .output pre, +.cell_input pre { + margin: 0px; +} + +/* Input cells */ +div.cell div.cell_input, +div.cell details.above-input>summary { + padding-left: 0em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + background-color: var(--mystnb-source-bg-color); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; + border-radius: var(--mystnb-source-border-radius); +} + +div.cell_input>div, +div.cell_output div.output>div.highlight { + margin: 0em !important; + border: none !important; +} + +/* All cell outputs */ +.cell_output { + padding-left: 1em; + padding-right: 0em; + margin-top: 1em; +} + +/* Text outputs from cells */ +.cell_output .output.text_plain, +.cell_output .output.traceback, +.cell_output .output.stream, +.cell_output .output.stderr { + margin-top: 1em; + margin-bottom: 0em; + box-shadow: none; +} + +.cell_output .output.text_plain, +.cell_output .output.stream { + background: var(--mystnb-stdout-bg-color); + border: 1px solid var(--mystnb-stdout-border-color); +} + +.cell_output .output.stderr { + background: var(--mystnb-stderr-bg-color); + border: 1px solid var(--mystnb-stderr-border-color); +} + +.cell_output .output.traceback { + background: var(--mystnb-traceback-bg-color); + border: 1px solid var(--mystnb-traceback-border-color); +} + +/* Collapsible cell content */ +div.cell details.above-input div.cell_input { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-top: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; +} + +div.cell div.cell_input.above-output-prompt { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +div.cell details.above-input>summary { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; + padding-left: 1em; + margin-bottom: 0; +} + +div.cell details.above-output>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.below-input>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-top: none; + border-bottom-left-radius: var(--mystnb-source-border-radius); + border-bottom-right-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.hide>summary>span { + opacity: var(--mystnb-hide-prompt-opacity); +} + +div.cell details.hide[open]>summary>span.collapsed { + display: none; +} + +div.cell details.hide:not([open])>summary>span.expanded { + display: none; +} + +@keyframes collapsed-fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} +div.cell details.hide[open]>summary~* { + -moz-animation: collapsed-fade-in 0.3s ease-in-out; + -webkit-animation: collapsed-fade-in 0.3s ease-in-out; + animation: collapsed-fade-in 0.3s ease-in-out; +} + +/* Math align to the left */ +.cell_output .MathJax_Display { + text-align: left !important; +} + +/* Pandas tables. Pulled from the Jupyter / nbsphinx CSS */ +div.cell_output table { + border: none; + border-collapse: collapse; + border-spacing: 0; + color: black; + font-size: 1em; + table-layout: fixed; +} + +div.cell_output thead { + border-bottom: 1px solid black; + vertical-align: bottom; +} + +div.cell_output tr, +div.cell_output th, +div.cell_output td { + text-align: right; + vertical-align: middle; + padding: 0.5em 0.5em; + line-height: normal; + white-space: normal; + max-width: none; + border: none; +} + +div.cell_output th { + font-weight: bold; +} + +div.cell_output tbody tr:nth-child(odd) { + background: #f5f5f5; +} + +div.cell_output tbody tr:hover { + background: rgba(66, 165, 245, 0.2); +} + +/** source code line numbers **/ +span.linenos { + opacity: 0.5; +} + +/* Inline text from `paste` operation */ + +span.pasted-text { + font-weight: bold; +} + +span.pasted-inline img { + max-height: 2em; +} + +tbody span.pasted-inline img { + max-height: none; +} + +/* Font colors for translated ANSI escape sequences +Color values are copied from Jupyter Notebook +https://github.com/jupyter/notebook/blob/52581f8eda9b319eb0390ac77fe5903c38f81e3e/notebook/static/notebook/less/ansicolors.less#L14-L21 +Background colors from +https://nbsphinx.readthedocs.io/en/latest/code-cells.html#ANSI-Colors +*/ +div.highlight .-Color-Bold { + font-weight: bold; +} + +div.highlight .-Color[class*=-Black] { + color: #3E424D +} + +div.highlight .-Color[class*=-Red] { + color: #E75C58 +} + +div.highlight .-Color[class*=-Green] { + color: #00A250 +} + +div.highlight .-Color[class*=-Yellow] { + color: #DDB62B +} + +div.highlight .-Color[class*=-Blue] { + color: #208FFB +} + +div.highlight .-Color[class*=-Magenta] { + color: #D160C4 +} + +div.highlight .-Color[class*=-Cyan] { + color: #60C6C8 +} + +div.highlight .-Color[class*=-White] { + color: #C5C1B4 +} + +div.highlight .-Color[class*=-BGBlack] { + background-color: #3E424D +} + +div.highlight .-Color[class*=-BGRed] { + background-color: #E75C58 +} + +div.highlight .-Color[class*=-BGGreen] { + background-color: #00A250 +} + +div.highlight .-Color[class*=-BGYellow] { + background-color: #DDB62B +} + +div.highlight .-Color[class*=-BGBlue] { + background-color: #208FFB +} + +div.highlight .-Color[class*=-BGMagenta] { + background-color: #D160C4 +} + +div.highlight .-Color[class*=-BGCyan] { + background-color: #60C6C8 +} + +div.highlight .-Color[class*=-BGWhite] { + background-color: #C5C1B4 +} + +/* Font colors for 8-bit ANSI */ + +div.highlight .-Color[class*=-C0] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC0] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C1] { + color: #800000 +} + +div.highlight .-Color[class*=-BGC1] { + background-color: #800000 +} + +div.highlight .-Color[class*=-C2] { + color: #008000 +} + +div.highlight .-Color[class*=-BGC2] { + background-color: #008000 +} + +div.highlight .-Color[class*=-C3] { + color: #808000 +} + +div.highlight .-Color[class*=-BGC3] { + background-color: #808000 +} + +div.highlight .-Color[class*=-C4] { + color: #000080 +} + +div.highlight .-Color[class*=-BGC4] { + background-color: #000080 +} + +div.highlight .-Color[class*=-C5] { + color: #800080 +} + +div.highlight .-Color[class*=-BGC5] { + background-color: #800080 +} + +div.highlight .-Color[class*=-C6] { + color: #008080 +} + +div.highlight .-Color[class*=-BGC6] { + background-color: #008080 +} + +div.highlight .-Color[class*=-C7] { + color: #C0C0C0 +} + +div.highlight .-Color[class*=-BGC7] { + background-color: #C0C0C0 +} + +div.highlight .-Color[class*=-C8] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC8] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C9] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC9] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C10] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC10] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C11] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC11] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C12] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC12] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C13] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC13] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C14] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC14] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C15] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC15] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C16] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC16] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C17] { + color: #00005F +} + +div.highlight .-Color[class*=-BGC17] { + background-color: #00005F +} + +div.highlight .-Color[class*=-C18] { + color: #000087 +} + +div.highlight .-Color[class*=-BGC18] { + background-color: #000087 +} + +div.highlight .-Color[class*=-C19] { + color: #0000AF +} + +div.highlight .-Color[class*=-BGC19] { + background-color: #0000AF +} + +div.highlight .-Color[class*=-C20] { + color: #0000D7 +} + +div.highlight .-Color[class*=-BGC20] { + background-color: #0000D7 +} + +div.highlight .-Color[class*=-C21] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC21] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C22] { + color: #005F00 +} + +div.highlight .-Color[class*=-BGC22] { + background-color: #005F00 +} + +div.highlight .-Color[class*=-C23] { + color: #005F5F +} + +div.highlight .-Color[class*=-BGC23] { + background-color: #005F5F +} + +div.highlight .-Color[class*=-C24] { + color: #005F87 +} + +div.highlight .-Color[class*=-BGC24] { + background-color: #005F87 +} + +div.highlight .-Color[class*=-C25] { + color: #005FAF +} + +div.highlight .-Color[class*=-BGC25] { + background-color: #005FAF +} + +div.highlight .-Color[class*=-C26] { + color: #005FD7 +} + +div.highlight .-Color[class*=-BGC26] { + background-color: #005FD7 +} + +div.highlight .-Color[class*=-C27] { + color: #005FFF +} + +div.highlight .-Color[class*=-BGC27] { + background-color: #005FFF +} + +div.highlight .-Color[class*=-C28] { + color: #008700 +} + +div.highlight .-Color[class*=-BGC28] { + background-color: #008700 +} + +div.highlight .-Color[class*=-C29] { + color: #00875F +} + +div.highlight .-Color[class*=-BGC29] { + background-color: #00875F +} + +div.highlight .-Color[class*=-C30] { + color: #008787 +} + +div.highlight .-Color[class*=-BGC30] { + background-color: #008787 +} + +div.highlight .-Color[class*=-C31] { + color: #0087AF +} + +div.highlight .-Color[class*=-BGC31] { + background-color: #0087AF +} + +div.highlight .-Color[class*=-C32] { + color: #0087D7 +} + +div.highlight .-Color[class*=-BGC32] { + background-color: #0087D7 +} + +div.highlight .-Color[class*=-C33] { + color: #0087FF +} + +div.highlight .-Color[class*=-BGC33] { + background-color: #0087FF +} + +div.highlight .-Color[class*=-C34] { + color: #00AF00 +} + +div.highlight .-Color[class*=-BGC34] { + background-color: #00AF00 +} + +div.highlight .-Color[class*=-C35] { + color: #00AF5F +} + +div.highlight .-Color[class*=-BGC35] { + background-color: #00AF5F +} + +div.highlight .-Color[class*=-C36] { + color: #00AF87 +} + +div.highlight .-Color[class*=-BGC36] { + background-color: #00AF87 +} + +div.highlight .-Color[class*=-C37] { + color: #00AFAF +} + +div.highlight .-Color[class*=-BGC37] { + background-color: #00AFAF +} + +div.highlight .-Color[class*=-C38] { + color: #00AFD7 +} + +div.highlight .-Color[class*=-BGC38] { + background-color: #00AFD7 +} + +div.highlight .-Color[class*=-C39] { + color: #00AFFF +} + +div.highlight .-Color[class*=-BGC39] { + background-color: #00AFFF +} + +div.highlight .-Color[class*=-C40] { + color: #00D700 +} + +div.highlight .-Color[class*=-BGC40] { + background-color: #00D700 +} + +div.highlight .-Color[class*=-C41] { + color: #00D75F +} + +div.highlight .-Color[class*=-BGC41] { + background-color: #00D75F +} + +div.highlight .-Color[class*=-C42] { + color: #00D787 +} + +div.highlight .-Color[class*=-BGC42] { + background-color: #00D787 +} + +div.highlight .-Color[class*=-C43] { + color: #00D7AF +} + +div.highlight .-Color[class*=-BGC43] { + background-color: #00D7AF +} + +div.highlight .-Color[class*=-C44] { + color: #00D7D7 +} + +div.highlight .-Color[class*=-BGC44] { + background-color: #00D7D7 +} + +div.highlight .-Color[class*=-C45] { + color: #00D7FF +} + +div.highlight .-Color[class*=-BGC45] { + background-color: #00D7FF +} + +div.highlight .-Color[class*=-C46] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC46] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C47] { + color: #00FF5F +} + +div.highlight .-Color[class*=-BGC47] { + background-color: #00FF5F +} + +div.highlight .-Color[class*=-C48] { + color: #00FF87 +} + +div.highlight .-Color[class*=-BGC48] { + background-color: #00FF87 +} + +div.highlight .-Color[class*=-C49] { + color: #00FFAF +} + +div.highlight .-Color[class*=-BGC49] { + background-color: #00FFAF +} + +div.highlight .-Color[class*=-C50] { + color: #00FFD7 +} + +div.highlight .-Color[class*=-BGC50] { + background-color: #00FFD7 +} + +div.highlight .-Color[class*=-C51] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC51] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C52] { + color: #5F0000 +} + +div.highlight .-Color[class*=-BGC52] { + background-color: #5F0000 +} + +div.highlight .-Color[class*=-C53] { + color: #5F005F +} + +div.highlight .-Color[class*=-BGC53] { + background-color: #5F005F +} + +div.highlight .-Color[class*=-C54] { + color: #5F0087 +} + +div.highlight .-Color[class*=-BGC54] { + background-color: #5F0087 +} + +div.highlight .-Color[class*=-C55] { + color: #5F00AF +} + +div.highlight .-Color[class*=-BGC55] { + background-color: #5F00AF +} + +div.highlight .-Color[class*=-C56] { + color: #5F00D7 +} + +div.highlight .-Color[class*=-BGC56] { + background-color: #5F00D7 +} + +div.highlight .-Color[class*=-C57] { + color: #5F00FF +} + +div.highlight .-Color[class*=-BGC57] { + background-color: #5F00FF +} + +div.highlight .-Color[class*=-C58] { + color: #5F5F00 +} + +div.highlight .-Color[class*=-BGC58] { + background-color: #5F5F00 +} + +div.highlight .-Color[class*=-C59] { + color: #5F5F5F +} + +div.highlight .-Color[class*=-BGC59] { + background-color: #5F5F5F +} + +div.highlight .-Color[class*=-C60] { + color: #5F5F87 +} + +div.highlight .-Color[class*=-BGC60] { + background-color: #5F5F87 +} + +div.highlight .-Color[class*=-C61] { + color: #5F5FAF +} + +div.highlight .-Color[class*=-BGC61] { + background-color: #5F5FAF +} + +div.highlight .-Color[class*=-C62] { + color: #5F5FD7 +} + +div.highlight .-Color[class*=-BGC62] { + background-color: #5F5FD7 +} + +div.highlight .-Color[class*=-C63] { + color: #5F5FFF +} + +div.highlight .-Color[class*=-BGC63] { + background-color: #5F5FFF +} + +div.highlight .-Color[class*=-C64] { + color: #5F8700 +} + +div.highlight .-Color[class*=-BGC64] { + background-color: #5F8700 +} + +div.highlight .-Color[class*=-C65] { + color: #5F875F +} + +div.highlight .-Color[class*=-BGC65] { + background-color: #5F875F +} + +div.highlight .-Color[class*=-C66] { + color: #5F8787 +} + +div.highlight .-Color[class*=-BGC66] { + background-color: #5F8787 +} + +div.highlight .-Color[class*=-C67] { + color: #5F87AF +} + +div.highlight .-Color[class*=-BGC67] { + background-color: #5F87AF +} + +div.highlight .-Color[class*=-C68] { + color: #5F87D7 +} + +div.highlight .-Color[class*=-BGC68] { + background-color: #5F87D7 +} + +div.highlight .-Color[class*=-C69] { + color: #5F87FF +} + +div.highlight .-Color[class*=-BGC69] { + background-color: #5F87FF +} + +div.highlight .-Color[class*=-C70] { + color: #5FAF00 +} + +div.highlight .-Color[class*=-BGC70] { + background-color: #5FAF00 +} + +div.highlight .-Color[class*=-C71] { + color: #5FAF5F +} + +div.highlight .-Color[class*=-BGC71] { + background-color: #5FAF5F +} + +div.highlight .-Color[class*=-C72] { + color: #5FAF87 +} + +div.highlight .-Color[class*=-BGC72] { + background-color: #5FAF87 +} + +div.highlight .-Color[class*=-C73] { + color: #5FAFAF +} + +div.highlight .-Color[class*=-BGC73] { + background-color: #5FAFAF +} + +div.highlight .-Color[class*=-C74] { + color: #5FAFD7 +} + +div.highlight .-Color[class*=-BGC74] { + background-color: #5FAFD7 +} + +div.highlight .-Color[class*=-C75] { + color: #5FAFFF +} + +div.highlight .-Color[class*=-BGC75] { + background-color: #5FAFFF +} + +div.highlight .-Color[class*=-C76] { + color: #5FD700 +} + +div.highlight .-Color[class*=-BGC76] { + background-color: #5FD700 +} + +div.highlight .-Color[class*=-C77] { + color: #5FD75F +} + +div.highlight .-Color[class*=-BGC77] { + background-color: #5FD75F +} + +div.highlight .-Color[class*=-C78] { + color: #5FD787 +} + +div.highlight .-Color[class*=-BGC78] { + background-color: #5FD787 +} + +div.highlight .-Color[class*=-C79] { + color: #5FD7AF +} + +div.highlight .-Color[class*=-BGC79] { + background-color: #5FD7AF +} + +div.highlight .-Color[class*=-C80] { + color: #5FD7D7 +} + +div.highlight .-Color[class*=-BGC80] { + background-color: #5FD7D7 +} + +div.highlight .-Color[class*=-C81] { + color: #5FD7FF +} + +div.highlight .-Color[class*=-BGC81] { + background-color: #5FD7FF +} + +div.highlight .-Color[class*=-C82] { + color: #5FFF00 +} + +div.highlight .-Color[class*=-BGC82] { + background-color: #5FFF00 +} + +div.highlight .-Color[class*=-C83] { + color: #5FFF5F +} + +div.highlight .-Color[class*=-BGC83] { + background-color: #5FFF5F +} + +div.highlight .-Color[class*=-C84] { + color: #5FFF87 +} + +div.highlight .-Color[class*=-BGC84] { + background-color: #5FFF87 +} + +div.highlight .-Color[class*=-C85] { + color: #5FFFAF +} + +div.highlight .-Color[class*=-BGC85] { + background-color: #5FFFAF +} + +div.highlight .-Color[class*=-C86] { + color: #5FFFD7 +} + +div.highlight .-Color[class*=-BGC86] { + background-color: #5FFFD7 +} + +div.highlight .-Color[class*=-C87] { + color: #5FFFFF +} + +div.highlight .-Color[class*=-BGC87] { + background-color: #5FFFFF +} + +div.highlight .-Color[class*=-C88] { + color: #870000 +} + +div.highlight .-Color[class*=-BGC88] { + background-color: #870000 +} + +div.highlight .-Color[class*=-C89] { + color: #87005F +} + +div.highlight .-Color[class*=-BGC89] { + background-color: #87005F +} + +div.highlight .-Color[class*=-C90] { + color: #870087 +} + +div.highlight .-Color[class*=-BGC90] { + background-color: #870087 +} + +div.highlight .-Color[class*=-C91] { + color: #8700AF +} + +div.highlight .-Color[class*=-BGC91] { + background-color: #8700AF +} + +div.highlight .-Color[class*=-C92] { + color: #8700D7 +} + +div.highlight .-Color[class*=-BGC92] { + background-color: #8700D7 +} + +div.highlight .-Color[class*=-C93] { + color: #8700FF +} + +div.highlight .-Color[class*=-BGC93] { + background-color: #8700FF +} + +div.highlight .-Color[class*=-C94] { + color: #875F00 +} + +div.highlight .-Color[class*=-BGC94] { + background-color: #875F00 +} + +div.highlight .-Color[class*=-C95] { + color: #875F5F +} + +div.highlight .-Color[class*=-BGC95] { + background-color: #875F5F +} + +div.highlight .-Color[class*=-C96] { + color: #875F87 +} + +div.highlight .-Color[class*=-BGC96] { + background-color: #875F87 +} + +div.highlight .-Color[class*=-C97] { + color: #875FAF +} + +div.highlight .-Color[class*=-BGC97] { + background-color: #875FAF +} + +div.highlight .-Color[class*=-C98] { + color: #875FD7 +} + +div.highlight .-Color[class*=-BGC98] { + background-color: #875FD7 +} + +div.highlight .-Color[class*=-C99] { + color: #875FFF +} + +div.highlight .-Color[class*=-BGC99] { + background-color: #875FFF +} + +div.highlight .-Color[class*=-C100] { + color: #878700 +} + +div.highlight .-Color[class*=-BGC100] { + background-color: #878700 +} + +div.highlight .-Color[class*=-C101] { + color: #87875F +} + +div.highlight .-Color[class*=-BGC101] { + background-color: #87875F +} + +div.highlight .-Color[class*=-C102] { + color: #878787 +} + +div.highlight .-Color[class*=-BGC102] { + background-color: #878787 +} + +div.highlight .-Color[class*=-C103] { + color: #8787AF +} + +div.highlight .-Color[class*=-BGC103] { + background-color: #8787AF +} + +div.highlight .-Color[class*=-C104] { + color: #8787D7 +} + +div.highlight .-Color[class*=-BGC104] { + background-color: #8787D7 +} + +div.highlight .-Color[class*=-C105] { + color: #8787FF +} + +div.highlight .-Color[class*=-BGC105] { + background-color: #8787FF +} + +div.highlight .-Color[class*=-C106] { + color: #87AF00 +} + +div.highlight .-Color[class*=-BGC106] { + background-color: #87AF00 +} + +div.highlight .-Color[class*=-C107] { + color: #87AF5F +} + +div.highlight .-Color[class*=-BGC107] { + background-color: #87AF5F +} + +div.highlight .-Color[class*=-C108] { + color: #87AF87 +} + +div.highlight .-Color[class*=-BGC108] { + background-color: #87AF87 +} + +div.highlight .-Color[class*=-C109] { + color: #87AFAF +} + +div.highlight .-Color[class*=-BGC109] { + background-color: #87AFAF +} + +div.highlight .-Color[class*=-C110] { + color: #87AFD7 +} + +div.highlight .-Color[class*=-BGC110] { + background-color: #87AFD7 +} + +div.highlight .-Color[class*=-C111] { + color: #87AFFF +} + +div.highlight .-Color[class*=-BGC111] { + background-color: #87AFFF +} + +div.highlight .-Color[class*=-C112] { + color: #87D700 +} + +div.highlight .-Color[class*=-BGC112] { + background-color: #87D700 +} + +div.highlight .-Color[class*=-C113] { + color: #87D75F +} + +div.highlight .-Color[class*=-BGC113] { + background-color: #87D75F +} + +div.highlight .-Color[class*=-C114] { + color: #87D787 +} + +div.highlight .-Color[class*=-BGC114] { + background-color: #87D787 +} + +div.highlight .-Color[class*=-C115] { + color: #87D7AF +} + +div.highlight .-Color[class*=-BGC115] { + background-color: #87D7AF +} + +div.highlight .-Color[class*=-C116] { + color: #87D7D7 +} + +div.highlight .-Color[class*=-BGC116] { + background-color: #87D7D7 +} + +div.highlight .-Color[class*=-C117] { + color: #87D7FF +} + +div.highlight .-Color[class*=-BGC117] { + background-color: #87D7FF +} + +div.highlight .-Color[class*=-C118] { + color: #87FF00 +} + +div.highlight .-Color[class*=-BGC118] { + background-color: #87FF00 +} + +div.highlight .-Color[class*=-C119] { + color: #87FF5F +} + +div.highlight .-Color[class*=-BGC119] { + background-color: #87FF5F +} + +div.highlight .-Color[class*=-C120] { + color: #87FF87 +} + +div.highlight .-Color[class*=-BGC120] { + background-color: #87FF87 +} + +div.highlight .-Color[class*=-C121] { + color: #87FFAF +} + +div.highlight .-Color[class*=-BGC121] { + background-color: #87FFAF +} + +div.highlight .-Color[class*=-C122] { + color: #87FFD7 +} + +div.highlight .-Color[class*=-BGC122] { + background-color: #87FFD7 +} + +div.highlight .-Color[class*=-C123] { + color: #87FFFF +} + +div.highlight .-Color[class*=-BGC123] { + background-color: #87FFFF +} + +div.highlight .-Color[class*=-C124] { + color: #AF0000 +} + +div.highlight .-Color[class*=-BGC124] { + background-color: #AF0000 +} + +div.highlight .-Color[class*=-C125] { + color: #AF005F +} + +div.highlight .-Color[class*=-BGC125] { + background-color: #AF005F +} + +div.highlight .-Color[class*=-C126] { + color: #AF0087 +} + +div.highlight .-Color[class*=-BGC126] { + background-color: #AF0087 +} + +div.highlight .-Color[class*=-C127] { + color: #AF00AF +} + +div.highlight .-Color[class*=-BGC127] { + background-color: #AF00AF +} + +div.highlight .-Color[class*=-C128] { + color: #AF00D7 +} + +div.highlight .-Color[class*=-BGC128] { + background-color: #AF00D7 +} + +div.highlight .-Color[class*=-C129] { + color: #AF00FF +} + +div.highlight .-Color[class*=-BGC129] { + background-color: #AF00FF +} + +div.highlight .-Color[class*=-C130] { + color: #AF5F00 +} + +div.highlight .-Color[class*=-BGC130] { + background-color: #AF5F00 +} + +div.highlight .-Color[class*=-C131] { + color: #AF5F5F +} + +div.highlight .-Color[class*=-BGC131] { + background-color: #AF5F5F +} + +div.highlight .-Color[class*=-C132] { + color: #AF5F87 +} + +div.highlight .-Color[class*=-BGC132] { + background-color: #AF5F87 +} + +div.highlight .-Color[class*=-C133] { + color: #AF5FAF +} + +div.highlight .-Color[class*=-BGC133] { + background-color: #AF5FAF +} + +div.highlight .-Color[class*=-C134] { + color: #AF5FD7 +} + +div.highlight .-Color[class*=-BGC134] { + background-color: #AF5FD7 +} + +div.highlight .-Color[class*=-C135] { + color: #AF5FFF +} + +div.highlight .-Color[class*=-BGC135] { + background-color: #AF5FFF +} + +div.highlight .-Color[class*=-C136] { + color: #AF8700 +} + +div.highlight .-Color[class*=-BGC136] { + background-color: #AF8700 +} + +div.highlight .-Color[class*=-C137] { + color: #AF875F +} + +div.highlight .-Color[class*=-BGC137] { + background-color: #AF875F +} + +div.highlight .-Color[class*=-C138] { + color: #AF8787 +} + +div.highlight .-Color[class*=-BGC138] { + background-color: #AF8787 +} + +div.highlight .-Color[class*=-C139] { + color: #AF87AF +} + +div.highlight .-Color[class*=-BGC139] { + background-color: #AF87AF +} + +div.highlight .-Color[class*=-C140] { + color: #AF87D7 +} + +div.highlight .-Color[class*=-BGC140] { + background-color: #AF87D7 +} + +div.highlight .-Color[class*=-C141] { + color: #AF87FF +} + +div.highlight .-Color[class*=-BGC141] { + background-color: #AF87FF +} + +div.highlight .-Color[class*=-C142] { + color: #AFAF00 +} + +div.highlight .-Color[class*=-BGC142] { + background-color: #AFAF00 +} + +div.highlight .-Color[class*=-C143] { + color: #AFAF5F +} + +div.highlight .-Color[class*=-BGC143] { + background-color: #AFAF5F +} + +div.highlight .-Color[class*=-C144] { + color: #AFAF87 +} + +div.highlight .-Color[class*=-BGC144] { + background-color: #AFAF87 +} + +div.highlight .-Color[class*=-C145] { + color: #AFAFAF +} + +div.highlight .-Color[class*=-BGC145] { + background-color: #AFAFAF +} + +div.highlight .-Color[class*=-C146] { + color: #AFAFD7 +} + +div.highlight .-Color[class*=-BGC146] { + background-color: #AFAFD7 +} + +div.highlight .-Color[class*=-C147] { + color: #AFAFFF +} + +div.highlight .-Color[class*=-BGC147] { + background-color: #AFAFFF +} + +div.highlight .-Color[class*=-C148] { + color: #AFD700 +} + +div.highlight .-Color[class*=-BGC148] { + background-color: #AFD700 +} + +div.highlight .-Color[class*=-C149] { + color: #AFD75F +} + +div.highlight .-Color[class*=-BGC149] { + background-color: #AFD75F +} + +div.highlight .-Color[class*=-C150] { + color: #AFD787 +} + +div.highlight .-Color[class*=-BGC150] { + background-color: #AFD787 +} + +div.highlight .-Color[class*=-C151] { + color: #AFD7AF +} + +div.highlight .-Color[class*=-BGC151] { + background-color: #AFD7AF +} + +div.highlight .-Color[class*=-C152] { + color: #AFD7D7 +} + +div.highlight .-Color[class*=-BGC152] { + background-color: #AFD7D7 +} + +div.highlight .-Color[class*=-C153] { + color: #AFD7FF +} + +div.highlight .-Color[class*=-BGC153] { + background-color: #AFD7FF +} + +div.highlight .-Color[class*=-C154] { + color: #AFFF00 +} + +div.highlight .-Color[class*=-BGC154] { + background-color: #AFFF00 +} + +div.highlight .-Color[class*=-C155] { + color: #AFFF5F +} + +div.highlight .-Color[class*=-BGC155] { + background-color: #AFFF5F +} + +div.highlight .-Color[class*=-C156] { + color: #AFFF87 +} + +div.highlight .-Color[class*=-BGC156] { + background-color: #AFFF87 +} + +div.highlight .-Color[class*=-C157] { + color: #AFFFAF +} + +div.highlight .-Color[class*=-BGC157] { + background-color: #AFFFAF +} + +div.highlight .-Color[class*=-C158] { + color: #AFFFD7 +} + +div.highlight .-Color[class*=-BGC158] { + background-color: #AFFFD7 +} + +div.highlight .-Color[class*=-C159] { + color: #AFFFFF +} + +div.highlight .-Color[class*=-BGC159] { + background-color: #AFFFFF +} + +div.highlight .-Color[class*=-C160] { + color: #D70000 +} + +div.highlight .-Color[class*=-BGC160] { + background-color: #D70000 +} + +div.highlight .-Color[class*=-C161] { + color: #D7005F +} + +div.highlight .-Color[class*=-BGC161] { + background-color: #D7005F +} + +div.highlight .-Color[class*=-C162] { + color: #D70087 +} + +div.highlight .-Color[class*=-BGC162] { + background-color: #D70087 +} + +div.highlight .-Color[class*=-C163] { + color: #D700AF +} + +div.highlight .-Color[class*=-BGC163] { + background-color: #D700AF +} + +div.highlight .-Color[class*=-C164] { + color: #D700D7 +} + +div.highlight .-Color[class*=-BGC164] { + background-color: #D700D7 +} + +div.highlight .-Color[class*=-C165] { + color: #D700FF +} + +div.highlight .-Color[class*=-BGC165] { + background-color: #D700FF +} + +div.highlight .-Color[class*=-C166] { + color: #D75F00 +} + +div.highlight .-Color[class*=-BGC166] { + background-color: #D75F00 +} + +div.highlight .-Color[class*=-C167] { + color: #D75F5F +} + +div.highlight .-Color[class*=-BGC167] { + background-color: #D75F5F +} + +div.highlight .-Color[class*=-C168] { + color: #D75F87 +} + +div.highlight .-Color[class*=-BGC168] { + background-color: #D75F87 +} + +div.highlight .-Color[class*=-C169] { + color: #D75FAF +} + +div.highlight .-Color[class*=-BGC169] { + background-color: #D75FAF +} + +div.highlight .-Color[class*=-C170] { + color: #D75FD7 +} + +div.highlight .-Color[class*=-BGC170] { + background-color: #D75FD7 +} + +div.highlight .-Color[class*=-C171] { + color: #D75FFF +} + +div.highlight .-Color[class*=-BGC171] { + background-color: #D75FFF +} + +div.highlight .-Color[class*=-C172] { + color: #D78700 +} + +div.highlight .-Color[class*=-BGC172] { + background-color: #D78700 +} + +div.highlight .-Color[class*=-C173] { + color: #D7875F +} + +div.highlight .-Color[class*=-BGC173] { + background-color: #D7875F +} + +div.highlight .-Color[class*=-C174] { + color: #D78787 +} + +div.highlight .-Color[class*=-BGC174] { + background-color: #D78787 +} + +div.highlight .-Color[class*=-C175] { + color: #D787AF +} + +div.highlight .-Color[class*=-BGC175] { + background-color: #D787AF +} + +div.highlight .-Color[class*=-C176] { + color: #D787D7 +} + +div.highlight .-Color[class*=-BGC176] { + background-color: #D787D7 +} + +div.highlight .-Color[class*=-C177] { + color: #D787FF +} + +div.highlight .-Color[class*=-BGC177] { + background-color: #D787FF +} + +div.highlight .-Color[class*=-C178] { + color: #D7AF00 +} + +div.highlight .-Color[class*=-BGC178] { + background-color: #D7AF00 +} + +div.highlight .-Color[class*=-C179] { + color: #D7AF5F +} + +div.highlight .-Color[class*=-BGC179] { + background-color: #D7AF5F +} + +div.highlight .-Color[class*=-C180] { + color: #D7AF87 +} + +div.highlight .-Color[class*=-BGC180] { + background-color: #D7AF87 +} + +div.highlight .-Color[class*=-C181] { + color: #D7AFAF +} + +div.highlight .-Color[class*=-BGC181] { + background-color: #D7AFAF +} + +div.highlight .-Color[class*=-C182] { + color: #D7AFD7 +} + +div.highlight .-Color[class*=-BGC182] { + background-color: #D7AFD7 +} + +div.highlight .-Color[class*=-C183] { + color: #D7AFFF +} + +div.highlight .-Color[class*=-BGC183] { + background-color: #D7AFFF +} + +div.highlight .-Color[class*=-C184] { + color: #D7D700 +} + +div.highlight .-Color[class*=-BGC184] { + background-color: #D7D700 +} + +div.highlight .-Color[class*=-C185] { + color: #D7D75F +} + +div.highlight .-Color[class*=-BGC185] { + background-color: #D7D75F +} + +div.highlight .-Color[class*=-C186] { + color: #D7D787 +} + +div.highlight .-Color[class*=-BGC186] { + background-color: #D7D787 +} + +div.highlight .-Color[class*=-C187] { + color: #D7D7AF +} + +div.highlight .-Color[class*=-BGC187] { + background-color: #D7D7AF +} + +div.highlight .-Color[class*=-C188] { + color: #D7D7D7 +} + +div.highlight .-Color[class*=-BGC188] { + background-color: #D7D7D7 +} + +div.highlight .-Color[class*=-C189] { + color: #D7D7FF +} + +div.highlight .-Color[class*=-BGC189] { + background-color: #D7D7FF +} + +div.highlight .-Color[class*=-C190] { + color: #D7FF00 +} + +div.highlight .-Color[class*=-BGC190] { + background-color: #D7FF00 +} + +div.highlight .-Color[class*=-C191] { + color: #D7FF5F +} + +div.highlight .-Color[class*=-BGC191] { + background-color: #D7FF5F +} + +div.highlight .-Color[class*=-C192] { + color: #D7FF87 +} + +div.highlight .-Color[class*=-BGC192] { + background-color: #D7FF87 +} + +div.highlight .-Color[class*=-C193] { + color: #D7FFAF +} + +div.highlight .-Color[class*=-BGC193] { + background-color: #D7FFAF +} + +div.highlight .-Color[class*=-C194] { + color: #D7FFD7 +} + +div.highlight .-Color[class*=-BGC194] { + background-color: #D7FFD7 +} + +div.highlight .-Color[class*=-C195] { + color: #D7FFFF +} + +div.highlight .-Color[class*=-BGC195] { + background-color: #D7FFFF +} + +div.highlight .-Color[class*=-C196] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC196] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C197] { + color: #FF005F +} + +div.highlight .-Color[class*=-BGC197] { + background-color: #FF005F +} + +div.highlight .-Color[class*=-C198] { + color: #FF0087 +} + +div.highlight .-Color[class*=-BGC198] { + background-color: #FF0087 +} + +div.highlight .-Color[class*=-C199] { + color: #FF00AF +} + +div.highlight .-Color[class*=-BGC199] { + background-color: #FF00AF +} + +div.highlight .-Color[class*=-C200] { + color: #FF00D7 +} + +div.highlight .-Color[class*=-BGC200] { + background-color: #FF00D7 +} + +div.highlight .-Color[class*=-C201] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC201] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C202] { + color: #FF5F00 +} + +div.highlight .-Color[class*=-BGC202] { + background-color: #FF5F00 +} + +div.highlight .-Color[class*=-C203] { + color: #FF5F5F +} + +div.highlight .-Color[class*=-BGC203] { + background-color: #FF5F5F +} + +div.highlight .-Color[class*=-C204] { + color: #FF5F87 +} + +div.highlight .-Color[class*=-BGC204] { + background-color: #FF5F87 +} + +div.highlight .-Color[class*=-C205] { + color: #FF5FAF +} + +div.highlight .-Color[class*=-BGC205] { + background-color: #FF5FAF +} + +div.highlight .-Color[class*=-C206] { + color: #FF5FD7 +} + +div.highlight .-Color[class*=-BGC206] { + background-color: #FF5FD7 +} + +div.highlight .-Color[class*=-C207] { + color: #FF5FFF +} + +div.highlight .-Color[class*=-BGC207] { + background-color: #FF5FFF +} + +div.highlight .-Color[class*=-C208] { + color: #FF8700 +} + +div.highlight .-Color[class*=-BGC208] { + background-color: #FF8700 +} + +div.highlight .-Color[class*=-C209] { + color: #FF875F +} + +div.highlight .-Color[class*=-BGC209] { + background-color: #FF875F +} + +div.highlight .-Color[class*=-C210] { + color: #FF8787 +} + +div.highlight .-Color[class*=-BGC210] { + background-color: #FF8787 +} + +div.highlight .-Color[class*=-C211] { + color: #FF87AF +} + +div.highlight .-Color[class*=-BGC211] { + background-color: #FF87AF +} + +div.highlight .-Color[class*=-C212] { + color: #FF87D7 +} + +div.highlight .-Color[class*=-BGC212] { + background-color: #FF87D7 +} + +div.highlight .-Color[class*=-C213] { + color: #FF87FF +} + +div.highlight .-Color[class*=-BGC213] { + background-color: #FF87FF +} + +div.highlight .-Color[class*=-C214] { + color: #FFAF00 +} + +div.highlight .-Color[class*=-BGC214] { + background-color: #FFAF00 +} + +div.highlight .-Color[class*=-C215] { + color: #FFAF5F +} + +div.highlight .-Color[class*=-BGC215] { + background-color: #FFAF5F +} + +div.highlight .-Color[class*=-C216] { + color: #FFAF87 +} + +div.highlight .-Color[class*=-BGC216] { + background-color: #FFAF87 +} + +div.highlight .-Color[class*=-C217] { + color: #FFAFAF +} + +div.highlight .-Color[class*=-BGC217] { + background-color: #FFAFAF +} + +div.highlight .-Color[class*=-C218] { + color: #FFAFD7 +} + +div.highlight .-Color[class*=-BGC218] { + background-color: #FFAFD7 +} + +div.highlight .-Color[class*=-C219] { + color: #FFAFFF +} + +div.highlight .-Color[class*=-BGC219] { + background-color: #FFAFFF +} + +div.highlight .-Color[class*=-C220] { + color: #FFD700 +} + +div.highlight .-Color[class*=-BGC220] { + background-color: #FFD700 +} + +div.highlight .-Color[class*=-C221] { + color: #FFD75F +} + +div.highlight .-Color[class*=-BGC221] { + background-color: #FFD75F +} + +div.highlight .-Color[class*=-C222] { + color: #FFD787 +} + +div.highlight .-Color[class*=-BGC222] { + background-color: #FFD787 +} + +div.highlight .-Color[class*=-C223] { + color: #FFD7AF +} + +div.highlight .-Color[class*=-BGC223] { + background-color: #FFD7AF +} + +div.highlight .-Color[class*=-C224] { + color: #FFD7D7 +} + +div.highlight .-Color[class*=-BGC224] { + background-color: #FFD7D7 +} + +div.highlight .-Color[class*=-C225] { + color: #FFD7FF +} + +div.highlight .-Color[class*=-BGC225] { + background-color: #FFD7FF +} + +div.highlight .-Color[class*=-C226] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC226] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C227] { + color: #FFFF5F +} + +div.highlight .-Color[class*=-BGC227] { + background-color: #FFFF5F +} + +div.highlight .-Color[class*=-C228] { + color: #FFFF87 +} + +div.highlight .-Color[class*=-BGC228] { + background-color: #FFFF87 +} + +div.highlight .-Color[class*=-C229] { + color: #FFFFAF +} + +div.highlight .-Color[class*=-BGC229] { + background-color: #FFFFAF +} + +div.highlight .-Color[class*=-C230] { + color: #FFFFD7 +} + +div.highlight .-Color[class*=-BGC230] { + background-color: #FFFFD7 +} + +div.highlight .-Color[class*=-C231] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC231] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C232] { + color: #080808 +} + +div.highlight .-Color[class*=-BGC232] { + background-color: #080808 +} + +div.highlight .-Color[class*=-C233] { + color: #121212 +} + +div.highlight .-Color[class*=-BGC233] { + background-color: #121212 +} + +div.highlight .-Color[class*=-C234] { + color: #1C1C1C +} + +div.highlight .-Color[class*=-BGC234] { + background-color: #1C1C1C +} + +div.highlight .-Color[class*=-C235] { + color: #262626 +} + +div.highlight .-Color[class*=-BGC235] { + background-color: #262626 +} + +div.highlight .-Color[class*=-C236] { + color: #303030 +} + +div.highlight .-Color[class*=-BGC236] { + background-color: #303030 +} + +div.highlight .-Color[class*=-C237] { + color: #3A3A3A +} + +div.highlight .-Color[class*=-BGC237] { + background-color: #3A3A3A +} + +div.highlight .-Color[class*=-C238] { + color: #444444 +} + +div.highlight .-Color[class*=-BGC238] { + background-color: #444444 +} + +div.highlight .-Color[class*=-C239] { + color: #4E4E4E +} + +div.highlight .-Color[class*=-BGC239] { + background-color: #4E4E4E +} + +div.highlight .-Color[class*=-C240] { + color: #585858 +} + +div.highlight .-Color[class*=-BGC240] { + background-color: #585858 +} + +div.highlight .-Color[class*=-C241] { + color: #626262 +} + +div.highlight .-Color[class*=-BGC241] { + background-color: #626262 +} + +div.highlight .-Color[class*=-C242] { + color: #6C6C6C +} + +div.highlight .-Color[class*=-BGC242] { + background-color: #6C6C6C +} + +div.highlight .-Color[class*=-C243] { + color: #767676 +} + +div.highlight .-Color[class*=-BGC243] { + background-color: #767676 +} + +div.highlight .-Color[class*=-C244] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC244] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C245] { + color: #8A8A8A +} + +div.highlight .-Color[class*=-BGC245] { + background-color: #8A8A8A +} + +div.highlight .-Color[class*=-C246] { + color: #949494 +} + +div.highlight .-Color[class*=-BGC246] { + background-color: #949494 +} + +div.highlight .-Color[class*=-C247] { + color: #9E9E9E +} + +div.highlight .-Color[class*=-BGC247] { + background-color: #9E9E9E +} + +div.highlight .-Color[class*=-C248] { + color: #A8A8A8 +} + +div.highlight .-Color[class*=-BGC248] { + background-color: #A8A8A8 +} + +div.highlight .-Color[class*=-C249] { + color: #B2B2B2 +} + +div.highlight .-Color[class*=-BGC249] { + background-color: #B2B2B2 +} + +div.highlight .-Color[class*=-C250] { + color: #BCBCBC +} + +div.highlight .-Color[class*=-BGC250] { + background-color: #BCBCBC +} + +div.highlight .-Color[class*=-C251] { + color: #C6C6C6 +} + +div.highlight .-Color[class*=-BGC251] { + background-color: #C6C6C6 +} + +div.highlight .-Color[class*=-C252] { + color: #D0D0D0 +} + +div.highlight .-Color[class*=-BGC252] { + background-color: #D0D0D0 +} + +div.highlight .-Color[class*=-C253] { + color: #DADADA +} + +div.highlight .-Color[class*=-BGC253] { + background-color: #DADADA +} + +div.highlight .-Color[class*=-C254] { + color: #E4E4E4 +} + +div.highlight .-Color[class*=-BGC254] { + background-color: #E4E4E4 +} + +div.highlight .-Color[class*=-C255] { + color: #EEEEEE +} + +div.highlight .-Color[class*=-BGC255] { + background-color: #EEEEEE +} diff --git a/branch/main/singlehtml/_static/plus.png b/branch/main/singlehtml/_static/plus.png new file mode 100644 index 0000000..7107cec Binary files /dev/null and b/branch/main/singlehtml/_static/plus.png differ diff --git a/branch/main/singlehtml/_static/pygments.css b/branch/main/singlehtml/_static/pygments.css new file mode 100644 index 0000000..84ab303 --- /dev/null +++ b/branch/main/singlehtml/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/branch/main/singlehtml/_static/searchtools.js b/branch/main/singlehtml/_static/searchtools.js new file mode 100644 index 0000000..b08d58c --- /dev/null +++ b/branch/main/singlehtml/_static/searchtools.js @@ -0,0 +1,620 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/branch/main/singlehtml/_static/sphinx-design.min.css b/branch/main/singlehtml/_static/sphinx-design.min.css new file mode 100644 index 0000000..860c36d --- /dev/null +++ b/branch/main/singlehtml/_static/sphinx-design.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative;font-size:var(--sd-fontsize-dropdown)}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary.sd-summary-title{padding:.5em .6em .5em 1em;font-size:var(--sd-fontsize-dropdown-title);font-weight:var(--sd-fontweight-dropdown-title);user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;list-style:none;display:inline-flex;justify-content:space-between}details.sd-dropdown summary.sd-summary-title::-webkit-details-marker{display:none}details.sd-dropdown summary.sd-summary-title:focus{outline:none}details.sd-dropdown summary.sd-summary-title .sd-summary-icon{margin-right:.6em;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary.sd-summary-title .sd-summary-text{flex-grow:1;line-height:1.5;padding-right:.5rem}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker{pointer-events:none;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker svg{opacity:.6}details.sd-dropdown summary.sd-summary-title:hover .sd-summary-state-marker svg{opacity:1;transform:scale(1.1)}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown .sd-summary-chevron-right{transition:.25s}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-right{transform:rotate(90deg)}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-down{transform:rotate(180deg)}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-bg: rgba(0, 113, 188, 0.2);--sd-color-secondary-bg: rgba(108, 117, 125, 0.2);--sd-color-success-bg: rgba(40, 167, 69, 0.2);--sd-color-info-bg: rgba(23, 162, 184, 0.2);--sd-color-warning-bg: rgba(240, 179, 126, 0.2);--sd-color-danger-bg: rgba(220, 53, 69, 0.2);--sd-color-light-bg: rgba(248, 249, 250, 0.2);--sd-color-muted-bg: rgba(108, 117, 125, 0.2);--sd-color-dark-bg: rgba(33, 37, 41, 0.2);--sd-color-black-bg: rgba(0, 0, 0, 0.2);--sd-color-white-bg: rgba(255, 255, 255, 0.2);--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem;--sd-fontsize-dropdown: inherit;--sd-fontsize-dropdown-title: 1rem;--sd-fontweight-dropdown-title: 700} diff --git a/branch/main/singlehtml/_static/sphinx_highlight.js b/branch/main/singlehtml/_static/sphinx_highlight.js new file mode 100644 index 0000000..8a96c69 --- /dev/null +++ b/branch/main/singlehtml/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/branch/main/singlehtml/_static/sphinx_lesson.css b/branch/main/singlehtml/_static/sphinx_lesson.css new file mode 100644 index 0000000..14b20c6 --- /dev/null +++ b/branch/main/singlehtml/_static/sphinx_lesson.css @@ -0,0 +1,51 @@ +/* sphinx_lesson.css */ + +body.wy-body-for-nav img.with-border { + border: 2px solid; +} + +.rst-content .admonition-no-content { + padding-bottom: 0px; +} + +.rst-content .demo > .admonition-title::before { + content: "\01F440"; /* Eyes */ } +.rst-content .type-along > .admonition-title::before { + content: "\02328\0FE0F"; /* Keyboard */ } +.rst-content .exercise > .admonition-title::before { + content: "\0270D\0FE0F"; /* Hand */ } +.rst-content .solution > .admonition-title::before { + content: "\02714\0FE0E"; /* Check mark */ } +.rst-content .homework > .admonition-title::before { + content: "\01F4DD"; /* Memo */ } +.rst-content .discussion > .admonition-title::before { + content: "\01F4AC"; /* Speech balloon */ } +.rst-content .questions > .admonition-title::before { + content: "\02753\0FE0E"; /* Question mark */ } +.rst-content .prerequisites > .admonition-title::before { + content: "\02699"; /* Gear */ } +.rst-content .seealso > .admonition-title::before { + content: "\027A1\0FE0E"; /* Question mark */ } + + +/* instructor-note */ +.rst-content .instructor-note { + background: #e7e7e7; +} +.rst-content .instructor-note > .admonition-title { + background: #6a6a6a; +} +.rst-content .instructor-note > .admonition-title::before { + content: ""; +} + + +/* sphinx_toggle_button, make the font white */ +.rst-content .toggle.admonition button.toggle-button { + color: white; +} + +/* sphinx-togglebutton, remove underflow when toggled to hidden mode */ +.rst-content .admonition.toggle-hidden { + padding-bottom: 0px; +} diff --git a/branch/main/singlehtml/_static/sphinx_rtd_theme_ext_color_contrast.css b/branch/main/singlehtml/_static/sphinx_rtd_theme_ext_color_contrast.css new file mode 100644 index 0000000..e68feb8 --- /dev/null +++ b/branch/main/singlehtml/_static/sphinx_rtd_theme_ext_color_contrast.css @@ -0,0 +1,47 @@ +/* The following are for web accessibility of sphinx_rtd_theme: they + * solve some of the most frequent contrast issues. Remove when this + * solved: + * https://github.com/readthedocs/sphinx_rtd_theme/issues/971 + */ +/* background: #fcfcfc, note boxes #E7F2FA */ +a { color: #2573A7; } /* original #2980B9, #1F5C84; */ +body { color: #242424; } /* original #404040, #383838 */ +.wy-side-nav-search>a, .wy-side-nav-search .wy-dropdown>a { + color: #ffffff; +} /* original #fcfcfc */ +footer { color: #737373; } /* original gray=#808080*/ +footer span.commit code, footer span.commit .rst-content tt, .rst-content footer span.commit tt { + color: #737373; +} /* original gray=#808080*/ +.rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal { + color: #AB2314; +} +/* Sidebar background */ +.wy-side-nav-search { background-color: #277CB4;} + +/* Same, but for pygments */ +.highlight .ch { color: #3E7A89; } /* #! line */ +.highlight .c1 { color: #3E7A89; } /* also comments */ +.highlight .nv { color: #AD3ECC; } /* variable */ +.highlight .gp { color: #B45608; } /* prompt character, $*/ +.highlight .si { color: #3975B1; } /* ${} variable text */ +.highlight .nc { color: #0C78A7; } + +/* Sphinx admonitions */ +/* warning */ +.wy-alert.wy-alert-warning .wy-alert-title, .rst-content .wy-alert-warning.note .wy-alert-title, .rst-content .attention .wy-alert-title, .rst-content .caution .wy-alert-title, .rst-content .wy-alert-warning.danger .wy-alert-title, .rst-content .wy-alert-warning.error .wy-alert-title, .rst-content .wy-alert-warning.hint .wy-alert-title, .rst-content .wy-alert-warning.important .wy-alert-title, .rst-content .wy-alert-warning.tip .wy-alert-title, .rst-content .warning .wy-alert-title, .rst-content .wy-alert-warning.seealso .wy-alert-title, .rst-content .admonition-todo .wy-alert-title, .rst-content .wy-alert-warning.admonition .wy-alert-title, .wy-alert.wy-alert-warning .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-warning .admonition-title, .rst-content .wy-alert-warning.note .admonition-title, .rst-content .attention .admonition-title, .rst-content .caution .admonition-title, .rst-content .wy-alert-warning.danger .admonition-title, .rst-content .wy-alert-warning.error .admonition-title, .rst-content .wy-alert-warning.hint .admonition-title, .rst-content .wy-alert-warning.important .admonition-title, .rst-content .wy-alert-warning.tip .admonition-title, .rst-content .warning .admonition-title, .rst-content .wy-alert-warning.seealso .admonition-title, .rst-content .admonition-todo .admonition-title, .rst-content .wy-alert-warning.admonition .admonition-title { + background: #B15E16; } +/* important */ +.wy-alert.wy-alert-success .wy-alert-title, .rst-content .wy-alert-success.note .wy-alert-title, .rst-content .wy-alert-success.attention .wy-alert-title, .rst-content .wy-alert-success.caution .wy-alert-title, .rst-content .wy-alert-success.danger .wy-alert-title, .rst-content .wy-alert-success.error .wy-alert-title, .rst-content .hint .wy-alert-title, .rst-content .important .wy-alert-title, .rst-content .tip .wy-alert-title, .rst-content .wy-alert-success.warning .wy-alert-title, .rst-content .wy-alert-success.seealso .wy-alert-title, .rst-content .wy-alert-success.admonition-todo .wy-alert-title, .rst-content .wy-alert-success.admonition .wy-alert-title, .wy-alert.wy-alert-success .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-success .admonition-title, .rst-content .wy-alert-success.note .admonition-title, .rst-content .wy-alert-success.attention .admonition-title, .rst-content .wy-alert-success.caution .admonition-title, .rst-content .wy-alert-success.danger .admonition-title, .rst-content .wy-alert-success.error .admonition-title, .rst-content .hint .admonition-title, .rst-content .important .admonition-title, .rst-content .tip .admonition-title, .rst-content .wy-alert-success.warning .admonition-title, .rst-content .wy-alert-success.seealso .admonition-title, .rst-content .wy-alert-success.admonition-todo .admonition-title, .rst-content .wy-alert-success.admonition .admonition-title { + background: #12826C; } +/* seealso, note, etc */ +.wy-alert.wy-alert-info .wy-alert-title, .rst-content .note .wy-alert-title, .rst-content .wy-alert-info.attention .wy-alert-title, .rst-content .wy-alert-info.caution .wy-alert-title, .rst-content .wy-alert-info.danger .wy-alert-title, .rst-content .wy-alert-info.error .wy-alert-title, .rst-content .wy-alert-info.hint .wy-alert-title, .rst-content .wy-alert-info.important .wy-alert-title, .rst-content .wy-alert-info.tip .wy-alert-title, .rst-content .wy-alert-info.warning .wy-alert-title, .rst-content .seealso .wy-alert-title, .rst-content .wy-alert-info.admonition-todo .wy-alert-title, .rst-content .wy-alert-info.admonition .wy-alert-title, .wy-alert.wy-alert-info .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-info .admonition-title, .rst-content .note .admonition-title, .rst-content .wy-alert-info.attention .admonition-title, .rst-content .wy-alert-info.caution .admonition-title, .rst-content .wy-alert-info.danger .admonition-title, .rst-content .wy-alert-info.error .admonition-title, .rst-content .wy-alert-info.hint .admonition-title, .rst-content .wy-alert-info.important .admonition-title, .rst-content .wy-alert-info.tip .admonition-title, .rst-content .wy-alert-info.warning .admonition-title, .rst-content .seealso .admonition-title, .rst-content .wy-alert-info.admonition-todo .admonition-title, .rst-content .wy-alert-info.admonition .admonition-title { + background: #277CB4; } +/* error, danger */ +.rst-content .danger .admonition-title, .rst-content .danger .wy-alert-title, .rst-content .error .admonition-title, .rst-content .error .wy-alert-title, .rst-content .wy-alert-danger.admonition-todo .admonition-title, .rst-content .wy-alert-danger.admonition-todo .wy-alert-title, .rst-content .wy-alert-danger.admonition .admonition-title, .rst-content .wy-alert-danger.admonition .wy-alert-title, .rst-content .wy-alert-danger.attention .admonition-title, .rst-content .wy-alert-danger.attention .wy-alert-title, .rst-content .wy-alert-danger.caution .admonition-title, .rst-content .wy-alert-danger.caution .wy-alert-title, .rst-content .wy-alert-danger.hint .admonition-title, .rst-content .wy-alert-danger.hint .wy-alert-title, .rst-content .wy-alert-danger.important .admonition-title, .rst-content .wy-alert-danger.important .wy-alert-title, .rst-content .wy-alert-danger.note .admonition-title, .rst-content .wy-alert-danger.note .wy-alert-title, .rst-content .wy-alert-danger.seealso .admonition-title, .rst-content .wy-alert-danger.seealso .wy-alert-title, .rst-content .wy-alert-danger.tip .admonition-title, .rst-content .wy-alert-danger.tip .wy-alert-title, .rst-content .wy-alert-danger.warning .admonition-title, .rst-content .wy-alert-danger.warning .wy-alert-title, .rst-content .wy-alert.wy-alert-danger .admonition-title, .wy-alert.wy-alert-danger .rst-content .admonition-title, .wy-alert.wy-alert-danger .wy-alert-title { + background: #e31704; +} + +/* Generic admonition titles */ +.wy-alert-title, .rst-content .admonition-title { + background: #277CB4; } diff --git a/branch/main/singlehtml/_static/tabs.css b/branch/main/singlehtml/_static/tabs.css new file mode 100644 index 0000000..957ba60 --- /dev/null +++ b/branch/main/singlehtml/_static/tabs.css @@ -0,0 +1,89 @@ +.sphinx-tabs { + margin-bottom: 1rem; +} + +[role="tablist"] { + border-bottom: 1px solid #a0b3bf; +} + +.sphinx-tabs-tab { + position: relative; + font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; + color: #1D5C87; + line-height: 24px; + margin: 0; + font-size: 16px; + font-weight: 400; + background-color: rgba(255, 255, 255, 0); + border-radius: 5px 5px 0 0; + border: 0; + padding: 1rem 1.5rem; + margin-bottom: 0; +} + +.sphinx-tabs-tab[aria-selected="true"] { + font-weight: 700; + border: 1px solid #a0b3bf; + border-bottom: 1px solid white; + margin: -1px; + background-color: white; +} + +.sphinx-tabs-tab:focus { + z-index: 1; + outline-offset: 1px; +} + +.sphinx-tabs-panel { + position: relative; + padding: 1rem; + border: 1px solid #a0b3bf; + margin: 0px -1px -1px -1px; + border-radius: 0 0 5px 5px; + border-top: 0; + background: white; +} + +.sphinx-tabs-panel.code-tab { + padding: 0.4rem; +} + +.sphinx-tab img { + margin-bottom: 24 px; +} + +/* Dark theme preference styling */ + +@media (prefers-color-scheme: dark) { + body[data-theme="auto"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); + } + + body[data-theme="auto"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); + } + + body[data-theme="auto"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 1px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); + } +} + +/* Explicit dark theme styling */ + +body[data-theme="dark"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); +} + +body[data-theme="dark"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); +} + +body[data-theme="dark"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 2px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); +} diff --git a/branch/main/singlehtml/_static/tabs.js b/branch/main/singlehtml/_static/tabs.js new file mode 100644 index 0000000..48dc303 --- /dev/null +++ b/branch/main/singlehtml/_static/tabs.js @@ -0,0 +1,145 @@ +try { + var session = window.sessionStorage || {}; +} catch (e) { + var session = {}; +} + +window.addEventListener("DOMContentLoaded", () => { + const allTabs = document.querySelectorAll('.sphinx-tabs-tab'); + const tabLists = document.querySelectorAll('[role="tablist"]'); + + allTabs.forEach(tab => { + tab.addEventListener("click", changeTabs); + }); + + tabLists.forEach(tabList => { + tabList.addEventListener("keydown", keyTabs); + }); + + // Restore group tab selection from session + const lastSelected = session.getItem('sphinx-tabs-last-selected'); + if (lastSelected != null) selectNamedTabs(lastSelected); +}); + +/** + * Key focus left and right between sibling elements using arrows + * @param {Node} e the element in focus when key was pressed + */ +function keyTabs(e) { + const tab = e.target; + let nextTab = null; + if (e.keyCode === 39 || e.keyCode === 37) { + tab.setAttribute("tabindex", -1); + // Move right + if (e.keyCode === 39) { + nextTab = tab.nextElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.firstElementChild; + } + // Move left + } else if (e.keyCode === 37) { + nextTab = tab.previousElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.lastElementChild; + } + } + } + + if (nextTab !== null) { + nextTab.setAttribute("tabindex", 0); + nextTab.focus(); + } +} + +/** + * Select or deselect clicked tab. If a group tab + * is selected, also select tab in other tabLists. + * @param {Node} e the element that was clicked + */ +function changeTabs(e) { + // Use this instead of the element that was clicked, in case it's a child + const notSelected = this.getAttribute("aria-selected") === "false"; + const positionBefore = this.parentNode.getBoundingClientRect().top; + const notClosable = !this.parentNode.classList.contains("closeable"); + + deselectTabList(this); + + if (notSelected || notClosable) { + selectTab(this); + const name = this.getAttribute("name"); + selectNamedTabs(name, this.id); + + if (this.classList.contains("group-tab")) { + // Persist during session + session.setItem('sphinx-tabs-last-selected', name); + } + } + + const positionAfter = this.parentNode.getBoundingClientRect().top; + const positionDelta = positionAfter - positionBefore; + // Scroll to offset content resizing + window.scrollTo(0, window.scrollY + positionDelta); +} + +/** + * Select tab and show associated panel. + * @param {Node} tab tab to select + */ +function selectTab(tab) { + tab.setAttribute("aria-selected", true); + + // Show the associated panel + document + .getElementById(tab.getAttribute("aria-controls")) + .removeAttribute("hidden"); +} + +/** + * Hide the panels associated with all tabs within the + * tablist containing this tab. + * @param {Node} tab a tab within the tablist to deselect + */ +function deselectTabList(tab) { + const parent = tab.parentNode; + const grandparent = parent.parentNode; + + Array.from(parent.children) + .forEach(t => t.setAttribute("aria-selected", false)); + + Array.from(grandparent.children) + .slice(1) // Skip tablist + .forEach(panel => panel.setAttribute("hidden", true)); +} + +/** + * Select grouped tabs with the same name, but no the tab + * with the given id. + * @param {Node} name name of grouped tab to be selected + * @param {Node} clickedId id of clicked tab + */ +function selectNamedTabs(name, clickedId=null) { + const groupedTabs = document.querySelectorAll(`.sphinx-tabs-tab[name="${name}"]`); + const tabLists = Array.from(groupedTabs).map(tab => tab.parentNode); + + tabLists + .forEach(tabList => { + // Don't want to change the tabList containing the clicked tab + const clickedTab = tabList.querySelector(`[id="${clickedId}"]`); + if (clickedTab === null ) { + // Select first tab with matching name + const tab = tabList.querySelector(`.sphinx-tabs-tab[name="${name}"]`); + deselectTabList(tab); + selectTab(tab); + } + }) +} + +if (typeof exports === 'undefined') { + exports = {}; +} + +exports.keyTabs = keyTabs; +exports.changeTabs = changeTabs; +exports.selectTab = selectTab; +exports.deselectTabList = deselectTabList; +exports.selectNamedTabs = selectNamedTabs; diff --git a/branch/main/singlehtml/_static/term_role_formatting.css b/branch/main/singlehtml/_static/term_role_formatting.css new file mode 100644 index 0000000..0b66095 --- /dev/null +++ b/branch/main/singlehtml/_static/term_role_formatting.css @@ -0,0 +1,4 @@ +/* Make terms bold */ +a.reference span.std-term { + font-weight: bold; +} diff --git a/branch/main/singlehtml/_static/togglebutton.css b/branch/main/singlehtml/_static/togglebutton.css new file mode 100644 index 0000000..54a6787 --- /dev/null +++ b/branch/main/singlehtml/_static/togglebutton.css @@ -0,0 +1,160 @@ +/** + * Admonition-based toggles + */ + +/* Visibility of the target */ +.admonition.toggle .admonition-title ~ * { + transition: opacity .3s, height .3s; +} + +/* Toggle buttons inside admonitions so we see the title */ +.admonition.toggle { + position: relative; +} + +/* Titles should cut off earlier to avoid overlapping w/ button */ +.admonition.toggle .admonition-title { + padding-right: 25%; + cursor: pointer; +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:hover { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 1%); +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:active { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 3%); +} + +/* Remove extra whitespace below the admonition title when hidden */ +.admonition.toggle-hidden { + padding-bottom: 0; +} + +.admonition.toggle-hidden .admonition-title { + margin-bottom: 0; +} + +/* hides all the content of a page until de-toggled */ +.admonition.toggle-hidden .admonition-title ~ * { + height: 0; + margin: 0; + opacity: 0; + visibility: hidden; +} + +/* General button style and position*/ +button.toggle-button { + /** + * Background and shape. By default there's no background + * but users can style as they wish + */ + background: none; + border: none; + outline: none; + + /* Positioning just inside the admonition title */ + position: absolute; + right: 0.5em; + padding: 0px; + border: none; + outline: none; +} + +/* Display the toggle hint on wide screens */ +@media (min-width: 768px) { + button.toggle-button.toggle-button-hidden:before { + content: attr(data-toggle-hint); /* This will be filled in by JS */ + font-size: .8em; + align-self: center; + } +} + +/* Icon behavior */ +.tb-icon { + transition: transform .2s ease-out; + height: 1.5em; + width: 1.5em; + stroke: currentColor; /* So that we inherit the color of other text */ +} + +/* The icon should point right when closed, down when open. */ +/* Open */ +.admonition.toggle button .tb-icon { + transform: rotate(90deg); +} + +/* Closed */ +.admonition.toggle button.toggle-button-hidden .tb-icon { + transform: rotate(0deg); +} + +/* With details toggles, we don't rotate the icon so it points right */ +details.toggle-details .tb-icon { + height: 1.4em; + width: 1.4em; + margin-top: 0.1em; /* To center the button vertically */ +} + + +/** + * Details-based toggles. + * In this case, we wrap elements with `.toggle` in a details block. + */ + +/* Details blocks */ +details.toggle-details { + margin: 1em 0; +} + + +details.toggle-details summary { + display: flex; + align-items: center; + cursor: pointer; + list-style: none; + border-radius: .2em; + border-left: 3px solid #1976d2; + background-color: rgb(204 204 204 / 10%); + padding: 0.2em 0.7em 0.3em 0.5em; /* Less padding on left because the SVG has left margin */ + font-size: 0.9em; +} + +details.toggle-details summary:hover { + background-color: rgb(204 204 204 / 20%); +} + +details.toggle-details summary:active { + background: rgb(204 204 204 / 28%); +} + +.toggle-details__summary-text { + margin-left: 0.2em; +} + +details.toggle-details[open] summary { + margin-bottom: .5em; +} + +details.toggle-details[open] summary .tb-icon { + transform: rotate(90deg); +} + +details.toggle-details[open] summary ~ * { + animation: toggle-fade-in .3s ease-out; +} + +@keyframes toggle-fade-in { + from {opacity: 0%;} + to {opacity: 100%;} +} + +/* Print rules - we hide all toggle button elements at print */ +@media print { + /* Always hide the summary so the button doesn't show up */ + details.toggle-details summary { + display: none; + } +} \ No newline at end of file diff --git a/branch/main/singlehtml/_static/togglebutton.js b/branch/main/singlehtml/_static/togglebutton.js new file mode 100644 index 0000000..215a7ee --- /dev/null +++ b/branch/main/singlehtml/_static/togglebutton.js @@ -0,0 +1,187 @@ +/** + * Add Toggle Buttons to elements + */ + +let toggleChevron = ` + + + +`; + +var initToggleItems = () => { + var itemsToToggle = document.querySelectorAll(togglebuttonSelector); + console.log(`[togglebutton]: Adding toggle buttons to ${itemsToToggle.length} items`) + // Add the button to each admonition and hook up a callback to toggle visibility + itemsToToggle.forEach((item, index) => { + if (item.classList.contains("admonition")) { + // If it's an admonition block, then we'll add a button inside + // Generate unique IDs for this item + var toggleID = `toggle-${index}`; + var buttonID = `button-${toggleID}`; + + item.setAttribute('id', toggleID); + if (!item.classList.contains("toggle")){ + item.classList.add("toggle"); + } + // This is the button that will be added to each item to trigger the toggle + var collapseButton = ` + `; + + title = item.querySelector(".admonition-title") + title.insertAdjacentHTML("beforeend", collapseButton); + thisButton = document.getElementById(buttonID); + + // Add click handlers for the button + admonition title (if admonition) + admonitionTitle = document.querySelector(`#${toggleID} > .admonition-title`) + if (admonitionTitle) { + // If an admonition, then make the whole title block clickable + admonitionTitle.addEventListener('click', toggleClickHandler); + admonitionTitle.dataset.target = toggleID + admonitionTitle.dataset.button = buttonID + } else { + // If not an admonition then we'll listen for the button click + thisButton.addEventListener('click', toggleClickHandler); + } + + // Now hide the item for this toggle button unless explicitly noted to show + if (!item.classList.contains("toggle-shown")) { + toggleHidden(thisButton); + } + } else { + // If not an admonition, wrap the block in a
block + // Define the structure of the details block and insert it as a sibling + var detailsBlock = ` +
+ + ${toggleChevron} + ${toggleHintShow} + +
`; + item.insertAdjacentHTML("beforebegin", detailsBlock); + + // Now move the toggle-able content inside of the details block + details = item.previousElementSibling + details.appendChild(item) + item.classList.add("toggle-details__container") + + // Set up a click trigger to change the text as needed + details.addEventListener('click', (click) => { + let parent = click.target.parentElement; + if (parent.tagName.toLowerCase() == "details") { + summary = parent.querySelector("summary"); + details = parent; + } else { + summary = parent; + details = parent.parentElement; + } + // Update the inner text for the proper hint + if (details.open) { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintShow; + } else { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintHide; + } + + }); + + // If we have a toggle-shown class, open details block should be open + if (item.classList.contains("toggle-shown")) { + details.click(); + } + } + }) +}; + +// This should simply add / remove the collapsed class and change the button text +var toggleHidden = (button) => { + target = button.dataset['target'] + var itemToToggle = document.getElementById(target); + if (itemToToggle.classList.contains("toggle-hidden")) { + itemToToggle.classList.remove("toggle-hidden"); + button.classList.remove("toggle-button-hidden"); + } else { + itemToToggle.classList.add("toggle-hidden"); + button.classList.add("toggle-button-hidden"); + } +} + +var toggleClickHandler = (click) => { + // Be cause the admonition title is clickable and extends to the whole admonition + // We only look for a click event on this title to trigger the toggle. + + if (click.target.classList.contains("admonition-title")) { + button = click.target.querySelector(".toggle-button"); + } else if (click.target.classList.contains("tb-icon")) { + // We've clicked the icon and need to search up one parent for the button + button = click.target.parentElement; + } else if (click.target.tagName == "polyline") { + // We've clicked the SVG elements inside the button, need to up 2 layers + button = click.target.parentElement.parentElement; + } else if (click.target.classList.contains("toggle-button")) { + // We've clicked the button itself and so don't need to do anything + button = click.target; + } else { + console.log(`[togglebutton]: Couldn't find button for ${click.target}`) + } + target = document.getElementById(button.dataset['button']); + toggleHidden(target); +} + +// If we want to blanket-add toggle classes to certain cells +var addToggleToSelector = () => { + const selector = ""; + if (selector.length > 0) { + document.querySelectorAll(selector).forEach((item) => { + item.classList.add("toggle"); + }) + } +} + +// Helper function to run when the DOM is finished +const sphinxToggleRunWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} +sphinxToggleRunWhenDOMLoaded(addToggleToSelector) +sphinxToggleRunWhenDOMLoaded(initToggleItems) + +/** Toggle details blocks to be open when printing */ +if (toggleOpenOnPrint == "true") { + window.addEventListener("beforeprint", () => { + // Open the details + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.dataset["togglestatus"] = el.open; + el.open = true; + }); + + // Open the admonitions + document.querySelectorAll(".admonition.toggle.toggle-hidden").forEach((el) => { + console.log(el); + el.querySelector("button.toggle-button").click(); + el.dataset["toggle_after_print"] = "true"; + }); + }); + window.addEventListener("afterprint", () => { + // Re-close the details that were closed + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.open = el.dataset["togglestatus"] == "true"; + delete el.dataset["togglestatus"]; + }); + + // Re-close the admonition toggle buttons + document.querySelectorAll(".admonition.toggle").forEach((el) => { + if (el.dataset["toggle_after_print"] == "true") { + el.querySelector("button.toggle-button").click(); + delete el.dataset["toggle_after_print"]; + } + }); + }); +} diff --git a/branch/main/singlehtml/index.html b/branch/main/singlehtml/index.html new file mode 100644 index 0000000..0a783a7 --- /dev/null +++ b/branch/main/singlehtml/index.html @@ -0,0 +1,6234 @@ + + + + + + + Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Train the trainer workshop

+
+

August/September 2024 CodeRefinery train the trainer workshop

+

Do you teach the use of computers and computational tools? Are you curious about scaling your training and learn about tested and proven practices from CodeRefinery workshops and other trainers? Join us for the CodeRefinery train the trainer workshop: four self-contained sessions on tools and techniques for computational training offer a great chance to enhance your teaching skills and learn about new tools and practices. What you will learn is also used a lot outside CodeRefinery, whenever good beginner friendly training is needed.

+

Learning objectives:

+
    +
  • Learn about tools and techniques and practice to create engaging online teaching experiences (screenshare, audio, etc.).

  • +
  • Become mentally ready to be an instructor in a collaborative interactive online workshop (not only large workshops but in general).

  • +
  • Learn how to design and develop lesson material collaboratively.

  • +
+

Target audience:

+
    +
  • Everyone teaching online workshops about computational topics or interested in teaching.

  • +
  • Previous and future instructors and helpers of CodeRefinery workshops.

  • +
+

Prerequisites: +An interest in teaching.

+

Workshop structure: +We aim for a mix of modular presentations and work in small groups. The latter will be done in breakoutrooms - +be prepared to switch on your camera and have a fruitful exchange with fellow participants!

+

Organizers and instructors:

+

The workshop is organized by partner organizations of the CodeRefinery project.

+

Facilitators and instructors:

+
    +
  • Radovan Bast

  • +
  • Richard Darst

  • +
  • Bjørn Lindi

  • +
  • Dhanya Pushpadas

  • +
  • Jarno Rantaharju

  • +
  • Stephan Smuts

  • +
  • Stepas Toliautas

  • +
  • Samantha Wittke

  • +
+

Content and timing:

+

The workshop consists of four sessions every Tuesday between August +13th and September 3rd 2024, + to +:

+
    +
  • Session 1: About lesson design, deployment and iterative improvement (Aug 13)

  • +
  • Session 2: Tools and techniques adopted in CodeRefinery workshops (Aug 20)

  • +
  • Session 3: About teaching & cool things we all would like to share (Aug 27)

  • +
  • Session 4: Workshop streaming practices and post-workshop tasks (Sep 3)

  • +
+

You can join all sessions, or the just the ones that interest you. More details on each session will be shared later.

+

The workshop is free of charge for everyone, please register below to get the Zoom link and other useful information for the workshop.

+

The workshop is over and registration is closed now.

+

If you have any questions, please write to support@coderefinery.org.

+
+
+
+

Lesson design and development

+
+

Objectives

+
    +
  • We share our design processes for teaching material and presentations.

  • +
  • Learn how to design lessons “backwards”, starting from learning objectives +and learner personas.

  • +
  • Learn good practices for improving existing material based on feedback.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 20 min

  • +
  • Exercises: 35 min

  • +
+
+
+

Exercise: How do you design your teaching material?

+
+

We collect notes using a shared document (5 min)

+
    +
  • When you start preparing a new lesson or training material, where do you start?

  • +
  • What tricks help you with “writer’s block” or the empty page problem?

  • +
  • Maybe you haven’t designed training material yet. But how do you start when creating a new presentation?

  • +
  • If your design process has changed over time, please describe what you used to do and what you do now instead.

  • +
  • What do you know now about preparing lessons/training/presentations that you wish you knew earlier?

  • +
+
+
+
+

Creating new teaching material

+
+

Typical problems

+
    +
  • Someone creates a lesson, but they think about what is interesting to them, +not what is important for the learners.

  • +
  • “I want to show a number of things which I think are cool about +tool X - how do I press these into 90 minutes?”

  • +
  • Write down material you want to cover and then sprinkle in some exercises.

  • +
  • Thinking about how I work, not how the learners work.

  • +
  • Trying to bring learners to their level/setup, not trying to meet the learners +where they are.

  • +
  • Not really knowing the learning objectives or the learner personas.

  • +
+
+
+

Better approach

+

Good questions to ask and discuss with a group of colleagues from diverse backgrounds:

+
    +
  • What is the expected educational level of my audience?

  • +
  • Have they been already exposed to the technologies I am planning to teach?

  • +
  • What tools do they already use?

  • +
  • What are the main issues they are currently experiencing?

  • +
  • What do they need to remember/understand/apply/analyze/evaluate/create +(Bloom’s taxonomy)?

  • +
  • Define learner personas.

  • +
  • It may be an advantage to share an imperfect lesson with others early to +collect feedback and suggestions before the lesson “solidifies” too much. +Draft it and collect feedback. The result will probably be better than +working in isolation towards a “perfect” lesson.

  • +
+
+
+

The process of designing a lesson “backwards”

+

As described in “A lesson design process” in the book Teaching Tech +Together:

+
    +
  1. Understand your learners.

  2. +
  3. Brainstorm rough ideas.

  4. +
  5. Create an summative assessment to know your overall goal.

    +
    +

    [Think of the things your learners will be able to do at the end of the lesson]

    +
    +
  6. +
  7. Create formative assessments to go from the starting point to this.

    +
    +

    [Think of some engaging and active exercises]

    +
    +
  8. +
  9. Order the formative assessments (exercises) into a reasonable order.

  10. +
  11. Write just enough material to get from one assessment (exercise) to +another.

  12. +
  13. Describe the course so the learners know if it is relevant to them.

  14. +
+
+
+
+

Improving existing lessons

+
+

All CodeRefinery lessons are on GitHub

+ +
+

Collect feedback during the workshop:

+
    +
  • Collect feedback from learners and instructors (Example from a past +workshop).

  • +
  • Convert feedback about lessons and suggestions for improvements into issues +so that these don’t get lost and stay close to the lesson material.

  • +
+

Collect feedback before you start a big rewrite:

+
    +
  • First open an issue and describe your idea and collect feedback before you +start with an extensive rewrite.

  • +
  • For things still under construction, open a draft pull/merge request to collect +feedback and to signal to others what you are working on.

  • +
+

Small picture changes vs. big picture changes:

+
    +
  • Lesson changes should be accompanied with instructor guide changes (it’s like +a documentation for the lesson material).

  • +
  • Instructor guide is essential for new instructors.

  • +
  • Before making larger changes, talk with somebody and discuss these changes.

  • +
+
+
+

Use case: our lessons

+

As an example to demonstrate the process of designing and improving lessons, we +will have a look at one of our own lessons: Introduction to version control +with Git.

+
    +
  • Initial 2014-2016 version

    + +
  • +
  • Some time in 2014-2015 attended Carpentries instructor training.

  • +
  • 2016: CodeRefinery started.

  • +
  • 2017: Started a new repository based on the Carpentries lesson template (at the time using Jekyll).

    +
      +
    • Exercises become part of the lesson.

    • +
    • We start in the command line and only later move to GitHub.

    • +
    +
  • +
  • 2019: A lot more thought about learning objectives and personas.

    +
      +
    • Also license change to CC-BY.

    • +
    +
  • +
  • 2022: Convert lesson from Jekyll to Sphinx.

    +
      +
    • Using the tools that we teach/advocate.

    • +
    • We can have tabs and better code highlighting/emphasis.

    • +
    • Easier local preview (Python environment instead of Ruby environment which we were not used to in our daily work).

    • +
    +
  • +
  • 2024: Big redesign. We move the lesson closer to where learners are.

    +
      +
    • Start from GitHub instead of on the command line.

    • +
    • Start from an existing repository instead of with an empty one.

    • +
    • Offer several tracks to participate in the lesson (GitHub, VS Code, and command line) and learners can choose which one they want to follow.

    • +
    • Blog post: We have completely changed our Git lessons. Hopefully to the better.

    • +
    +
  • +
  • Next steps?

    +
      +
    • Making the lesson citable following +our blog post.

    • +
    • Improvements based on what we learn from this workshop.

    • +
    +
  • +
+

The overarching trend was to make the lesson simpler and more accessible - to +meet the learners where they are instead of pulling them to the tool choices of +the instructors. Looking back, we learned a lot and the learning process is +not over yet.

+
+
+

Exercise: Discussion about learning objectives and exercise design

+
+

We work in groups but use the shared document as result (20 min)

+
    +
  1. As a group pick a lesson topic. It can be one of the topics listed here but +you can also choose something else that your group is interested in, or a topic +that you have taught before or would like to teach. Some suggestions:

    +
      +
    • Git: Creating a repository and porting your project to Git and GitHub

    • +
    • Git: Basic commands

    • +
    • Git: Branching and merging

    • +
    • Git: Recovering from typical mistakes

    • +
    • Code documentation

    • +
    • Jupyter Notebooks

    • +
    • Collaboration using Git and GitHub/GitLab

    • +
    • Using GitHub without the command line

    • +
    • Project organization

    • +
    • Automated testing

    • +
    • Data transfer

    • +
    • Data management and versioning

    • +
    • Code quality and good practices

    • +
    • Modular code development

    • +
    • How to release and publish your code

    • +
    • How to document and track code dependencies

    • +
    • Recording environments in containers

    • +
    • Profiling memory and CPU usage

    • +
    • Strategies for parallelization

    • +
    • Conda environments

    • +
    • Data processing using workflow managers

    • +
    • Regular expressions

    • +
    • Making papers in LaTeX

    • +
    • Making figures in your favorite programming language

    • +
    • Linux shell basics

    • +
    • Something non-technical, such as painting a room

    • +
    • Introduction to high-performance computing

    • +
    • A lesson you always wanted to teach

    • +
    • +
    +
  2. +
  3. Try to define 2-3 learning objectives for the lesson and write them down. +You can think of these as “three simple enough messages that someone will +remember the next day” - they need to be pretty simple.

  4. +
  5. Can you come up with one or two engaging exercises that could be used to +demonstrate one of those objectives? +They should be simple enough people can actually do them. Creating simple exercises is not easy. +Some standard exercise types:

    +
      +
    • Multiple choice (easy to get feedback via a classroom tool - try to design each wrong answer so that it identifies a specific misconception).

    • +
    • Code yourself (traditional programming)

    • +
    • Code yourself + multiple choice to see what the answer is (allows you to get feedback)

    • +
    • Inverted coding (given code, have to debug)

    • +
    • Parsons problems (working solution but lines in random order, learner must only put in proper order)

    • +
    • Fill in the blank

    • +
    • Discussions, self directed learning exercises

    • +
    +
  6. +
+
+
+
+

Great resources

+ +
+
+
+

Lessons with version control

+
+

Objectives

+
    +
  • Understand why version control is useful even for teaching material

  • +
  • Understand how version control managed lessons can be modified.

  • +
  • Understand how the CodeRefinery lesson template is used to create new lessons

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 25 min

  • +
  • Exercises or demos: 20 min

  • +
+
+
+

Why version control?

+
    +
  • If you are in CodeRefinery TTT, you probably know what version +control is and why it is important.

  • +
  • The benefits of version control also extend to lessons:

    +
      +
    • Change history

    • +
    • Others can submit contributions

    • +
    • Others can make derived versions and sync up later

    • +
    • Same workflow as everything else

    • +
    • Write it like documentation: probably more reading after than +watching it as a presentation.

    • +
    +
  • +
  • Disadvantages

    +
      +
    • “What you see is what you get” editing is hard

    • +
    • Requires knowing version control

    • +
    +
  • +
+
+

Accepting the smallest contribution

+

Question: if someone wants to make a tiny fix to your material, can they?

+
+
+
+

Tour of lesson templates options

+

There are different ways to make lessons with git. Some dedicated to +teaching:

+ +

Our philosophy is that anything works: it doesn’t have to be just +designed for lessons

+
    +
  • Jupyter Book

    +
      +
    • Example: https://jupyterbook.org/

    • +
    • Note: is based on sphinx, many extensions here are used in CR lessons

    • +
    +
  • +
  • Various ways to make slides out of Markdown

  • +
  • Cicero: GitHub-hosted Markdown to slides easily

    + +
  • +
  • Whatever your existing documentation is.

  • +
+

We like the CodeRefinery format, but think that you should use +whatever fits your needs the most.

+
+
+

Sphinx

+
    +
  • We build all our lesson material with Sphinx

  • +
  • Generate HTML/PDF/LaTeX from RST and Markdown.

  • +
  • Many Python projects use Sphinx for documentation but Sphinx is not limited to Python.

  • +
  • Read the docs hosts public Sphinx documentation for free!

  • +
  • Also hostable anywhere else, like Github pages, like our lesson material

  • +
  • For code a selling point for Sphinx is that also API documentation +is possible.

  • +
+

Sphinx is a doc generator, not HTML generator. It can:

+
    +
  • Markdown, Jupyter, and ReST (and more…) inputs. Executable inputs.

    +
      +
    • jupyter-book is Sphinx, so anything it can do we can do. This was one of the +inspirations for using Sphinx

    • +
    +
  • +
  • Good support for inline code. Much more than static code display, if +you want to look at extensions.

  • +
  • Generate different output formats (html, single-page html, pdf, epub, etc.)

  • +
  • Strong cross-referencing within and between projects

  • +
+
+
+

CodeRefinery lesson template

+

It is “just a normal Sphinx project” - with extensions:

+
    +
  • Sphinx lesson extension

    +
      +
    • adds is various directives (boxes) tuned to lesson purposes

    • +
    • provides a sample organization and template repo you can use so that lessons look consistent

    • +
    +
  • +
  • Sphinx gives us other nice features for free

    +
      +
    • Tabs: they are very important for us and allow us to customize in-place instead of copying everything and fragmenting lessons

    • +
    • Emphasize lines: they make it easier to spot what has changed in longer code snippets

    • +
    • Various input formats

      +
        +
      • Markdown (via the MyST-parser), ReStructured text, Jupyter +Notebooks.

      • +
      +
    • +
    • Many other features designed for presenting and interacting with code

    • +
    +
  • +
  • It’s fine if you use some other static site generator or git-based lesson method.

  • +
+
+

Instructors go through the building and contributing process

+

Depending on the course, instructors will demo what is roughly +exercise 4 below. Or a course might go straight to exercises.

+
    +
  • Instructors decide what change they would want to make

  • +
  • Instructors clone the repository

  • +
  • Instructors make the change

  • +
  • Instructors set up the build environment

  • +
  • Instructors build and preview

  • +
  • Instructors command and send upstream

  • +
+
+
+
+

Exercises

+

Some exercises have prerequisites (Git or Github accounts). Most +instances of this course will have you do 1 and 2 below.

+
+

Lesson-VCS-1: Present and discuss your own lesson formats

+

We don’t want to push everyone towards one format, but as long as you +use Git, it’s easy to share and reuse.

+
    +
  • Discuss what formats you do use

  • +
  • Within your team, show examples of the lessons formats you use +now. Discuss what is good and to-be-improved about them.

  • +
  • Look at how they source is managed and how easy it might be to edit.

  • +
+
+
+

Lesson-VCS-2: Tour a CodeRefinery or Carpentries lesson on Github

+
    +
  • Look at either a CodeRefinery or Carpentries lesson

    + +
  • +
  • Can you find

    +
      +
    • Where is the content of the lessons?

    • +
    • What recent change propsals (pull requests) have been made?

    • +
    • What are the open issues?

    • +
    • How you would contribute something?

    • +
    • How would you use this yourself?

    • +
    +
  • +
+
+
+

Lesson-VCS-3: Modify a CodeRefinery example lesson on Github

+

In this, you will make a change to a lesson on Github, using only the +Github interface. (Github account required, and we assume some +knowledge of Github. Ask for help in your team if it is new to you!)

+
    +
  • Navigate to the example lesson we have set up: +repo, web

  • +
  • Go to some page and follow the link to go to the respective page on +Github. (Alternatively, you can find the page from the Github repo directly).

  • +
  • Follow the Github flow to make a change, and open a Pull Request +with the change proposal:

    +
      +
    • Click on the pencil icon

    • +
    • Make a change

    • +
    • Follow the flow to make a commit and change. You’ll fork the +repository to make your own copy, add a message, and open a pull +request.

    • +
    +
  • +
+

We will look at these together and accept some changes.

+
+
+

Lesson-VCS-4: Clone and build a CodeRefinery lesson locally

+

In this exercise, you will use Git to clone one a CodeRefinery lesson +and try to preview it locally. It assumes installation and knowledge +of Git.

+
    +
  • Use this sample repository: +git-intro (or whatever +else you would like)

  • +
  • Clone the repository to your own computer

  • +
  • Create a virtual environment using the requirements.txt +contained within the repository.

  • +
  • Build the lesson.

    +
      +
    • Most people will probably run: sphinx-build content/ _build/

    • +
    • If you have make installed you can make html

    • +
    • Look in the _build directory for the built HTML files.

    • +
    +
  • +
+

Overall, this is pretty easy and straightforward, if you have a Python +environment set up. The CodeRefinery documentation +lesson teaches +this for every operating system.

+

This same tool can be used to build documentation for other software +projects and is pretty standard.

+
+
+

Lesson-VCS-5: (advanced) Create your own lesson using the CodeRefinery format

+

In this lesson, you’ll copy the CodeRefinery template and do basic +modifications for your own lesson.

+
    +
  • Clone the lesson template: +https://github.com/coderefinery/sphinx-lesson-template

  • +
  • Attempt to build it as it is (see the previous exercise)

  • +
  • How can you do tabs?

  • +
  • How can you highlight lines in code boxes?

  • +
  • How can you change color, logo and fonts?

  • +
  • What directives are available?

  • +
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Version control takes teaching materials to the next level: +shareable and easy to contribute

  • +
  • There are different formats that use version control, but we like +Sphinx with a sphinx-lesson extension.

  • +
+
+
+
+
+

How we collect feedback and measure impact

+
+

Objectives

+
    +
  • Discuss how one can collect feedback from learners (“what can we improve?”).

  • +
  • Discuss how we convert feedback into actionable items.

  • +
  • Discuss how we measure the impact of teaching (“did we achieve our goals?”).

  • +
  • Discuss the “why”.

  • +
  • Get to know the reasons and sources of inspiration behind major lesson and workshop updates.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 20 min

  • +
  • Exercises: 10 min

  • +
+
+
+

Asking questions before the workshop

+ +
+
+

Collecting feedback as we teach

+
    +
  • Each day we ask for feedback in the collaborative notes.

    +
      +
    • One good thing about today.

    • +
    • One thing to improve for next time.

    • +
    • Any other comments?

    • +
    +
  • +
  • During the workshop we sometimes check in and ask about the pace, example:

    +
    How is the speed so far? (add an "o")
    +- Too fast:   oooooo
    +- Too slow:   ooo
    +- Just right: ooooooooooooooooooo
    +
    +
    +
  • +
  • We publish all questions, answers, and feedback. Example: https://coderefinery.github.io/2024-03-12-workshop/questions/

  • +
  • How we follow up:

    +
      +
    • Some problems we can fix already before the next workshop day.

    • +
    • We convert feedback/problems into GitHub issues and track these close to the lesson material.

    • +
    +
  • +
+
+
+

Trying to measure impact with longer-term surveys

+ +
+
+

Lessons learned

+
    +
  • Think about how to measure impact/success from the beginning.

  • +
  • Make the feedback and survey results public.

  • +
  • Make the results persistent and citable.

  • +
  • Have a mechanism to follow-up on feedback.

  • +
  • Anonymization is more than just removing or dissociating names.

  • +
  • Take time designing your survey and collect feedback on the survey itself.

  • +
+
+
+

Take time designing your survey

+

We are not experts in survey design but we reached out to RISE Research +Institutes of Sweden to get feedback on our survey questions. They provided us +with a lot of valuable feedback and suggestions for improvements. +Below are few examples.

+
+

Example 1

+

First version of our survey question about impact:

+
    +
  • “Do our workshops help to save time in future?” Please quantify in hours saved: …

  • +
+

Feedback:

+
    +
  • Difficult to answer.

  • +
  • Since when? Until all eternity?

  • +
+
+Screenshot of earlier version of the survey question about impact. +
+

Earlier version of the survey question about impact.

+
+
+

Feedback:

+
    +
  • The question “Do our workshops help to save time in future?” is unspecified, +unnecessary, and leading.

  • +
  • “No time saving” does not match the wording “save time” in the question.

  • +
+
+Screenshot of later version of the survey question about impact. +
+

Later version of the survey question about impact.

+
+
+
    +
  • The wording “have you saved” now matches “No time saved”.

  • +
+
+
+

Example 2

+
    +
  • Earlier version:

    +
    Would you judge your code to be better reusable/reproducible/modular/documented
    +as a result of attending the workshop?
    +
    +- More reusable
    +- More reproducible
    +- More modular
    +- Better documented
    +- None of the above
    +
    +
    +
  • +
  • Feedback: The question is not neutrally formulated and risks leading to +over-reporting of yes answers. Consider balancing so that the questions are +formulated more neutrally.

  • +
  • Reformulated to:

    +
    After attending the workshop, would you judge your code to be
    +more reusable or not more reusable?
    +
    +- My code is more reusable
    +- My code is not more reusable
    +- Not sure
    +
    +
    +
  • +
+
+
+

Example 3

+
    +
  • Early version:

    +
    What else has changed in how you write code since attending the workshop?
    +
    +[free-form text field]
    +
    +
    +
  • +
  • Feedback: Leading and assumes that something has changed.

  • +
  • Reformulated to:

    +
    Has anything else changed in how you write code for your research after
    +attending the workshop?
    +
    +[free-form text field]
    +
    +
    +
  • +
+
+
+

Example 4

+
    +
  • Earlier version:

    +
    Has it become easier for you to collaborate on software development with your
    +colleagues and collaborators?
    +
    +- Yes
    +- Not sure
    +- No
    +
    +
    +
  • +
  • Feedback:

    +
      +
    • Leading question.

    • +
    • Avoid “Yes” and “No” response options because respondents tend to answer +“Yes” if that option is available, leading to a risk of measurement error +(acquiescence bias).

    • +
    • Do not place “Not sure” in the middle of the scale because it captures +participants who actually don’t know and should therefore be placed at the +bottom instead of in the middle of the scale.

    • +
    +
  • +
  • Reformulated to:

    +
    After attending the workshop, has it become easier or not for you to
    +collaborate on software development with your colleagues and collaborators?
    +
    +- Collaboration is easier
    +- Collaboration is not easier
    +- Not sure
    +
    +
    +
  • +
+
+
+
+

Exercise: Group discussion (10 min)

+
+

Group discussion using the collaborative notes

+
    +
  • What tricks/techniques have you tried in your teaching or seen in someone +else’s teaching that you think have been particularly effective in collecting +feedback from learners?

  • +
  • Can you give tips or share your experiences about how to convert feedback +into actionable items?

  • +
  • How do you measure the impact of your teaching? Any tips or experiences about +what you have tried or seen other courses do?

  • +
  • Anybody knows of good resources on survey design? Please link them in +the collaborative notes.

  • +
+
+
+
+
+
+
+

About the CodeRefinery project and CodeRefinery workshops in general

+
+

Objectives

+
    +
  • Discuss what CodeRefinery is and how we got here

  • +
  • Understand about the challenges to define our target audience

  • +
+
+

CodeRefinery is a +Nordic e-Infrastructure Collaboration (NeIC) +project that has started in October 2016 and is currently +funded until February 2025. We are working on the continuation plans.

+

The funding from 2022-2025 is designed to keep this project active +beyond 2025 by forming a support network and building a community of +instructors and contributors.

+
+

History

+

The CodeRefinery project idea grew out of two SeSE courses given at KTH Stockholm in 2014 and 2016. +The project proposal itself was submitted to NeIC in 2015, accepted in 2015, and started in 2016.

+

We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form.

+
+
+

Goals

+
    +
  • Develop and maintain training material on good enough software development practices for researchers that write code/scripts/notebooks.

  • +
  • Our material addresses all academic disciplines and tries to be as programming language-independent as possible.

  • +
  • Provide a code repository hosting service that is open and free +for all researchers based in universities and research institutes from Nordic countries.

  • +
  • Provide training opportunities in the Nordics using (Carpentries and) CodeRefinery training materials.

  • +
  • Evolve the project towards a community-driven project with a network of instructors and contributors.

  • +
+
+
+

Community

+
+_images/community.png +
+

Image showing the key areas of the CodeRefinery community: Workshops, chat inlcuding help channel, online meetings and co-working, +other collaborative training, eg on High Performance Computing topics.

+
+
+

CodeRefinery is not just workshops, we are community and want you to be part of it!

+

There are many different levels of involvement, from the occasional commenter in chat, +CodeRefinery ambassador (people who like the project and workshops and help us spreading the word) or lesson issue creators and lesson contributors to +local host, co-instructor or co-organizer.

+

Best first step in any case is to join the CodeRefinery Zulip chat +or let us know about your interest at support@coderefinery.org.

+
+
+

Target audience

+

One common question we get is how do we relate to the Carpentries. +This section describes how we see it:

+
+

Carpentries audience

+

The Carpentries aims to teach computational competence to learners through an applied approach, +avoiding the theoretical and general in favor of the practical and specific.

+

Mostly, learners do not need to have any prior experience in programming. +One major goal of a Carpentries workshop is to raise awareness on the tools researchers can learn/use to speed up their research.

+

By showing learners how to solve specific problems with specific tools and providing hands-on practice, +learners develops confidence for future learning.

+
+

Novices

+

We often qualify Carpentries learners as novices: they do not know what they need to learn yet. +A typical example is the usage of version control: the Carpentries lesson +Version Control with Git +aims to give a +very high level conceptual overview of Git but it does not explain how it can be used in research projects.

+
+
+
+

CodeRefinery audience

+

In that sense, CodeRefinery workshops differ from Carpentries workshops as we assume +our audience already writes code and scripts and we aim at teaching them best software practices.

+

Our learners usually do not have a good overview of best software practices but are aware of the need to learn them. +Very often, they know of the tools (Git, Jupyter, etc.) we are teaching +but have difficulties to make the best use of them in their software development workflow.

+

Whenever we can, we direct learners that do not have sufficient coding experience to Carpentries workshops.

+
+

Competent practitioners

+

We often qualify CodeRefinery learners as competent practitioners because they already have an understanding of their needs.

+
+ +
+
+

Keypoints: CodeRefinery

+
    +
  • Teaches intermediate-level software development tool lessons

  • +
  • It is difficult to define “best practices”, we try to teach “good enough” practices

  • +
  • Training network for other lessons

  • +
  • Publicly-funded discrete projects (3 projects actually) transitioning towards an open community project

  • +
  • We have online material, teaching, and exercise sessions

  • +
  • Our main target audience are competent practitioners, but also novices and experts can get something out of the workshops

  • +
  • We want more people to work with us, and to work with more people

  • +
+
+
+
+
+
+

Collaborative notes

+
+

Objectives

+
    +
  • Be able to provide a highly interactive online workshop environment with collaborative documents

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Exercise: 15 min

  • +
  • Questions & Answers: 5 min

  • +
+
+
+

Introduction

+

The Collaborative document is how you interact with the participants. +The participants can ask questions and give feedback through the collaborative +document. During a CodeRefinery session there can be a large a volume of questions. +A dedicated person, a Collaborative document-manager, is needed to answer and edit the collaborative document. +Let us see how the collaborative document is used, then discuss the role of +the editor or collaborative document-manager.

+
+
+

Collaborative document mechanics and controls

+

Technologies that can be used as a collaborative document are Hackmd, HedgeDoc, +or Google Docs

+

Hackmd or HedgeDoc are real-time text editor online. We use it to:

+
    +
  • As a threaded chat, to answer questions and provide other information without +interrupting the main flow of the room.

  • +
  • provide everyone with a more equal opportunity to ask questions.

  • +
  • create notes which will be archived, for your later reference.

  • +
+

You do not need to login/create an account to be able to edit the document.

+
+

Basic controls

+
+_images/hackmd--controls.png +
+

This may look slightly different on mobile devices and small windows.

+
+
+
    +
  • At the top (left or right), you can switch between view, +edit, and split view and edit modes.

  • +
  • You write in markdown here. Don’t +worry about the syntax, just see what others do and try to be like +that! Someone will come and fix any problems there may be.

  • +
  • Please go back to view mode if you think you won’t edit for a +while - it will still live update.

  • +
+
+
+

Asking questions

+

Always ask questions and add new sections at the very bottom. +You can also answer and comment on older questions, too.

+
+_images/hackmd--questions2.png +
+

Questions and answers in bullet points

+
+
+

Since we plan to publish the questions and answers later as part +of the workshop page, we recommend to not use any names. You can indicate +your own name to make it easier to discuss more during the workshop but +then always use this form: [name=Myname]. This makes it easier for +us to automatically remove all names before publishing the notes.

+

Other hints:

+
    +
  • Use +1 to agree with a statement or question (we are more likely +to comment on it).

  • +
  • Please leave some blank lines at the bottom

  • +
  • NOTE: Please don’t “select all”, it highlights for everyone and adds a +risk of losing data (there are periodic backups, but not instant).

  • +
  • It can be quite demanding to follow the collaborative document closely. Keep an eye +on it, but consider how distracted you may get from the course. For +things beyond the scope of the course, we may come back and answer +later.

  • +
+
+
+

Don’t get overwhelmed

+

There can be a flood of information on the collaborative document. Scan for what is +important, then if you would like come back later. But it is +important to keep checking it.

+
+
+

Privacy

+
    +
  • Assume the collaborative document is public and published: you never +need to put your name there.

  • +
  • The collaborative document will be published on the website afterwards. We will +remove all non-instructors names, but it’s easier if you don’t add +it there in the first place.

  • +
  • Please keep the link private during the workshop, since since +security is “editable by those who have the link”.

  • +
  • You can use [name=YOURNAME], to name yourself. We will remove +all names (but not the comments) before archiving the notes (use +this format to make it easy for us).

  • +
+
+
+
+

Exercise

+
+

Discuss how to collaborate and handle questions (15 min)

+

Write down your conclusions in the shared document. Items to discuss are:

+
    +
  • What is your experience with questions and discussions while teaching?

  • +
  • How do you deal with them?

  • +
  • What kind of technologies do you prefer: chat, shared document, or voices +and discussion raised during instruction? And why?

  • +
+
+
+
+

Collaborative Document Manager

+

We have one person who is a “Collaborative Document helper”. This isn’t the only +person that should edit and answer, but one person shouldn’t have too +much else on their mind so can focus on it. They also make sure that +the collaborative document is updated with exercise, break, and other meta-information to +keep people on track.

+

Below, (*) = important.

+
+

Before the workshop

+
    +
  • Create a new collaborative document for the workshop

  • +
  • make sure that editing is enabled for anyone without login

  • +
  • Add workshop information, links to the workshop page and material +and an example question and answer to the top of the collaborative document(see below)

  • +
+
+
+

Most things to edit (everyone)

+

Make it easy to post after the course and consistent to follow:

+
    +
  • Tag all names with [name=XXX] (so they can be removed later), +remove other personal data or make it obvious.

  • +
  • Add in information on exercises (new section for them, link, end +time, what to accomplish)

  • +
  • Make a logical section structure (# for title, ## for sections, +### for episodes, etc. - or what makes sense)

  • +
+
+
+

General Collaborative Document practices

+
+_images/hackmd--full-demo.png +
+

A live demo of a Collaborative Document during a Q&A time. The two instructors are +discussing some of the import answers. Multiple learners have asked +questions, multiple answers, and some remaining to be answered

+
+
+

Keep it formatted well:

+
    +
  • (*) Tag names you see with [name=XXX] so that we can remove it +later.

  • +
  • Heading level # is only the page title

  • +
  • Add a new ## heading when a new lesson or similar thing is +started (introduction, icebreaker, break between lessons, etc)

  • +
  • Add a new ### heading when a new episode, exercise, break +(within exercise session)

  • +
  • Ensure people are asking questions at the bottom, direct them there +if they aren’t.

  • +
  • (*) Ensure each question is a bullet point. Each answer or follow-up +should be a bullet point below.

    +
      +
    • Should you use more deeply nested bullet points, or have only one +level below the initial question? It depends on the context, but +if a conversation goes on too long, try not to let it go too +deep.

    • +
    +
  • +
+

Update with meta-talk, so that learners can follow along easily:

+
    +
  • Add Icebreaker and introductory material of the day. Try to talk to +people as they joined to get them to open the collaborative document and answer.

  • +
  • Anything important for following along should not be only said via +voice. It needs to be in the collaborative document, too.

  • +
  • New lessons or episodes, with links to them.

  • +
  • For exercises, link to exercise and add the duration, end time, +goals. If these are unclear, bring it up to the instructor by voice.

  • +
  • Add a status display about breaks.

  • +
+

Screenshare it when necessary:

+
    +
  • During breaks and other times, share the collaborative document(including the +notification about break, and when it ends).

  • +
  • It is nice if the arrangement allows some of the latest questions to +be seen, so people are reminded to ask there.

  • +
  • Someone else may do this, but should make sure it happens.

  • +
+

Answer questions

+
    +
  • If there is an question that should be answered by the instructor by +voice, bring it up (by voice) to the instructor immediately.

  • +
  • How soon do you answer questions? Two points of view:

    +
      +
    • Answer questions right away: can be really intense to follow.

    • +
    • Wait some so that we don’t overload learners: reduces the info +flow. But then do people need to check back more often.

    • +
    • You need to find your own balance. Maybe a quick answer right +away, and more detailed later. Or delay answers during the most +important parts of the lecture.

    • +
    +
  • +
  • Avoid wall-of-text answers. If reading an answer takes too long, it +puts the person (and other people who even try to read it) behind +even more by taking up valuable mental energy. If an answer needs a +wall of text, consider these alternatives:

    +
      +
    • Progressive bullet points getting more detailed (first ones +useful alone for basic cases)

    • +
    • Don’t be worried to say “don’t worry about this now, let’s talk +later.”

    • +
    • Figure out the root problem instead of answering every possible +interpretation

    • +
    • Declare it advanced and that you will come back later.

    • +
    +
  • +
+

Ensure it can be posted quickly:

+
    +
  • The collaborative document gets posted to the workshop webpage. For this, it needs some +minimal amount of formatting (it doesn’t need to be perfect, just +not horrible).

  • +
  • All names and private information needs to be stripped. This is why +you should rigorously tag all names with [name=XXX] so they can be +removed (see above).

    +
      +
    • Learner names can be completely removed. CR staff names can be +[name=CR] or something similar.

    • +
    • There may be other private URLs at the top or bottom.

    • +
    +
  • +
  • If possible, send the PR adding the collaborative document to the workshop webpage +(though others can do this, too).

  • +
+
+
+

Collaborative document format example

+
# Workshop, day 1
+
+
+## Lesson name
+https://coderefinery.github.io/lesson/
+
+### Episode name
+https://coderefinery.github.io/01-episode/
+
+- This is a question
+  - Anwser
+  - More detailed answer
+- question
+  - answer
+
+### Exercises:
+https://link-to-exercise/.../.../#section
+20 minutes, until xx:45
+Try to accomplish all of points 1-3.  Parts 4-5 are optional.
+
+Breakout room status:
+- room 2, need help with Linux permissions
+- room 5, done
+
+### Break
+:::danger
+We are on a 10 minute break until xx:10
+:::
+
+
+## Lesson 2
+https://coderefinery.github.io/lesson-2/
+
+
+
+
+
+

Posting the collaborative document to the website

+

The collaborative document should be posted sooner rather than later, and hopefully the +steps above will make it easy to do so quickly. You could wait a few +hours, to allow any remaining questions to be asked an answered.

+
    +
  • Download as markdown

  • +
  • Remove any private links at the top

  • +
  • Adjust headings so that they are reasonable

  • +
  • Look for private info and remove it

    +
      +
    • Search document for [name=???] (change to [name=staff] or +[name=learner])

    • +
    • Any names not tagged with [name=]

    • +
    • usernames in URLs

    • +
    • private links

    • +
    +
  • +
+
+
+

Feedback template

+
## Feedback, day N
+
+:::info
+### News for day N+1
+- .
+- .
+:::
+
+### Today was (multi-answer):
+- too fast: 
+- just right: 
+- too slow: 
+- too easy: 
+- right level: 
+- too advanced: 
+- I would recommend this course to others: 
+- Exercises were good: 
+- I would recommend today to others: 
+- I wouldn't recommend today: 
+
+### One good thing about today:
+- ...
+- ...
+
+### One thing to be improved for next time:
+- ...
+- ...
+
+### Any other comments:
+- ...
+- ...
+
+
+
+

Keypoints

+
    +
  • Having a collaborative document improves communication and interaction.

  • +
  • Answering questions requires a dedicated person - A Collaborative Document Manager.

  • +
  • The collaborative document should be posted on the web site as soon as possible.

  • +
+
+
+
+
+
+

A workshop seen from different perspectives

+
+

Objectives

+
    +
  • Understand the general structure of CodeRefinery workshops and why it is the way it is

  • +
  • Get to know the different roles of a workshop and which ones are the most essential ones

  • +
  • Understand the importance of installation instructions and how they contribute to learners success

  • +
  • Understand the importance of onboarding and a welcoming community for volunteers in a workshop

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 15 min

  • +
  • Roles journeys can be shortened to looking only at instructor role.

  • +
+
+
+

Note

+

This episode focuses on the large scale streamed workshop setup. Some of the features can also be applied to smaller scale workshops though.

+
+
+

Discussion

+
+

Discussion

+

In breakoutrooms: choose one or two questions to talk about your own experiences; summary in collaborative notes:

+
    +
  • What kind of roles have you been in yourself regarding workshops?

  • +
  • How were you prepared for your role?

  • +
  • What are the things you would like to know before a workshop?

  • +
  • How are you preparing your participants for your trainings?

  • +
  • What was the best workshop experience for you as learner, helper or instructor? What made it great?

  • +
+
+
+
+

One workshop - many parts

+
+_images/CR_workshop_setup.png +
+

Image showing the different phases of a CodeRefinery workshop described below. Also showing that while there is only two people teaching, many people work behind the scenes.

+
+
+
+

Before the workshop

+
    +
  • During winter/summer: “Someone” takes the coordinator role for the next workshop

  • +
  • Coordinator fills other roles:

    +
      +
    • Coordinator: collects necessary lesson updates, supports other coordinators

    • +
    • Registration coordinator: Sets up web page, starts and manages registration

    • +
    • Instructor coordinator: Finds instructors and onboards them

    • +
    • Advertising coordinator: Prepares advertizement texts and finds people to distribute them

    • +
    • Team coordinator: Gathers local organizers/teams

    • +
    • Bring your own code session coordinator: If available, offer BYOC session after main workshop

    • +
    +
  • +
  • Instructor: Onboarding with (instructor-) coordinator and previous instructor of lesson; update of lesson materials (urgent issues and personal touches)

  • +
  • Local organizer/Team lead: Group onboarding ~ week/or two before workshop

  • +
  • Learner: Gets installation instructions, invited to installation help session, workshop info from event page and summary via e-mail

  • +
  • Collaborative notes manager sets up the notes document

  • +
+
+

Note

+

Onboarding manuals

+
    +
  • Outline of what will happen during the workshop

  • +
  • Discussion of different strategies to handle the exercise sessions

  • +
  • Lowering the barrier to ask for support by meeting some organizers

  • +
  • Q&A

  • +
+
+
+

Note

+

Installation instructions

+
    +
  • Instructions for all operating systems

  • +
  • Goal: Learners leave the workshop and are ready to apply the learned tools and techniques to their own work

  • +
  • Support session for installation challenges

  • +
+
+
+
+

During the workshop

+
+_images/BYOC.png +
+

Image showing the different ways learners can do the exercises. No matter which way they choose, they always watch the stream and interact with instructors and organizers via collaborative notes. Individual learners do the exercises alone, people in online or local classrooms in addition get to discuss with their peers.

+
+
+
    +
  • Everyone watches stream

  • +
  • Co-instructors +- Present content +- Answer questions in collaborative notes

  • +
  • Collaborative notes manager

    +
      +
    • Keeps the collaborative notes clean

    • +
    • Helps answering questions

    • +
    • Adds sections

    • +
    • Archives the document after each day

    • +
    +
  • +
  • Learners do exercises individually or in team

  • +
  • Local organizer / Team lead

    +
      +
    • Guides learners through exercises

    • +
    • Facilitates discussion

    • +
    +
  • +
  • (Registration-) coordinator sends out e-mails to participants after each day (summary + preparation)

  • +
  • Director/Broadcaster manages the streaming (see session 4)

  • +
+
+
+

After the workshop

+
    +
  • Coordinator collects lessons learned based on experience and feedback and turns them into issues

  • +
  • Coordinator organizes debriefing week after the workshop, where anyone can join to give feedback

  • +
  • “Someone” sends out post-workshop survey half a year after workshop

  • +
  • Coordinator organizes “Bring your own code” sessions

  • +
  • Broadcaster prepares and shares recording (see session 4)

  • +
+
+

Note

+

Bring your own code sessions

+

We want to support learners to apply what they have learned in the workshop to their own work by offering one/two sessions where they can drop in, and discuss challenges with CodeRefinery instructors and helpers.

+
+_images/welcome.png +
+

Image showing a classroom learning about git leading to a discussion between student and teacher to start a welcoming environment for asking for help.

+
+
+
+
+
+
+

This sounds like a lot of people and time investment!

+
    +
  • Many roles can be combined or adjusted as needed

  • +
  • Some roles can be taken on by multiple people

  • +
+

So how many people are needed for this kind of workshop?

+
    +
  • Recommended minimum: 2-3 people

  • +
  • Optimum: ~ 4-5 people +The more people you involve, the more time goes into coordination work.

  • +
+
+
+

How did we get to this setup?

+
    +
  • Collaborative in-person workshops since 2016 around the Nordics

  • +
  • Moved online in 2020

  • +
  • Started with “traditional zoom” workshops, breakoutrooms, volunteer helpers

  • +
  • Thought about scaling and ease of joining -> current setup (More about this in session 4)

  • +
  • Continuous development

  • +
+

We also still do smaller scale local workshops, if instructors are available. +You can offer your own CodeRefinery workshop by inviting other CodeRefinery instructors. +You can also reuse single lessons and integrate them into your own teaching.

+
+
+

Workshop roles and their journeys

+
+

Individual learner journey

+
    +
  • Registration

  • +
  • Installation

  • +
  • (if appicable: Invited to local meetup)

  • +
  • Workshop

    +
      +
    • Watch stream

    • +
    • Q&A in notes

    • +
    • Exercises alone or in team

    • +
    • Daily feedback

    • +
    +
  • +
  • Debrief/ Feedback session

  • +
  • Post workshop survey

  • +
+
+
+

Instructor journey

+
    +
  • Indicate interest in CodeRefinery chat

  • +
  • Onboarding

  • +
  • Lesson material updates

  • +
  • Teaching

  • +
  • (if wished: supports answering questions in notes)

  • +
  • Debrief

  • +
+
+
+

Team lead / Local host journey

+
    +
  • Registration

  • +
  • (if applicable: run own registration)

  • +
  • Onboarding

  • +
  • Workshop

    +
      +
    • Watch stream

    • +
    • Facilitate exercises/discussions

    • +
    • Daily feedback

    • +
    +
  • +
  • Debrief / feedback / survey

  • +
+
+
+

Other roles

+

Director and broadcaster roles will be discussed in Session 4. +For more in-depth descriptions and other roles (host, instructor, registration coordinator, etc), see also our CodeRefinery manuals.

+
+
+
+

Different roles as stepping stones for community involvement

+
+_images/steps.png +
+

Image showing a person jumping from step to step following learner, helper, expert helper, co-instructor, co-organizer.

+
+
+

There is no “one way” to get involved. Do what feels right. +Interested in teaching with us? Let us know and we can discuss what is a suitable path for you!

+
+

Keypoints

+
    +
  • CodeRefinery workshops are a collaborative effort with many different roles

  • +
  • Onboarding the different roles is one key aspect of our workshops

  • +
  • Everyone has their own path

  • +
+
+
+
+
+

Sound

+
+

Objectives

+
    +
  • Understand that sound quality is very important

  • +
  • Evaluate your and others sound quality and know how to improve it

  • +
  • Test tips and tricks for achieving good sound quality

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Exercises: 10 min

  • +
+
+
+

The importance of audio

+
    +
  • Pleasing audio quality makes events much more enjoyable

  • +
  • Audio is one of the most important things you can control

  • +
  • Things that can go wrong:

    +
      +
    • Too quiet

    • +
    • Too loud

    • +
    • Instructors’ volumes imbalanced

    • +
    • Background noise

    • +
    • Low-quality/breaking up audio hard to hear.

    • +
    • “Ducking” (first words lower volume, or lower volume other times)

    • +
    +
  • +
+
+
+

Tips for good sound quality

+
    +
  • Have a headset with mounted microphone

    +
      +
    • Even if you have a professional external microphone, it doesn’t +matter if your room has bad acoustics.

    • +
    • The close pickup can’t be beat with normal tools.

    • +
    • As long as it’s headset mounted, price doesn’t seem to matter +that much.

    • +
    +
  • +
  • Don’t use Bluetooth

    +
      +
    • Bluetooth can have too much latency (300-500ms)

    • +
    • This may seem small but for interactive work, it’s a lot

    • +
    • Use a wired headset, or wireless with a non-Bluetooth USB plug +(like gaming headsets have). These have much lower latency.

    • +
    • Bluetooth 5 can have much lower latency, but you probably +shouldn’t count on that without testing.

    • +
    • It can also have lower sound quality on some devices due to +bandwidth limitations.

    • +
    +
  • +
  • Once you have a headset, turn input noise cancellation to low +(wherever it might be: headphone, meeting software, etc.).

  • +
+
+
+

Balancing and dynamic adjustment

+
    +
  • It’s important that instructors volumes match.

  • +
  • An exercise will go over a systematic procedure for matching +volumes.

    +
      +
    • Practice so that you can do this quickly.

    • +
    +
  • +
  • May need re-adjusting when instructors swap out or start getting +excited.

  • +
  • An exercise below will demonstrate our procedure.

  • +
+
+
+

Speak up when there are problems

+
    +
  • If you notice someone with audio issues, let them know right away +(voice if bad, or chat/notes if less urgent).

  • +
  • Take the time to fix it as soon as practical.

  • +
  • Make a culture of speaking up, helping, and not suffering.

  • +
+
+
+

Recommendations

+
    +
  • Procure some reasonable headset.

  • +
  • Low/medium-priced gaming-type headsets have worked well for us.

    +
      +
    • (gaming headsets usually aren’t Bluetooth, because gaming needs +low latency.)

    • +
    +
  • +
  • Show this page to your workplace (if you have one) and call a good +headset work equipment.

  • +
+
+
+

Exercises

+
+

Sound-1: Evaluate sound quality

+

It’s important to be able to discuss with others the quality of their +audio. They can’t hear themselves, after all.

+
    +
  • Within the teams, discuss each person’s audio quality and what kind +of setup they have.

  • +
  • Be respectful and constructive (and realize that people came +prepared to listen, not teach).

  • +
  • Consider, for example

    +
      +
    • Volume

    • +
    • Clarity

    • +
    • Background noise

    • +
    • Noise cancellation artifacts

    • +
    • “Ducking”: first words at lower volume or missing

    • +
    +
  • +
  • Discuss how to bring this up during other courses and meetings.

  • +
+
+
+

Sound-2: Adjust volume up and down

+

In addition to individual quality, it is important that sound is +balanced among all instructors. Have you ever been to a event when +one person is too quiet and they can’t make themselves any louder? +And they can’t adjust it?

+

You should ensure that you have a range of volumes available to you. +You might have to look into several different locations in order to +make the full adjustment ().

+
    +
  • Go to your sound settings

  • +
  • One by one, each person

    +
      +
    • Adjusts their microphone volume so quiet that they can’t be heard.

    • +
    • Adjusts their microphone volume so that it is extremely loud (this +may require going beyond 100% if possible).

    • +
    +
  • +
  • Basically, make sure you aren’t so close to either end that you have +no potential to make an adjustment in that direction.

  • +
  • Everyone tries to set the volume to something reasonable, in +preparation for the next exercise.

  • +
+

Once you know where these settings are , you won’t be panicked when the +volume is too low or high during a course.

+
+
+

Sound-3: Do a balance check

+

It’s important that instructor audio is balanced (the same volume). +But how can you do this?

+
    +
  • Pick a leader.

  • +
  • The leader decides the order (“I am first, then [name-1] and +[name-2]”)

  • +
  • The leader says “one”. Everyone else says “one” in the order +specified.

  • +
  • The leader says “two”. Everyone else says “two” in the order.

  • +
  • The leader asks for opinions on who they think is louder or softer. +If there are more than three people, you can figure it out +yourselves. With less than two, you have to ask someone in the +audience.

  • +
+

Example:

+
    +
  • Leader: Let’s do a sound check. I am first, then AAA and BBB.

  • +
  • Leader: One

  • +
  • AAA: One

  • +
  • BBB: One

  • +
  • Leader: Two

  • +
  • AAA: Two

  • +
  • BBB: Two

  • +
  • Leader: Three

  • +
  • AAA: Three

  • +
  • BBB: Three

  • +
  • Leader: How did that sound to everyone?

  • +
  • [Someone else]: Leader and BBB were pretty similar but AAA is a bit +lower.

  • +
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Audio quality is important and one of the most notable parts of the +workshop.

  • +
  • Improving audio isn’t hard or expensive, but does require preparation.

  • +
+
+
+
+
+

How to prepare a quality screen-share

+
+

Objectives

+
    +
  • Discuss the importance of a well planned screen-share.

  • +
  • Learn how to prepare and how to test your screen-share setup.

  • +
  • Know about typical pitfalls and habits to avoid.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 15 min

  • +
  • Exercises: 15 min

  • +
+
+
+

Share portrait layout instead of sharing entire screen when teaching online

+
    +
  • Many learners will have a smaller screen than you.

  • +
  • You should plan for learners with only one small screen.

  • +
  • A learner will need to focus on both your screen share and their +work.

  • +
  • Share a portrait/vertical half of your screen (840 × 1080 is our standard and your +maximum).

  • +
  • Zoom provides a “Share a part of screen” that is good for this.

    +
      +
    • Our latest streaming setup (day 4) can take the portrait part for +you so you can share landscape.

    • +
    • Zoom + Linux + Wayland display manager doesn’t have “Share a +portion of the screen”

      +
        +
      • You can share a single window portrait.

      • +
      • Or you can start your desktop session in “X11” or “Xorg” legacy +mode.

      • +
      • Or possibly other workarounds (does anyone know other solutions?)

      • +
      +
    • +
    +
  • +
+
+_images/landscape.png +
+

A FullHD 1920x1080 screen shared. Learners have to make this really small if +they want to have something else open.

+
+
+
+_images/portrait.png +
+

Portrait layout. Allows learners to have something else open in the other half.

+
+
+

Motivation for portrait layout:

+
    +
  • This makes it easier for you to look at some other notes or to coordinate +with other instructors at the same time +without distracting with too much information.

  • +
  • This makes it possible for participants to have something else open in the +other screen half: terminal or browser or notebook.

  • +
+
+

Instructor perspective

+
+_images/instructor.png +
+

I1: +This is how it can look for the instructor. Zoom is sharing a portion of the left +side, the right side is free for following notes, chat, etc.

+
+
+
+
+

Learner perspective

+

Here are three examples of how it can look for the learner.

+
+_images/learner-large.png +
+

L1: +Learner with a large screen, Zoom in dual-monitor mode so that the instructor +pictures are not shown. Screen-share is on the left side, collaborative notes +at bottom left, terminal and web browser on the right.

+
+
+
+_images/learner-normal.png +
+

L2: +A learner with a single large screen (Zoom in “single monitor mode”). +Instructor screen share at right, learner stuff at left.

+
+
+
+_images/learner-small.png +
+

L3: +A learner with a particularly small screen. Instructor screen-share at left, +your windows at right.

+
+
+
+
+
+

Share the history of your commands

+

Even if you type slowly it is almost impossible to follow every command. We +all get distracted or want to read up on something or while following a command +fails on the learner laptop while instructor gets no error.

+

Add pauses and share the commands that you have typed so that one can catch up.

+

Below are some examples (some more successful than others) of sharing history +of commands.

+
+_images/history-portrait.png +
+

H1: +A vertical screen layout shared. Note the extra shell history at the top. The +web browser is at the bottom, because the Zoom toolbar can cover the bottom +bit.

+
+
+
+_images/history-rsh.png +
+

H2: +This isn’t a screen-share from CodeRefinery, but may be instructive. Note the +horizontal layout and shell history at the bottom right.

+
+
+
+_images/history-landscape-dark.png +
+

H3: +Similar to above, but dark. Includes contents on the right.

+
+
+
+_images/history-portrait-light.png +
+

H4: +Jupyter + terminal, including the fish shell and the terminal history.

+
+
+
+_images/history-portrait-dark.png +
+

H5: +Lesson + terminal, tmux plus terminal history and dark background.

+
+
+
+_images/portrait.png +
+

H6: +HPC Kickstart course. Note the colors contrast of the windows and colors of +the prompt and text. The history is smaller and doesn’t take up primary +working space. The working directory is in the window title bar.

+
+
+
+https://raw.githubusercontent.com/bast/history-window/main/demo.gif +
+

H7: +Show command history “picture-in-picture”, in the same terminal window.

+
+
+
+
+

How to configure history sharing

+

You need to find a way to show the recent commands you have entered, so that +learners can see the recent commands. Below are many solutions. Try them out +and see what works for you.

+
    +
  • prompt-log: +It adds a interesting idea that the command you enter is in color and also +provides terminal history before the command returns.

  • +
  • Simple: The simple way is PROMPT_COMMAND="history -a" and then +tail -f -n0 ~/.bash_history, but this doesn’t capture ssh, +sub-shells, and only shows the command after it is completed.

  • +
  • Better yet still simple: Many Software Carpentry instructors use +this script, +which sets the prompt, splits the terminal window using tmux and displays command history +in the upper panel. Requirement: tmux

  • +
  • Better (bash): This prints the output before the command is run, +instead of after. Tail with tail -f ~/demos.out.

    +
    BASH_LOG=~/demos.out
    +bash_log_commands () {
    +    # https://superuser.com/questions/175799
    +    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    +    [[ "$PROMPT_COMMAND" =~ "$BASH_COMMAND" ]] && return # don't cause a preexec for $PROMPT_COMMAND
    +    local this_command=`HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"`;
    +    echo "$this_command" >> "$BASH_LOG"
    +}
    +trap 'bash_log_commands' DEBUG
    +
    +
    +
  • +
  • Better (zsh): This works like above, with zsh. Tail with tail -f ~/demos.out.

    +
    preexec() { echo $1 >> ~/demos.out }
    +
    +
    +
  • +
  • Better (fish): This works like above, but for fish. Tail with +tail -f ~/demos.out.

    +
    function cmd_log --on-event fish_preexec ; echo "$argv" >> ~/demos.out  ; end
    +
    +
    +
  • +
  • Better (tmuxp): This will save some typing. +TmuxP is a Python program (pip install tmuxp) that gives you programmable tmux sessions. One configuration that +works (in this case for fish shell):

    +
    session_name: demo
    +windows:
    +  - window_name: demo
    +    layout: main-horizontal
    +    options:
    +      main-pane-height: 7
    +    panes:
    +      - shell_command:
    +          - touch /tmp/demo.history
    +          - tail -f /tmp/demo.history
    +      - shell_command:
    +          - function cmd_log --on-event fish_preexec ; echo "$argv" >> /tmp/demo.history  ; end
    +
    +
    +
  • +
  • Windows PowerShell: In Windows Terminal, +a split can be made by pressing CTRL+SHIFT+=. Then, in one of the splits, the following +PowerShell command will start tracking the shell history:

    +
    Get-Content (Get-PSReadlineOption).HistorySavePath -Wait
    +
    +
    +

    Unfortunately, this only shows commands after they have been executed.

    +
  • +
  • Tavatar: shell history mirroring teaching tool can copy recent history to a remote server.

  • +
  • history-window: Show command +history “picture-in-picture” when teaching command line. Requires Bash.

  • +
+
+
+

Font, colors, and prompt

+
+

Terminal color schemes

+
    +
  • Dark text on light background, not dark theme. Research and our +experience says that dark-text-on-light is better in some cases and +similar in others.

  • +
  • You might want to make the background light grey, to avoid +over-saturating people’s eyes and provide some contrast to the pure +white web browser. (this was an accessibility recommendation when +looking for ideal color schemes)

  • +
  • Do you have any yellows or reds in your prompt or program outputs? +Adjust colors if possible.

  • +
+
+
+

Font size

+
    +
  • Font should be large (a separate history terminal can have a smaller +font).

  • +
  • Be prepared to resize the terminal and font as needed. Find out +the keyboard shortcuts to do this since you will need it.

  • +
+
+
+

Prompt

+

At the beginning of the workshop your goal is to have a shell +as easy to follow as possible and as close to what learners will +see on their screens:

+
    +
  • Your prompt should be minimal: few distractions, and not take up many +columns of text.

  • +
  • prompt-log does +this for you.

  • +
  • The minimum to do is is export PS1='\$ '.

  • +
  • Blank line between entries: export PS1='\n\$ '.

  • +
  • Have a space after the $ or % or whatever prompt character you +use.

  • +
  • Strongly consider the Bash shell. This is what most new people will +use, and Bash will be less confusing to them.

  • +
  • Eliminate menu bars and any other decoration that uses valuable +screen space.

  • +
  • Add colors only if it simplifies the reading of the prompt.

  • +
+

Later in the workshop or in more advanced lessons:

+
    +
  • Using other shells and being more adventurous is OK - learners will +know what is essential to the terminal and what is extra for your +environment.

  • +
+

Try to find a good balance between:

+
    +
  • Showing a simple setup and showing a more realistic setup.

  • +
  • Showing a consistent setup among all instructors and showing a +variety of setups.

  • +
+
+
+
+

Habits we need to un-learn

+
    +
  • Do not clear the terminal. Un-learn CTRL-L or clear if possible. +More people will wonder what +just got lost than are helped by seeing a blank screen. Push +ENTER a few times instead to add some white space.

  • +
  • Do not rapidly switch between windows or navigate quickly between multiple +terminals, browser tabs, etc. This is useful during your own work when nobody +is watching, but it is very hard to follow for learners.

  • +
  • Avoid using aliases or shortcuts that are not part of the +standard setup. Learners probably don’t have them, and they will fail +if they try to follow your typing. Consider even to rename corresponding +files (.bashrc, .gitconfig, .ssh/config, .ssh/authorized_keys, .conda/*).

  • +
  • Be careful about using tab completion or reverse history search if these +haven’t been introduced yet.

  • +
+
+
+

Desktop environment and browser

+
    +
  • Try to remove window title bars if they take up lots of space +without adding value to the learner.

  • +
  • Can you easily resize your windows for adjusting during teaching?

  • +
  • Does your web browser have a way to reduce its menu bars and other +decoration size?

    +
      +
    • Firefox-based browsers: go to about:config and set +layout.css.devPixelsPerPx to a value slightly smaller than one, +like 0.75. Be careful you don’t set it too small or large since +it might be hard to recover! When you set it to something smaller +than 1, all window decorations become smaller, and you compensate +by zooming in on the website more (you can set the default zoom to +be greater than 100% to compensate). Overall, you get more +information and less distraction.

    • +
    +
  • +
+
+
+

How to switch between teaching setup and work setup?

+
    +
  • Make a dedicated “demos” profile in your terminal emulator, if +relevant. Or use a different terminal emulator just for demos.

  • +
  • Same idea for the browser: Consider using a different browser profile for +teaching/demos.

  • +
  • Another idea is to containerize the setup for teaching. +We might demonstrate this during the Sharing teaching gems session later.

  • +
+
+
+

Keypoints

+
    +
  • Share portrait layout instead of sharing entire screen

  • +
  • Adjust your prompt to make commands easy to read

  • +
  • Readability and beauty is important: adjust your setup for your audience

  • +
  • Share the history of your commands

  • +
  • Get set up a few days in advance and get feedback from someone else. +Feedback and time to improve is very important to make things clear and accessible. +10 minutes before the session starts is typically too late.

  • +
+
+
+
+

Exercises

+
+

Evaluate screen captures (20 min)

+

Evaluate screenshots on this page. Discuss the trade-offs of each one. Which +one do you prefer? Which are useful in each situation?

+

Please take notes in the collaborative document.

+
+
+

Set up your own environment (20 min)

+

Set up your screen to teach something. Get some feedback from another learner +or your exercise group.

+
+
+
+

Other resources

+ +
+
+
+
+
+

Computational thinking

+
+

Objectives

+
    +
  • Explain what is computational thinking

  • +
  • Get to know how the theory of computational thinking can be used in teaching

  • +
  • Short exercise

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 10 min

  • +
+
+

Materials available as slides.

+
+

Keypoints

+
    +
  • Computational Thinking consists of 4 main parts: decomposition, pattern recognition, abstraction and algorithmic design.

  • +
  • How can this be a useful framework for solving problems?

  • +
  • How can this be used practically?

  • +
+
+
+
+

CodeRefinery teaching philosophies

+
+

Objectives

+
    +
  • Get to know the teaching philosophies of CodeRefinery instructors

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Discussion: 20 min

  • +
+
+
+

Introduction

+

During this episode we split into breakoutrooms and discuss own teaching philosophies. +Collect your teaching philosophies in the collaborative document. We will be going through +these and the end of the lesson.

+
+

Ice-breaker in groups (20 minutes)

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+
+

Instructor views

+

Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops.

+

It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us.

+
+

Video recordings

+

We have recorded some of the below as videos: https://www.youtube.com/playlist?list=PLpLblYHCzJAAHF89P-GCjEXWC8CF-7nhX

+
+
+

Bjørn Lindi

+

My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this “BLOB” (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the “BLOB”, to be able to share it with others.

+

In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic.

+

When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson.

+

Tools that I find useful in preparing a lesson is concept maps and Learner Personas (though I have developed too few of them):

+ +
+
+

Radovan Bast

+

My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos.

+

My goal for a lesson is to spark curiosity to try things after the lesson, both +for the novices (“This looks like a useful tool, I want to try using it after +the workshop.”) and the more experienced participants (“Aha - I did not know +you could do this. I wonder whether I can make it work with X.”). I like to +start lessons with a question because this makes participants look up from +their browsers.

+

Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise.

+

For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate the +answer.

+

I try to avoid jargon and “war stories” from the professional developers’ +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid “customer”, +“production”, also a lot of Agile jargon is hard to relate to.

+

Less and clear is better than more and unclear. Simple examples are better than +complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +“simply”, “just”, “easy”. If participants take home one or two points from a +lesson, that’s for me success.

+

I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don’t want to be +surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or slide. +This allows me to skip and distill the essence and not read bullet point by +bullet point.

+

I try to never deviate from the script and if I do, be very explicit about it.

+

A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel listening to me.

+

I very much like the co-teaching approach where the other person helps +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson.

+
+
+

Sabry Razick

+

My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case.

+
+
+

Richard Darst

+

Like many people, I’ve often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I’ve realized long ago that my most important lessons weren’t +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I’ve realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds.

+

My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I’m often start at the +very basics, because this is what I see missing most often.

+

When teaching, I like lots of audience questions and don’t mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don’t have to know everything perfectly, just show how +you’d approach a problem.

+
+
+

Stepas Toliautas

+

I aim for my learners to understand things (concepts, techniques…), instead of just memorizing them. The phrase I use from time to time when teaching information technology topics (be it hardware or software) is “there is no magic”: everything can be explained if necessary. While CodeRefinery also emphasizes usefulness/ immediate applicability of the content, often having the correct notions actually helps to start using them sooner and with less mistakes.

+

I try to guide my audience through the presented material with occasional questions related to previous topics and common knowledge – to help them link the concepts already during the lesson. I’m also fully aware that waiting for someone to answer is quite uncomfortable in-person and doubly so in an online environment, especially if no one uses their cameras :)

+

And if I get the question I don’t have the answer for (or material to show it) at the moment, in university classes I prepare and come back to it next time. While with one-off workshops there might not be a “next time”, open-source material used by CodeRefinery allows to have the same outcome: the latest and greatest version stays available for self-study afterwards.

+
+
+
+

Summary

+
+

Keypoints

+
    +
  • People have different viewpoints on teaching.

  • +
+
+
+
+
+

Co-teaching

+
+

Objectives

+
    +
  • Get to know the principle of co-teaching: How we do it and how you can too.

  • +
  • Learn the team teaching concept and how to tailor it to your situation.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 15 min

  • +
  • Exercises: 10 min

  • +
  • Discussion: 5 min

  • +
+
+
+

Overview

+

CodeRefinery lessons benefit from the application of the concepts of co-teaching.

+
+

Co-teaching

+

Co-teaching can be defined as “the division of labor between educators to plan, organize, instruct and make assessments on the same group of students, generally in a common classroom, and often with a strong focus on those teaching as a team complementing one another’s particular skills or other strengths”.

+
+

Co-teaching can be used in various forms, some of which are present in our workshops:

+
    +
  • Teaching + support, e.g. one of the teachers leading instruction while the other watches over and maintains the collaborative document (HackMD/HedgeDoc/…).

  • +
  • Another similar example is remote learning groups that watch the streamed CodeRefinery lessons guided by the local instructors.

  • +
  • Having open-source material and planning jointly allows multiple instances of a lesson to be held by multiple teachers:

    +
      +
    • parallel teaching, to different audiences at the same time,

    • +
    • alternative teaching, to different audiences at the same or different time, with potential content adjustments (for example, different installation procedures).

    • +
    +
  • +
  • Team teaching, where the lesson is presented by multiple (in most cases, two) teachers who actively engage in conversation with each other. The team-teaching concept is explained in more detail in the CodeRefinery manual.

  • +
+

In reality, different forms are very often mixed or fused together, even within a single lesson.

+

Co-teaching is not an online-only concept. However, it is very practical in online teaching due to larger number of instructors and learners potentially available to join a teaching session.

+
+
+

Co-teaching and team teaching benefits

+
    +
  • It saves preparation time. Co-teachers can rely on each other’s strengths while creating/ revising the material as well as in unexpected situations during the lesson.

  • +
  • It helps with onboarding new instructors. One of the co-teachers can be learning at the same time, either the subtleties of the material taught (in this case literally being the “voice of the audience”) or the teaching process itself.

  • +
  • Team teaching looks more interactive and engaging to the audience in many cases, without forcing the learners to speak up if they can’t or don’t want to do so.

  • +
  • It also ensures responsive feedback and less workload by having more active minds.

  • +
+
+

Are there any downsides?

+

Not every learner and not every instructor might like the team-teaching approach.

+
    +
  • It might seem less structured, unprepared, and chaotic, even with preparation.

    +
      +
    • It might create situations where instructors accidentally talk over each other or “interrupt” and change the flow of the lesson.

    • +
    • For some instructors it can be stressful to not know in advance what questions they get asked from the co-instructor.

    • +
    • Sometimes when an unexpected question is asked that throws the other instructor off, it can add to the feeling of chaos and unpreparedness.

    • +
    +
  • +
  • It can be interactive and engaging but it can also end up awkward if the co-teachers don’t have a good synergy.

    +
      +
    • Can sound awkward: Main instructor talking all the time and at the end asking co-instructor whether everything is clear and co-instructor only saying “yes”.

    • +
    • Possibly more engaging: Co-instructor asking questions which help with the flow and a common understanding of the material.

    • +
    +
  • +
+
+
+
+

Team teaching specifics

+
    +
  • For successful team teaching, additional coordination is needed, first of all to agree on the teaching model (see below) and the person in control (the director) for the lesson or its parts.

  • +
  • It’s useful to keep track of the lecture plan. The discussion is a good way to make lesson more interactive and adjust to the audience, but deviating too much will become disorienting (for example, if someone dropped their attention for a minute and now is trying to catch-up by reading lecture notes).

  • +
  • Experienced solo teacher might have a habit to keep talking (lecturing), while the co-teacher might not want to “interrupt”. Therefore, it is important for the leading presenter to anticipate and allow for remarks/ questions, and this can be different from one’s previous teaching style at first.

  • +
+
+
+

Team teaching models

+

We propose two basic models, but of course there is a constant continuum.

+
+

Guide and demo-giver

+

One person serves the role of guide, explaining the big picture and context of the examples.

+

Another, the demo-giver,

+
    +
  • shows the typing and does the examples,

  • +
  • might take the role of a learner who is asking about what is going on, to actually explain the details, or to comment occasionally.

  • +
+

Hands-on demos and exercises work especially well like this.

+
+
+

Presenter and interviewer

+

In this case, one is the presenter who is mostly explaining (including demos or examples), and trying to move the forward through the material.

+

Another, the interviewer,

+
    +
  • serves as a learner or spotter,

  • +
  • fills in gaps by asking relevant questions,

  • +
  • tries to comment to the presenter when things are going off track.

  • +
+

This can be seen as closer to classical teaching, but with a dedicated and prepared “voice of the audience”.

+
+
+

Exercise

+
+

Discuss the models of team teaching (10 min)

+

While in breakout rooms, discuss one of the basic team-teaching models presented here:

+
    +
  • Have you already tried this or similar model in your teaching?

  • +
  • Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best?

  • +
+

Write your comments in the collaborative document.

+
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Co-teaching focuses on complementing individual skills and strengths in teaching process.

  • +
  • Co-teaching may save time, reduce teachers’ workload and make lessons more interactive/ engaging.

  • +
  • Team teaching requires some adjustments in lesson preparation and delivery.

  • +
+
+
+
+
+

Sharing teaching gems

+
+

Objectives

+
    +
  • Our goal is to share our teaching tricks and tools and demonstrate them in +very short presentations/discussions.

  • +
+
+
+

Instructor note

+
    +
  • Demonstrations: 35 min

  • +
+
+

Here we encourage participants to take the screen share for 3 minutes and +demonstrate either some tool or trick they found useful for their teaching or +something from a course you liked.

+
+
+
+
+

Session 4 intro

+

This session covers streaming and technical production. Some +introductory notes:

+
    +
  • (As of 2024) This is the first and only comprehensive introduction +to our online streaming.

  • +
  • These practices are new and well-refined internally, but a +different kind of refinement is needed to teach and reuse them.

  • +
  • The lessons have outlines of what to talk about, but it’s just an +outline. It is not refined, since thees things are new. Many +things will have to be figured out as we talk.

  • +
  • This session is a demo of lots of basics.

    +
      +
    • Ask questions - otherwise it will be boring

    • +
    • If you want to use this in real life: you will need mentoring +sessions and active help. Contact us to do that.

    • +
    +
  • +
+
+

Warning

+

Audio and video weirdness

+

We are setting up video and audio recording, but also capturing that +for re-sharing it. There may be anomalies as video or audio +feedback. Please be prepared.

+
+
+
+

Why we stream

+
+

Objectives

+
    +
  • Learn the general history of CodeRefinery streaming.

  • +
  • Discuss the benefits of streaming and recording

  • +
  • Discuss the downsides and difficulties

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 10 min

  • +
  • Q&A: 5 min

  • +
  • Exercises: 0 min

  • +
+
+

This is a general discussion of the topics of the day, focused on the +history of why we stream and record, how we got here, and how people +feel about it. We won’t focus on how anything is done.

+
+

Icebreaker questions

+
    +
  • What is the most people you have taught for?

  • +
  • What are the distinct parts of teaching, that can be +separated? (teaching, helping, etc)

  • +
+
+
+

What is streaming and recording?

+
    +
  • Streaming is mass communication: one to many

    +
      +
    • Interaction audience→presenters is more limited (but different)

    • +
    +
  • +
  • Using consumer-grade tools, normal people can reach huge audiences +by Twitch/YouTube/etc.

  • +
  • This isn’t actually that hard: people with much less training than +us do it all the time.

  • +
  • They reach huge audiences and maintain engagement for long events.

  • +
+

Recording and rapid video editing is useful even without +streaming.

+
+
+

History

+
    +
  • In-person workshops

    +
      +
    • 3 × full day, required travel, infrequent, one-shot

    • +
    +
  • +
  • Covid and remote teaching

    +
      +
    • Traditional “Zoom” teaching several times

    • +
    +
  • +
  • Mega-CodeRefinery workshop

    +
      +
    • 100-person Zoom teaching

    • +
    • Emphasis on teams

    • +
    +
  • +
  • Research Software Hour

    +
      +
    • Livestream free-form discussions on Twitch

    • +
    +
  • +
  • Streamed “HPC Kickstart” courses

  • +
+
+
+

Benefits and disadvantages

+

Benefits:

+
    +
  • Larger size gives more (but different) interaction possibility

    +
      +
    • “Notes” for async Q&A

    • +
    +
  • +
  • Recording (with no privacy risk) allows instant reviews

  • +
  • Stream-scale allows for many of the things you have learned about in +days 1-3.

  • +
+

Disadvantages:

+
    +
  • Requires training for using the tools

  • +
  • Requires a certain scale to be worth it

  • +
  • Coordination is much harder for big events

  • +
+

When would I recommend it?

+
    +
  • No: For small courses

  • +
  • Questionable: Medium sized courses with no videos

  • +
  • Yes: When you want the largest audience

  • +
  • Yes: When you want without registration required

  • +
  • Yes: When you want good reusability/fast videos

  • +
+
+
+

Future prospects (briefly)

+
    +
  • Streaming probably stays as a CodeRefinery tool

  • +
  • We can scale our courses much larger than they are now. Why don’t +we, together with others?

  • +
  • These tools are useful in other places too

    +
      +
    • I’ve used them to record my own talks to make videos of my +single-person presentations or record conference talks nicer than Zoom.

    • +
    +
  • +
+
+
+

Q&A

+

Q&A from audience

+
+

Keypoints

+
    +
  • Streaming optimizes a course for different things

  • +
  • The disadvantages can be compensated for

  • +
  • There are benefits and disadvantages

  • +
+
+
+
+
+

Behind the stream

+
+

Objectives

+
    +
  • Take a first look at the broadcaster’s view.

  • +
  • Get to know what happens “behind the stream” of a workshop

  • +
  • See what the “broadcaster” sees and what they need to do.

  • +
  • Not yet: learn details of how to do this.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Q&A 10 min

  • +
+
+

In this episode, you’ll see an end-to-end view of streaming from the +broadcaster’s point of view. It’s a tour but not an explanation or +tutorial.

+
+

Who does what

+

We have certain role definitions:

+
    +
  • Broadcaster: Our term for the person who manages the streaming.

  • +
  • Director: Person who is guiding the instructors to their +sessions, changing the scenes, calling the breaks, etc.

    +
      +
    • Could be the same as broadcaster.

    • +
    +
  • +
  • Instructor: One who is teaching. They don’t have to know +anything else about how streaming works.

  • +
+

This lesson describes what the Broadcaster/Director sees.

+
+
+

Window layouts

+

What does the broadcaster see on their screen?

+
    +
  • What are the main windows you see?

  • +
  • What do each of them do?

  • +
  • Which ones do you need to focus on?

  • +
  • How do you keep all this straight in your head?

  • +
+
+
+

CodeRefinery control panel

+
    +
  • A custom application that controls scenes

  • +
  • Based on OBS-websocket (remote control connection for OBS - we’ll +learn about this later)

  • +
  • Can also work remotely, so that you can have a remote director

  • +
+
+
+

How scenes are controlled

+

What has to be done during a course?

+
    +
  • How do you start the stream?

  • +
  • How do you change the view?

  • +
  • How do you adjust things based on what the instructors share?

  • +
  • How do you coordinate with the instructors?

  • +
  • How do you know when to change the view?

  • +
+
+
+

Getting it set up

+
    +
  • How hard was it to figure this out?

  • +
  • How hard is it to set it up for each new workshop?

  • +
+
+
+

What can go wrong

+
    +
  • What’s the worst that has happened?

  • +
  • What if you need to walk away for a bit?

  • +
  • Someone broadcasts something unexpectedly

  • +
+
+
+

Alternatives

+
    +
  • Youtube vs Twitch

  • +
  • Zoom stream directly to YouTube/Twitch

  • +
  • Direct streaming platform, e.g. streamyard

  • +
+
+
+

Q&A

+

Q&A from audience

+
+

Keypoints

+
    +
  • The broadcaster’s view shouldn’t be so scary.

  • +
  • There is a lot to manage, but each individual part isn’t that hard.

  • +
+
+
+
+
+

Video editing

+
+

Objectives

+
    +
  • Get to know ways of quick video editing to be able to provide +accessible videos

  • +
  • Learn how video editing can be distributed and done the same day.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 20 min

  • +
+
+

Video recordings could be useful for people watching later, +but also are (perhaps more) useful for immediate review and catching +up after missing a day in a workshop. For this, they need to be +released immediately, within a few hours of the workshop. +CodeRefinery does this, and you can too.

+

Hypothesis: videos must be processed the same evening as they were +recorded, otherwise (it may never happen) or (it’s too late to be +useful). To do that, we have to make processing good enough (not +perfect) and fast and the work distributeable.

+
+

Primary articles

+ +
+
+

How this relates to streaming

+
    +
  • If you stream, then the audience can not appear in the recorded +videos

  • +
  • This allows you to release videos very quickly if you have the +right tools.

  • +
  • When you have a large audience, the videos start helping more +(review a missed day, catch up later, review later)

  • +
  • Thus

    +
      +
    • If you would never want videos, there may never be a benefit to +streaming

    • +
    • If you want videos, it gives motivation to stream.

    • +
    +
  • +
+
+
+

Summary

+
    +
  • Basic principle: privacy is more important than any other factor. +If we can’t guarantee privacy, we can’t release videos at all.

    +
      +
    • Disclaimers such as “if you don’t want to appear in a recording, +leave your video off and don’t say anything”, since a) accidents +happen especially when coming back from breakout rooms. b) it +creates an incentive to not interact or participate in the course.

    • +
    +
  • +
  • Livestreaming is important here: by separating the instruction from +the audience audio/video, there is no privacy risk in the raw +recording. They could be released or shared unprocessed.

  • +
  • Our overall priorities

    +
      +
    1. No learner (or anyone not staff) video, audio, names, etc. are +present in the recordings.

    2. +
    3. Good descriptions.

    4. +
    5. Removing breaks and other dead time.

    6. +
    7. Splitting videos into useful chunks (e.g. per-episode), perhaps +equal with the next one:

    8. +
    9. Good Table of Contents information so learners can jump to the +right spots (this also helps with “good description”.)

    10. +
    +
  • +
  • ffmpeg-editlist +allows us to define an edit in a text file (crowdsourceable on +Github), and then generate videos very quickly.

  • +
+
+
+

How we do it

+

The full explanation is in the form of the exercises below. As a +summary:

+
    +
  • Record raw video (if from a stream, audience can’t possibly be in +it)

  • +
  • Run Whisper to get good-enough subtitles. Distribute to someone for +checking and improving.

  • +
  • Define the editing steps (which segments become which videos and +their descriptions) in a YAML file.

  • +
  • Run ffmpeg-editlist, which takes combines the previous three steps +into final videos.

  • +
+
+
+

Exercises

+
+

Exercise A

+

These exercises will take you through the whole sequence.

+
+

Editing-1: Get your sample video

+

Download a sample video:

+ +
+

Editing-2: Run Whisper to generate raw subtitles and test video.

+

First off, install Whisper and generate the base subtitles, based +on the. Since this is probably too much to expect for a short +lesson, they are provided for you (above), but if you want you can +try using Whisper, or generating the subtitles some other way.

+

You can start generating subtitles now, while you do the next +steps, so that they are ready by the time you are ready to apply +the editlist. ffmpeg-editlist can also slice up the subtitles from +the main video to make subtitles for each segment you cut out.

+

Whisper is left as an exercise to the reader.

+ +
+
+
+

Editing-3: Create the basic editlist.yaml file

+

Install +ffmpeg-editlist and +try to follow its instructions, to create an edit with these features:

+
    +
  • The input definition.

  • +
  • Two output sections: the “Intro to the course”, and “From data +storage to your science” talks (Remember it said the recording +started at 11:35… look at the schedule for hints on when it +might start!). This should have a start/end timestamp from the +original video.

  • +
+

A basic example:

+
- input: day1-raw.mkv
+
+# This is the output from one section.  Your result should have two of these sections.
+- output: part1.mkv
+  title: something
+  description: >-
+    some long
+    description of the
+    segment
+  editlist:
+    - start: 10:00    # start timestamp of the section, in *original* video
+    - end: 20:00      # end timestamp of the section, in the *original* video
+
+
+ +
+
+

Discussion: what makes a video easy to edit?

+
    +
  • Clear speaking and have high audio quality.

  • +
  • For subtitle generation: Separate sentences cleanly, otherwise it +gets in a “stream of words” instead of “punctuated sentences” +mode.

  • +
  • Clearly screen-sharing the place you are at, including section +name.

  • +
  • Clear transitions, “OK, now let’s move on to the next lesson, +LESSON-NAME. Going back to the main page, we see it here.”

  • +
  • Clearly indicate where the transitions are

  • +
  • Hover mouse cursor over the area you are currently talking about.

  • +
  • Scroll screen when you move on to a new topic.

  • +
  • Accurate course webpage and sticking to the schedule

  • +
+

All of these are also good for learners. By editing videos, you +become an advocate for good teaching overall.

+
+
+

Editing-4: Run ffmpeg-editlist

+

Install ffmpeg-editlist: pip install ffmpeg-editlist[srt] (you +may want to use a virtual environment, but these are very minimal +dependencies).

+

The ffmpeg command line tool must be available in your +PATH.

+ +
+
+

Editing-5: Add more features

+
    +
  • Several chapter definitions.(re-run and you should see a +.info.txt file also generated). Video chapter definitions +are timestamps of the original video, that get translated to +timestamps of the output video.

    +
    - output: part1.mkv
    +  editlist:
    +  - start: 10:00
    +  - -: Introduction    #  <-- New, `-` means "at start time"
    +  - 10:45: Part 1      #  <-- New
    +  - 15:00: Part 2      #  <-- New
    +  - end: 20:00
    +
    +
    +

    Look at the .info.txt files that come out now. What is new in it?

    +
  • +
  • Add in “workshop title”, “workshop description”, and see the +.info.txt files that come out now. This is ready for +copy-pasting into a YouTube description (first line is the title, +rest is the description).

    +

    Look at the new .info.txt files. What is new?

    +
  • +
+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+
+
+

Editing-7: Generate the final output file.

+
    +
  • Run ffmpeg-editlist with the --reencode option: this +re-encodes the video and makes sure that there is no black point +at the start.

  • +
  • If you re-run with --check, it won’t output a new video file, +but it will re-output the .info.txt and .srt files. +This is useful when you adjust descriptions or chapters.

  • +
+
+
+

Discussion: how to distribute this?

+

Create a flowchat of all the parts that need to be done, and which +parts can be done in parallel. Don’t forget things that you might +need to do before the workshop starts.

+

How hard was this editing? Was it worth it?

+
+
+
+

Exercise B

+

This is a more limited (and older) version of the above exercise, +using an synthetic example video.

+
+

Use ffmpeg-editlist to edit this sample video

+

Prerequisites: ffmpeg must be installed on your computer +outside of Python. Be able to install ffmpeg-editlist. This is +simple in a Python virtual environment, but if not the only +dependency is PyYAML.

+ + +
+
+
+
+

See also

+ +
+

Keypoints

+
    +
  • Video editing is very useful for learning

  • +
  • Set your time budget and make it good enough in that time

  • +
  • Reviewing videos improves your teaching, too.

  • +
+
+
+
+
+

Open Broadcaster Software (OBS) introduction

+
+

Objectives

+
    +
  • Understand that OBS is a video mixer.

  • +
  • Understand the basic controls and features of OBS.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 15 min

  • +
  • Q&A 5 min

  • +
+
+ +

In this episode, you’ll get more familiar with the OBS portion of the +streaming setup. You’ll see how it’s used, but not yet how to +configure it from scratch. You’ll learn how to be a “director”.

+
+

What is OBS?

+
    +
  • Formally “OBS Studio”

  • +
  • Most commonly known as a livestreaming application.

  • +
  • Open source, free.

  • +
  • Cross-platform, easy to use screencasting and streaming application.

  • +
  • Real-time video mixer.

  • +
+
+
+

OBS user interface

+
    +
  • We’ll click through each view.

  • +
  • What does each view do?

  • +
  • Let’s click through the buttons.

  • +
  • Let’s see the important config options.

  • +
+
+
+

OBS during a course

+
    +
  • What management is needed.

  • +
  • The control panel.

  • +
  • Audio.

  • +
  • Adjusting windows and so on.

  • +
+
+
+

Hardware requirements

+
    +
  • Reasonably powerful broadcast computer

    +
      +
    • CodeRefinerys streaming computer is 8 CPU AMD, 64GB memory

    • +
    • That is way overkill: a powerful laptop can probably do this.

    • +
    +
  • +
  • Large second monitor for laying out the windows you capture

  • +
  • Stable internet connection (wired preferable)

    +
      +
    • CodeRefinery’s broadcast is the slowest purchasable: 100 Mbit down / +25Mbit up

    • +
    +
  • +
+
+
+

Q&A

+

We’ll answer audience questions.

+
+
+

See also

+ +
+

Keypoints

+
    +
  • OBS may seem complicated, but it’s a graphical application and most +pieces make sense once you know how it works.

  • +
+
+
+
+
+

Open Broadcaster Software (OBS) setup

+
+

Objectives

+
    +
  • See how to configure OBS using the pre-made CodeRefinery scene +collections

  • +
  • Modify the collections to suit your needs.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: ?? min

  • +
  • Hands-on: ?? min

  • +
  • Q&A: ?? min

  • +
+
+ +

In this lesson, we’ll see how to configure OBS from scratch for your +purposes. We’ll do this by deleting the instructor’s configuration +and trying to recreate it

+

This section is short, since it has never been done before: we’ll just +give it a short and update the lesson later.

+
+

CodeRefinery OBS configs

+
    +
  • CodeRefinery configs are shared in a repository: +https://github.com/coderefinery/obs-config

  • +
  • These can be imported to pre-configure some things

  • +
  • There are two types of configs:

    +
      +
    • Profiles

      +
        +
      • Servers, resolutions, audio, video, etc.

      • +
      +
    • +
    • Scene collections

      +
        +
      • The graphical layouts.

      • +
      +
    • +
    +
  • +
+
+
+

Installing the OBS config

+
    +
  • Clone the git repository.

  • +
  • Import the profile and scene collections under their respective +menus.

  • +
+
+
+

Initial setup

+
    +
  • Click through each menu and change anything that is needed

  • +
  • Set the streaming server

  • +
+
+

The instructor will go through the setup.

+
    +
  • Reset configuration: mv .config/obs-studio/ .config/obs-studio-old/

  • +
  • Import profiles/TeachingStreamingv3/

  • +
  • Import scenes/TeachingStreamingZoomv3.json

  • +
+
+
+
+

Set up the remote control

+
    +
  • Create a Python environment and install it: pip install https://github.com/coderefinery/obs-cr/archive/refs/heads/master.zip

  • +
  • Run it: python obs_cr/control.py localhost:4445 TOKEN --broadcaster

  • +
  • There are more options but let’s not cover them yet… and leave +this for a hands-on session.

  • +
+
+
+

Setup before each course

+
    +
  • Re-confirm audio

  • +
  • Re-confirm each scene

  • +
  • Test everything

  • +
  • rkdarst has a rather long +checklist, +but each individual step is short.

  • +
+
+
+

Q&A

+

We’ll answer audience questions.

+
+

Keypoints

+
    +
  • Most of our configuration has been OBS may seem complicated, but it’s a graphical application and most +pieces make sense once you know how it works.

  • +
+
+
+
+
+

What’s next?

+
+

Objectives

+
    +
  • Know next steps if you want to do streaming

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 5 min

  • +
  • Q&A 5 min

  • +
+
+

What comes next?

+
    +
  • We talked a lot about theory, and gave demonstrations.

  • +
  • Hands-on is very different. We recommend working with someone to +put it in practice.

  • +
  • +
+
    +
  • Work with someone who can show you the way

  • +
  • Use it for smaller courses with a backup plan

  • +
+
+

See also

+
+

Keypoints

+
    +
  • These lessons about streaming have been the theoretical part of +streaming training.

  • +
+
+
+
+
+
+
+

Collaborative notes archives from workshops

+
+

August/September 2024

+
+

Day1: Session 1 (13.08.24) - About lesson design, deployment and iterative improvement

+
+
:calendar: Schedule
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 10.00

Lesson design and development

10.15 - 11.00

8.15 - 9.00

10.00 - 10.15

Break

11.00 - 11.15

9.00 - 9.15

10.15 - 11.00

Lessons with version control

11.15 - 12.00

9.15 - 10.00

11.00 - 11.15

Break

12.00 - 12.15

10.00 - 10.15

11.15 - 12.00

How we collect feedback and measure impact

12.15 - 13.00

10.15 - 11.00

+
+
+
:icecream: Icebreaker
+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :Decaffed … and going strong …

  • +
  • :coffee: 🤔

  • +
  • :100: (ironically!) :coffee: intake happening

  • +
  • :smile:

  • +
  • :tired_face:

  • +
  • :coffee: :party:

  • +
  • :coffee: :happy:

  • +
  • 😪

  • +
  • just got zoom installed / before my coffee

  • +
  • :smil-

  • +
  • :sweat_smile: (+)

  • +
  • :yawning_face:

  • +
  • :is it morning already?

  • +
  • :smile:

  • +
  • :yawning_face:

  • +
  • :nerded_face:

  • +
  • 🥵

  • +
  • :smile:

  • +
  • :sleeping:

  • +
  • :sleepy: :coffee: :smiley_cat:

  • +
  • 🥳

  • +
  • :coffee:

  • +
  • :coffee:

  • +
+
+
+
Introduction in breakoutrooms.
+
    +
  • Name / Affiliation / Location

  • +
+
+
+
About teaching
+

What is the hardest thing about teaching for you?

+
    +
  • Knowing how “it’s going”, whether learners are happy or not (especially when teaching online) :+1:

  • +
  • The preparation the night before. It is always much more that I would hope, no matter how prepared I want it to be :+1: :+1:

  • +
  • Managing groups with vastly different academic backgrounds

  • +
  • Teaching wide spectrum of skill level at the same time. :+1: :+1: :+1: :+1:

  • +
  • Time management! (Knowing how much can fit in a sessions) :+1: :+1:

  • +
  • General preparation time, how to fit it into the regular work schedule, and estimate how much time is needed for prep.

  • +
  • How to reduce too much text into just the right amount

  • +
  • Preparation of the session material and estimating the right amount of time for each section

  • +
  • Getting learners to take the first step: sign up for and attend a workshop, when they don’t think programming is a skill they can learn

  • +
  • Getting learners to take the second step: translating what they’ve learned in a workshop into something they can apply

  • +
  • preparation and time management

  • +
  • Engaging with the students which was much easier for me when I used to coach

  • +
  • Finding the right depth for an unknown audience for “my topic”

  • +
  • education background of participants and their learning objectives

  • +
+

What is the best thing about teaching for you?

+
    +
  • Seeing when learner gets interested/curious about something and takes inspiration from the course. :+1:

  • +
  • Seeing it works and someone can do something new.

  • +
  • Motivated students grasping new stuff

  • +
  • Students picking up and running with the matertial and skills I give them and using it for their own work. :+1:

  • +
  • The “ah-ha!” moment when a student gets it! :+1::100: :+1:

  • +
  • Learning from students who know about some topic more than you do. :+1:

  • +
  • Being able to help people reach their goals, by showing them something new.

  • +
  • Teaching is optimism acted out in the hope of making a difference both ways I suppose.

  • +
  • The feeling of accomplishment when you see learning grow and implement the learnings :book:

  • +
  • mutual learning and impact on learners :+1:

  • +
  • Results and feedbacks / Mutual interests and interesting discussions

  • +
  • mutual learning and I can also learn lots of things and new ideas from participants

  • +
+
+
+
+
:question: Questions
+
+
General / Practicalities
+
    +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms? I’m not in a place where I can talk, so if we’re going to talk a lot I’ll need to move offices

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    +
  • +
  • +
+
+
+
Episode 1: Lesson design and development
+

Materials: https://coderefinery.github.io/train-the-trainer/lesson-development/ +Discussion:

+
    +
  • When you start preparing a new lesson or training material, where do you start?

    +
      +
    • I look at existing materials on the same topic, but chose/refine topics based on the perceived needs/interests of the presumed audience

    • +
    • Outline of structure and Material collection for a new lesson :+1:

    • +
    • What material I have already? (what other material is already out there?)

    • +
    • Start by looking for related resources (documents, videos, courses, etc) to have a base data and better understanding of what have been done around the topic

    • +
    • Know your audience

    • +
    • Review existing material

    • +
    • Think about learning objectives (to keep focus on essential things)

    • +
    • Think of three things simple enough that they will be remembered the next day. Design around that.

    • +
    • I write down the thoughts that I have and then go back and structure it.

    • +
    +
  • +
  • What tricks help you with “writer’s block” or the empty page problem?

    +
      +
    • Write anything down that comes to mind, sometimes draw something, looking out the window :)

    • +
    • Do a mind map - what concepts do I want to get across?

    • +
    • Starting small, for example a list of headings and then building around it. :+1:

    • +
    • What does one know about the target audience and why should they be spending longer than 1 minute listening to what they will eventually get to hear?

    • +
    • Get some inspiration from another source.

    • +
    • Start with the three things above

    • +
    • Start with the plan and the overview design

    • +
    • Some kind of outline / main message(s)

    • +
    • Start with three things. Three supporting points for each of these.

    • +
    +
  • +
  • Maybe you haven’t designed training material yet. But how do you start when creating a new presentation?

    +
      +
    • Think about the learning objectives and try to break them down into steps

    • +
    • Title, Objectives, target audience and Plan

    • +
    • Some kind of outline / main message(s). Get as many images as I can, instead of words

    • +
    • Draft an outline and use chatgpt to fill in details

    • +
    • Example of how the teaching content is applied in a real-world context

    • +
    +
  • +
  • If your design process has changed over time, please describe what you used to do and what you do now instead.

    +
      +
    • I look more at existing materials and try to get more information about the audience. Unfortunately getting information about the audience before the event is hard

    • +
    • I used to start from the begginning and get from there but that often meant a very polished start and a rushed end. Now I try an overview first, then fil out sparsed details at every section

    • +
    • Updating the data and tweak the presentation

    • +
    • If I am teaching a small group (or one to one) talk to them before hand - find out what they know already, what they want to learn.

    • +
    +
  • +
  • What do you know now about preparing lessons/training/presentations that you wish you knew earlier?

    +
      +
    • less is more. It’s better to have 2-3 main messages rather than trying to show everything in one go :+1: :+1: :+1: :+1:

    • +
    • how much practice time the learners need to master what’s taught

    • +
    • Don’t worry about something going wrong. It often makes the lesson (and thus the material) more presistent in memory. :+1:

    • +
    • Try and remove everything except what you want the person to learn

      +
        +
      • That’s a very tough part for me in the sense that I never know how much of an underlying “black box” is still ok….

      • +
      +
    • +
    • Designing intermediate materials is hard, and requires putting some “gatekeeping” making sure that learners are directed to appropriate courses

    • +
    • When I see a cool graphic, concept, slide, etc., download it and save it in my ‘new-materials’ folder to use later on!

    • +
    • I have come to the conclusion that perhaps a more “agile” approach to developing materials (try to do design/teaching iterations quickly) might be the best way to go, but there are risks with this approach too

    • +
    +
  • +
+

Questions

+
    +
  • From zoom chat: Can you expand on what a learner persona is?

    +
      +
    • A defined example person described in terms of the materials you are preparing, making up a story about the background and interest of t

    • +
    • Answer from chat: A learner persona is a blackbox which has a very simple algorithm inside: GIGO.

    • +
    • Answer from chat: I think it’s the same as ICP (Ideal customer persona) where you describe the learner as a customer

    • +
    • Answer from chat: I’m a big fan of “How Learning Works” by Ambrose et al https://bookshop.org/p/books/how-learning-works-eight-research-based-principles-for-smart-teaching-michele-dipietro/18640868?ean=9781119861690

    • +
    • See also book: Teaching tech together

    • +
    +
  • +
+
+

CodeRefinery lessons: https://coderefinery.org/lessons/

+
+
    +
  • From chat: Do you have an example of an instructor guide?

    + +
  • +
  • From zoom chat: Do you have a “measure” of how better are the new lesson compared to the old ones? Does it make sense to talk about measurements here?

    +
      +
    • So far we only have daily feedback that we collect at the end of the day and we can compare that to earlier daily feedbacks. More about that in the last episode of today. But measuring this is indeed not easy and it also takes time to capture the effect during longer-term surveys. Some of the changes were more leap-of-faith than based on data.

    • +
    • I guess that sometimes one can use “compelling arguments” instead of data to justify a decision

    • +
    +
  • +
  • Software Carpentry does teach using the command line, and gives a session on the command line before. What do you think about this approach? Are you stating that a 3-hour lesson about CLI is not sufficient to make people comfortable enough to use that for version control?

    +
      +
    • Yes, good question. For CR we consider it a more advanced step: we do think people should learn command line, but it’s for a different course. We accept some people might not know it or want to know it so adapt to that.

    • +
    • In general, we’ve found the “you need X, but have to learn A, B, and C first” approach should be avoided if possible: people are busy, try to reach people where they are.

    • +
    +
  • +
+
+

Exercise in breakoutrooms

+
+
    +
  • Room 1

    +
      +
    • Research data management

    • +
    • Objectives

      +
        +
      • Research life cycle

      • +
      • FAIR principles (Findable, Accessible, Interoperable, Reusable)

      • +
      +
    • +
    • Exercise

      +
        +
      • develop a data management plan (DMP) that outlines how their research data will be handled throughout its lifecycle.

      • +
      +
    • +
    +
  • +
  • Room 2: What is the difference between eating breakfast and sitting through a lecture? (Tip: Start by listing the similarities …)

  • +
  • Room2 : Making papers in LaTeX +- What is LaTex and how is it different from editors like Word +- Basic Structures +- How to find and use a template +- Including figure & table +- How to use references and labels +- Exercise: to create a new LaTeX document & edit it +- Excercise: common error messages: can you find the error in this code? +- Exce

  • +
  • Room 3

    +
      +
    • GPU Programming (1 hour intro)

    • +
    • Learning objectives:

      +
        +
      • What is GPU programming.

      • +
      • When is it usable, beneficial to use GPU programming?

      • +
      • What are technologies to do GPU programming?

      • +
      • [What are and how to manage typical issues]

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • Git / Figures / Project management / data cleaning

    • +
    • Chose data cleaning

    • +
    • Three learning objectives:

      +
        +
      1. What do we mean by “clean”? How to identify it?

      2. +
      3. Identify some common problems in a dataset

      4. +
      5. Identifying and handling missing values/fields

      6. +
      +
    • +
    • Exercise

      +
        +
      1. Discuss problems, find the most common ones

        +
          +
        • In small groups

        • +
        • What problems have you run into with datasets you’ve worked with?

        • +
        • What problems can you imagine, or have you heard about from colleagues/news/social media?

        • +
        • Report back, instructor collects all problems into a list

        • +
        +
      2. +
      3. Have a dataset to clean; a clean and a messy example

        +
          +
        • (identifying) Using a visualisation or overviewing tool?

        • +
        +
      4. +
      +
    • +
    +
  • +
  • Room 5

    +
      +
    • Jupyter Notebooks

    • +
    • Learning Objectives

      +
        +
      • Can setup an enviroment you can reuse / can share with others / a project.

      • +
      • The order you run the commands in needs to match the order of the code in the Notebook - otherwise you end up in a pickle.

      • +
      • Why use a Jupyter Notebook? What are the advantages? Easy to use environment.

      • +
      +
    • +
    • Exercise

      +
        +
      • Print variable assignments from different cells - show that the order you run the code is important.

      • +
      • hand out a domain specific notebook that does some calculations and visualization to run and modify, to show that you can share easily

      • +
      • show !pip install to add dependencies/features

      • +
      +
    • +
    +
  • +
  • Room 6

    +
      +
    • Using GitHub without the command line

    • +
    • Learning Outcomes:

      +
        +
      • Be able to discuss changes before merging changes into the main repository.

      • +
      • Publish a personal repository page ( I think its called intro repository)

      • +
      • Share their script/notebook/code/small data on GitHub

      • +
      • Homepage using GitHub pages or the README that becomes the “index page” of the GitHub user account page

      • +
      +
    • +
    • Learner personas:

      +
        +
      • Check the Personas of the learners

        +
          +
        • Somebody who has seen/heard of GitHub but hasn’t used it yet

        • +
        • Someone using it for their own work but struggling with collaboration

        • +
        +
      • +
      +
    • +
    • Exercises:

      +
        +
      • Upload/share an example dataset or script

      • +
      • Review another collaborators pull request.

      • +
      • Take part in the discussion on a pull request.

      • +
      +
    • +
    +
  • +
  • Room 7 +Linux shell basics: why do we want to teach them? +(this took most of the time for the discussion)

    +
      +
    • Learning objectives:

      +
        +
      1. Filesystem: Directory (CLI) - Folder (GUI) analogy

      2. +
      3. Basic commands (which commands are basic? make a survey of shell histories and get the most common ones)

      4. +
      5. Basic constructs (e.g., for loops, pipes, while loops… which ones are basic? See above)

      6. +
      +
    • +
    +
  • +
+
+

Note from chat: Zoom timer: https://support.zoom.com/hc/en/article?id=zm_kb&sysparm_article=KB0068677

+
+
+
+
Episode 2: Lessons with version control
+

Materials: https://coderefinery.github.io/train-the-trainer/lessons-with-git/

+

Poll options: I want to hear about:

+
    +
  • A: Why use version control for teaching materials

  • +
  • B: Different template options

  • +
  • C: How CodeRefinery does it; CodeRefinerys lesson template

  • +
+

Poll vote (multi-select): add a o to your answer +- A: ooo +- B: oooooo +- C: oooooooo :ghost:

+

Question to audience: if someone wants to make a tiny fix to your material, how hard is it?

+
    +
  • If my material is only in pdf format which is not online, then it is hard.

  • +
  • I hope it is easy - my material is in GitHub. Nobody has ever done that though!

  • +
  • Slides: hard to find, easy to edit; Git repos somewhat easy, unless they have to be built locally or with an action; HackMD easiest to edit.

    +
      +
    • if you use something like google slides they are not that difficult to find

    • +
    • known permanent address. Google docs et al fail on that/same for many pads.

    • +
    +
  • +
  • For this material today - very easy! e.g. https://github.com/coderefinery/train-the-trainer/pull/128

  • +
  • Template with an edit button in the HTML pointing to the source-code in the repo.

  • +
+

Questions/Discussion topics

+
+

Upcoming CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/ +Please share with your networks, and let us know if you would like to co-teach a lesson (to support@coderefinery.org or in our Zulip chat)

+
+
    +
  • Changes to the material are sometimes not just tiny fixes. For example, one wants to present a slightly different selection of topics, but maybe some topics are “coupled” (perhaps naturally or perhaps just because of how they are presented), or change the general “theme” (e.g., life sciences vs theoretical physics) while keeping the actual topics the same. How could a lesson be developed to avoid having to do a huge rewrite?

    +
      +
    • You can try to modularize your material and keep non topic specific parts non themed. E.g. where you explain the functionality, don’t make reference to the example (not simple), so the example can be changed depending on the audience.

    • +
    +
  • +
  • What are the pros/cons of renaming a course / changing a repo name in GitHub?

    +
      +
    • It should be relatively unproblematic since GitHub will forward to the new name.

      +
        +
      • How long does Github keep the “old” name linked? Is there a max time it’s blocked, or changed as soon as a new one appears with the name?

        +
          +
        • in my experience it forwards “forever” until I create a new repo with the old name which will break the forward

        • +
        +
      • +
      +
    • +
    +
  • +
  • what should be in the readme for the git repo? (canonical address? contact points? license!)

    +
      +
    • https://coderefinery.github.io/mini-workshop/2/documentation/#often-a-readme-is-enough-checklist

      +
        +
      • I miss the url to the (main) repo in the readme

        +
          +
        • Do you mean the link to the rendered (lesson) page?

        • +
        +
      • +
      +
    • +
    • Link to rendered page: We often have this in the “about” section of the readme (see up right: https://github.com/coderefinery/train-the-trainer)

    • +
    • this gets lost in a fork, doesn’t it? so 20 folks forking and or reuploading the repo somewhere means the url gets lost?

      +
        +
      • True, but they might want to have their own version rendered?

        +
          +
        • yes, I have had issues finding and contributing to the “master” repo so all benefit. Else it gets cluttered. Both is valid

          +
            +
          • Good point though, the link to rendered page should probably also be included in the readme for completeness; ah and the link to the repository too, yes

            +
              +
            • so realistically we need a content folder and some more next to the readme as a best practice. sounds good!

            • +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • Is myst (markdown renderer) enabled by default in sphinx now?

    +
      +
    • to my knowledge no. we add the “myst_parser” extension to conf.py.

    • +
    +
  • +
+
+

Cicero: https://cicero.readthedocs.io/ +Sphinx documentation: https://www.sphinx-doc.org/en/master/ +Carpentries workbench for creating Carpentries lessons: https://carpentries.github.io/workbench/ +This is the testing lesson Richard showed: https://coderefinery.github.io/testing/ +And the corresponding repository: https://github.com/coderefinery/testing +You can lean back and watch, exercise coming in a bit :) +Richard will now edit our train the trainer material repository: https://github.com/coderefinery/train-the-trainer +The Sphinx extension for CodeRefinery lessons: https://github.com/coderefinery/sphinx-lesson +Empty lesson template to build your own lesson: https://github.com/coderefinery/sphinx-lesson-template

+
+

More questions

+
    +
  • Does the coderefinery.org page built on sphinx?

    +
      +
    • It’s built also from markdown but it uses https://www.getzola.org/ (which is more optimized to render websites, but we could do teaching also with Zola or create the project page using Sphinx)

    • +
    +
  • +
  • Is there a way to build and preview CR lessons without the command line?

    +
      +
    • The GitHub workflow we use creates HTML from all branches. This means that one can push a branch to GitHub, preview it there, and then open a pull request. One thing that would be nice but we don’t have yet is if a bot automatically posts the link to the preview to a pull request.

    • +
    +
  • +
  • For VCS-2, for the Carpentries Linux shell example, Lesson, Github repo, to me it seemed as though the Sandpaper setup they have makes a very nice interface, complicates the relationship between source and output. E.g on the soucre page https://github.com/swcarpentry/shell-novice/blob/main/index.md I could only see to ‘Prerequisits’ and not ‘Download files’ on the page https://swcarpentry.github.io/shell-novice/. Perhaps I have missed something?

    +
      +
    • I am sorry I don’t know the new Sandpaper setup well enough to answer this question.

    • +
    +
  • +
  • Do we have the instructions to build the lessons available somewhere to try out later?

    +
      +
    • https://github.com/coderefinery/sphinx-lesson

    • +
    +
  • +
+
+

Exercise VCS-1 (and VCS-2 (if time)) (https://coderefinery.github.io/train-the-trainer/lessons-with-git/#exercises) in breakoutrooms until xx:05

+

then short summary in main room and then break.

+

Use the notes below. Collect a list of lesson formats and discuss what you like about each of them.

+
+
    +
  • PDF slides by a presentation program

  • +
  • pdf slides with beamer in latex under source control.

  • +
  • Markdown slides via Github

  • +
  • CodeRefinery template

  • +
  • Carpentries template

  • +
  • Google Slides

  • +
  • git-book

  • +
  • Jupyter Book - allows creating a structured reference website using RST/Markdown, including Jupyter Notebooks to show result of running code

  • +
  • mdbook - create simple/minimal website using Markdown

  • +
  • Binder - allows learners to run their own live version of a github repository with Jupyter Notebooks, with only a web browser

  • +
  • Jupyter notebooks and jupyterhub platform

  • +
  • Jupyter + Nbviewer and custom css (read only) + Binder link (hands on)

  • +
  • RMarkdown

  • +
  • Quarto Slides

  • +
  • Reveal.js - write slides in HTML (also supports markdown)

    +
      +
    • Example: https://bl-presentations.erambler.co.uk/2024-02-21-idcc24/

    • +
    +
  • +
  • Remark.js - write slides in markdown

    +
      +
    • Example: https://bl-presentations.erambler.co.uk/2024-02-19-idcc-pids-workshop/

    • +
    +
  • +
+

Room discussions:

+
    +
  • Room 1

    +
      +
    • (https://smc-aau-cph.github.io/SPIS/README.html)

    • +
    • CodeRefinery template

    • +
    • Shared notes & blogs

    • +
    +
  • +
  • Room 2

    +
      +
    • demo the exercise

    • +
    +
  • +
  • Room 3

    +
      +
    • Mix of JupyterLab, Terminal within that, and traditional slides

    • +
    • Jupyter + RISE (benefit: slides that are editable and executable live)

    • +
    • Challenges

      +
        +
      • present code in an interactive way

      • +
      • handle lots of images/ figures without too much additional overhead when setting up the material

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • Material and tools depend on instructors

    • +
    • Some slide building tools

      +
        +
      • https://revealjs.com/

      • +
      • https://remarkjs.com/

      • +
      • https://github.com/rust-lang/mdBook

      • +
      +
    • +
    • Using flat git repos without fancy styling to make it easier to edit but still version controlled

    • +
    +
  • +
  • Room 5

    +
      +
    • Using R as a GIS: https://github.com/nickbearman/intro-r-spatial-analysis

      +
        +
      • Workbook: RMarkdown, Slides: Quarto

      • +
      • No continuous intergration

      • +
      +
    • +
    • Having a jupyter nbinder link to test the notebook

    • +
    • repo lives on codeberg in this example

    • +
    +
  • +
  • Room 7

    +
      +
    • Ex 1:

      +
        +
      • Sphinx, similar to CR

      • +
      • Sometimes pdfs generated with beamer package (or from pptx and odt), but blows up repository size if in version control

      • +
      +
    • +
    • Ex 2:

      +
        +
      • Content

        +
          +
        • CR: Content commonly found int the content folder

        • +
        • SC: Mostly under episodes

        • +
        +
      • +
      +
    • +
    • Question that came up:

      +
        +
      • is CR/Sphinx approach mostly for technical topics? What about language.

      • +
      • I guess by our nature it’s focused there. But probably could be used for others (I guess it it’s much easier to use git in a technical audience.)

      • +
      +
    • +
    +
  • +
+
+
+
Episode 3: How we collect feedback and measure impact
+

Materials: https://coderefinery.github.io/train-the-trainer/feedback-and-impact/

+

Questions to audience

+
    +
  • What tricks/techniques have you tried in your teaching or seen in someone else’s teaching that you think have been particularly effective in collecting feedback from learners?

    +
      +
    • preparing a survey and emailing it to participants as soon as the event ends (usually get <50% of answers but it’s a representative enough sample)

    • +
    • do engage with the audience, give them the time to get the courage to speak up

    • +
    • Be the audience yourself

      +
        +
      • yes! some problems/issues I don’t notice as instructor, only as listener

      • +
      +
    • +
    • Have time (e.g. 5 min) in the session to fill out the feedback form

    • +
    • If the course/workshop has several days/sections do a couple questions every change, then a full one afterwards

    • +
    • “Traffic light” feedback (e.g. for pacing or progress on exercises): give each learner two different coloured post-it notes for in-person, or use emoji for online, to indicate a current status

    • +
    +
  • +
  • Can you give tips or share your experiences about how to convert feedback into changes or actionable items?

    +
      +
    • ask questions about things you know you don’t know

    • +
    • “Don’t let the noise of others’ opinions drown out your own inner voice.” — Steve Jobs

    • +
    +
  • +
  • When people ask questions / get stuck with a specific step. Is there a typo I can change there and then in the workbook?

    +
      +
    • Being able to fix small things on the fly helps sometimes, otherwise open issues if working on github

    • +
    • If multiple people have the same question, then this is an indication that I should look at this in more detail

    • +
    +
  • +
  • How do you measure the impact of your teaching? Any tips or experiences about what you have tried or seen other courses do?

    +
      +
    • “How likely are you to recommend this workshop to others? (0/5)”

    • +
    • Check the ‘Garbage Out’ bin, what you find there will be what went across. The rest will be history…

    • +
    +
  • +
  • Anybody knows of good resources on survey design? Please link them here.

    +
      +
    • “Our job is to figure out what they’re going to want before they do… Our task is to read things that are not yet on the page.” - Steve Jobs

    • +
    +
  • +
+

Questions/Discussion points

+
    +
  • Feedback is necessary to design good lessons. Improvement can only be done iteratively. So the faster the iteration (design/teach), the better. But on the other hand, I cannot constantly bomb our community with training event emails. So I would like to try proposing a course many times a year, but I don’t want to spam everybody many times a year.

    +
      +
    • :+1:

    • +
    • With CR we also have a calendar that can be imported to different calendar applications, where we add all workshops: https://github.com/coderefinery/calendar/

    • +
    +
  • +
  • Does an even split of too fast / too slow mean speed is about right?!

    +
      +
    • I take it to mean “it’s roughly where it should be”. Would be better to accomdate the sides better though… (we do try to design for a broad audience: some easy stuff, some advanced stuff, so people can make their own path)

    • +
    • It could also indicate that the prerequisites/scope are not well defined :+1:

      +
        +
      • Based on long term surveys we also know though that even though the workshop might have been to fast, people appreciate having “heard things before and know where to find them later”

      • +
      +
    • +
    • perhaps the even split between too fast/too slow is ok only if the majority of votes goes for “just right” :+1:

    • +
    +
  • +
  • One of the most important disciplines in journalism is to challenge your working premises. (Bill Keller) This applies equally to learning as well.

    +
      +
    • Participants can be encouraged to write some posts on LinkedIn. If it is helpful some blurbs can be created for pre and post-workshop to generate more traction for Code Refinery and future participation.

    • +
    • Ask participants if they use Dev.to, hashnode etc to blog their work or use twitter etc to have a memory of their work.

    • +
    +
  • +
  • Do you have any suggestions for prerequisites? I try to make them clear, but occasionally people attend who clearly do not meet them. :+1:

    +
      +
    • I guess it depends how much it matters for the workshop itself. If you have group exercises etc, it probably matters? , lecture style maybe not so much?; important is that the participants themselves know that prerequisites exist and if they meet them

    • +
    • Sometimese people that do not meet the prerequisites join to get to “know what they don’t know”, find out where to find information on topics they might get interested in future etc

    • +
    • Other suggestions? Viewpoints? :)

    • +
    • Thank you - things for me to think about there :-)

    • +
    • With CR’s latest ideas, we try to make the prerequisites clear, but there is no capicity limit: it’s OK if people drop by and are less than prepared: it’s livestream, anyone can come. We try to have something for these people, too: learn what you are missing, why you might want to study more in the future.

    • +
    • Any thoughts on applying this to a more practical focused course, with a total capacity limit (i.e. not like CodeRefinery).

    • +
    +
  • +
  • Everytime you do a course on CodeRefinery, think of it as trying to bake a new cake with an old recipe with no idea about the individual taste preferences of the one you bake the cake for. Then, you will not experience too many surprises. Fine-tuning the recipe for one cohort still remains the ‘old recipe’ as far as the next ‘new cohort’ will be concerned. C’est la vie.

    +
      +
    • nice analogy!

    • +
    +
  • +
  • Question from chat: For examples 2 & 4, would you also consider using something like a Likert scale? E.g. Rate how well you agree with the statement “My code is more reusable as a result of attending a CodeRefinery workshop” (from 1 Strongly disagree to 5 Strongly agree)

    +
      +
    • Thanks! I am new to Likert scale and will read up on it. In my experience numbered answers can be useful for reporting. But I also like questions where we ask for what actually to change.

    • +
    +
  • +
  • Comment from chat: Richard, your point crowns the point of having CodeRefinery, With Radovan’s and Samantha’s acquiescence assured, I would like to suggest you wear a crown going forward, especially for the CodeRefinery session. Do we have a deal ?

    +
      +
    • I don’t quite understand this

    • +
    • I think it’s a tongue-in-cheek-comment (joke) but I am not sure…..

    • +
    +
  • +
  • What is the ideal way to allow people to interact while course is going on in the main online session, i.e. without a breakout room? Taking a pause or discussion in the background?

    +
      +
    • I’ve had some success with WhatsApp groups for a course - particually ones that run over 4 (or 2) sessions.

    • +
    • A quick survey/quiz

    • +
    • Question to the audience that we take time to answer but it helps to show the answers

    • +
    +
  • +
+
+
+
+
+
+

Wrapup

+
    +
  • Thank you for active participation :)

    +
      +
    • We’ll continue answering questions after the workshop and make the cleaned up (no names etc) available from the materials

    • +
    +
  • +
  • Next session Tuesday August 20, 9 CEST: Tools and techniques adopted in CodeRefinery workshops

    +
      +
    • we will talk about on-boarding, install help, roles, screensharing, sound, collaborative notes

    • +
    +
  • +
  • All workshop materials will stay available (after the full workshop also on Zenodo :tools:)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • If you want to co-teach with us in the upcoming (or next) CodeRefinery workshop (https://coderefinery.github.io/2024-09-10-workshop/); or just want to learn more about this opportunity: Send your name and e-mail address to support@coderefinery.org; we will contact you!

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • Lesson design approach

  • +
  • I liked the backwards lesson design, gives a name to a practice I’ve already been doing :+1: :+1:

  • +
  • Lessons from code refinery on lesson design. Learning about Sphinx.

  • +
  • Collaborative notes and anonymized archive of notes.

  • +
  • it’s nice to have a community to discuss these kinds of problems

  • +
  • Hearing the variety of tools people use for slides (PDF, Quarto, Beamer etc.)

  • +
  • Good intro of the tools, the jargon and the pedagogical philosophy of teaching tech.

  • +
  • The absolute openess in having everything publicly available - materials ofc but also questions, discussions, feedback, …

  • +
  • Thinking about all content being available publicly and as a git repo

  • +
  • Thanks for explaining the HedgeDoc interface, with view and edit options

    +
      +
    • Is there anyway to come back to this document later (e.g. tomorrow) and see what has changed since now? So I can see if any other questions have been asked/answered?

      +
        +
      • There is a “revision” point under “Menu” up right, which shows you different versions of this document

      • +
      +
    • +
    +
  • +
  • Modesty: the gentle art of enhancing your charm by pretending not to be aware of it. - Oliver Herford

  • +
  • +
+

What one thing would you improve about this session?

+
    +
  • Perhaps some more interactivity but can be hard to plan and time

    +
      +
    • We’ll see what we can do.

    • +
    +
  • +
  • Maybe mix the breakout groups up for each breakout session (although there are advantages to consistency too) :+1:

    +
      +
    • yes, pros and cons! For me, having consistency worked well this time.

    • +
    • Likely we will have different participants next week, and a bit of mixing will happen naturally.

    • +
    +
  • +
  • The pace of the presentations could be a little tighter (the pace is good for a discussion though)

  • +
  • Richard’s voice was only 80% audible

    +
      +
    • Sorry to hear that. It seemed fine on my end. Will check better for next session.

    • +
    +
  • +
  • Hands on simulation and collaborative notes

  • +
  • I found it difficult to follow the presentation and the collaborative notes at the same time

    +
      +
    • We will highlight the collaborative notes more in the next session. Our strategy usually is to say to focus on the “teaching part” and use the notes only when needed. Since you can go back and also check the notes later.

      +
        +
      • My problem is that I want to follow both since I don’t want to miss out on anything. As such, I have both windows (zoom and the notes) open side-by-side. Since there is near-constant real-time typing in the editor, and as such visible movement on screen, I get constantly distracted. This makes following the event quite exhausting.

      • +
      +
    • +
    +
  • +
  • Heads up to participants on using the break out rooms on voice interaction and screen sharing.

    +
      +
    • Do you mean that we should have mentioned it more clearly in the pre workshop email?

    • +
    +
  • +
  • I found it hard to follow with so many things going on at once…

    +
      +
    • A collaborative document being changed at the same time as…

    • +
    • Someone speaking and explaining content at the same time as…

    • +
    • Chat in a different application at the same time as…

    • +
    • Content changing in a termin application.

      +
        +
      • Thank you for the feedback. We will remove the Zoom chat out for the next session and explain the use of the collaborative notes more.

      • +
      +
    • +
    +
  • +
  • Make more use of defining and then making sure the learning objectives are met

    +
      +
    • True we did not talk about them much, will pick that up better for next session.

    • +
    +
  • +
  • UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. - Dennis Ritchie. You need to do a lot to prove that to be wrong, simply put.

  • +
  • Allocate some time for learners to type in the answers so that we don’t have to listen and type at the same time.

  • +
+

Any other comments?

+
    +
  • It’s great to hear other people’s experience

    +
      +
    • Good to hear :)

    • +
    +
  • +
  • Looking to meet you onsite if there are any events and get more emails from you :)

    +
      +
    • We will keep you informed :)

    • +
    +
  • +
  • Thanks for putting this together, I got a lot of inspiration for my own courses

    +
      +
    • Good to hear :)

    • +
    +
  • +
  • I didn’t know where to ask questions. It would work best for me to do it in zoom chat as that’s the application that I’m watching in..

    +
      +
    • Sorry for that, just to figure out why: Did you join a bit late?

      +
        +
      • No. Perhaps I just missed that or it was too quick for me or something?

        +
          +
        • Ok, sorry. Will try to make this more clear in next session.

        • +
        +
      • +
      • Perhaps also because there were so many things going on and jumping around. For me, the zoom chat is the constant (and obvious) place to ask questions while watching a shared screen, trying to find the right place in a moving collaborative document is difficult. It tears my attention into too many pieces. :+1:

      • +
      +
    • +
    +
  • +
  • Had a lot of content that assumed extant knowledge that I didn’t have. This wasn’t in the pre-requisites.

    +
      +
    • Do you have examples?

      +
        +
      • Yes! The code refinery templates and even just the way of doing that. I was expecting more on “when designing a lesson you should think about these steps” rather than this is how we do it and this is our tool for doing it. I guess I should have read the pre-workshop content better?

      • +
      • Ok, thank you for your feedback. You are right that we actually had some content that for sure would have been easier to follow for people with background knowledge about a certain topic.

      • +
      • “If you are in CodeRefinery TTT, you probably know what version control is and why it is important.” - extant knowledge, why not just add a sentence or two?

        +
          +
        • Please can you update in preparation for the next workshops so that I can decide whether or not they will be right for me?

          +
            +
          • Yes, we will think more thoroughly about this and send the info in the next email going out Wed/Thu

            +
              +
            • Thank you!

            • +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • Lots of the content was relevant to code refinery but not the wider topic (e.g. it was how to design a code refinery lesson and not how to design a lesson as stated in the session title)

    +
      +
    • We thought of the content of showing one way of doing things, ie “what we have learned”, if you have suggestions on how we could make that more clear on the event page, please let us know :)

      +
        +
      • “in a code refinery lesson” in the lesson/workshop description?

      • +
      +
    • +
    +
  • +
  • When you have pre-written “thank you for your active participation” it feels fake!

    +
      +
    • He, that is true, did not think about that. Thank you for the feedback. I would not have added it if Radovan and Richard would not have provided good feedback from circling the rooms.

    • +
    +
  • +
  • I found it vague and disorganised and difficult to follow. It felt like the instructors were presenting the content for the first time and didn’t know what to do next.

    +
      +
    • Thank you for your feedback. This is not the first time we have this training, but it is the first time in this constellation/way. The way of teaching may also sometimes make it seem new to instructors.

    • +
    +
  • +
  • I really liked the active exchange with other participants, but I also would have enjoyed a bit more technical content in the presentations. In a sense it felt less like a ‘training’ and more like a get-together :+1:.

    +
      +
    • Thank you for your feedback. We thought the name “workshop” would combine the training and exchange nature of this event. But maybe it didn’t do so enough? Do you have suggestions on how to clarify it on the event page?

      +
        +
      • Well, the ‘train the trainer’ title created the anticipation of being trained ;) don’t get me wrong, I liked the exchange, but I felt that the training aspect fell a little short. imho the workshop would benefit from a little more (instructional) content that is presented in a more structured way by the instructors (as opposed to ‘crowd-sourced knowledge’ that is collated in a loose collection of questions, notes and links)

      • +
      • Other than that, you could add another section on the main page, sth like ‘Workshop structure: we aim for a mix of modular presentations and work in small groups. The latter will be done in breakout rooms - be prepared to switch on your camera and have a fruitful exchange with fellow participants!’

        +
          +
        • Thank you for the suggestions, will add something like this :tools:

          +
            +
          • +

            Added : https://github.com/coderefinery/train-the-trainer/commit/03308595436e636b3bb37ed9d1f0dee39eeccd0f

            +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • My understanding (so far) of what (unlike the competition) CodeRefinery DOES NOT seek to exemplify - +https://images.ctfassets.net/rxqefefl3t5b/2k45BFtw4sBMlBfjr1OZ90/5c6ecd3628a43b0cdc79815f665e224a/Screenshot_2023-05-02_at_09.35.23.png?fl=progressive&q=80

  • +
  • My understanding of what (unlike the competition) today’s session of CodeRefinery DID exemplify - Definition of ‘Workshop’ from the Oxford dictionary of the English language “a period of discussion and practical work on a particular subject, in which a group of people share their knowledge and experience”

  • +
  • In my experience, even for the most seasoned Programmer coding, by its very nature, is nothing trivial, this being a simple straightforward fact just like there is no such thing as an egg which is a cube. I mean there is a reason why not just about everybody is a poet either. But, other minds have pointed this out without having to first explain why the universe is what it is in a way that could be understood without effort … https://i.pinimg.com/originals/7b/7e/c4/7b7ec4b91d2cf9d8e1b064678d205467.jpg

  • +
  • The inclusive environment feels very welcoming. Keep up the good work!

  • +
+

Thank you all for your feedback! Highly appreciated!

+
+
+
+

Day 2 : Session 2 (20.08.24)- Tools and techniques adopted in CodeRefinery workshops

+
+
:calendar: Schedule
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 9.25

About CodeRefinery workshops

10.15 - 10.25

8.15 - 8.25

9.25 - 9.55

Collaborative notes and interaction

10.25 - 10.55

8.25 - 8.55

9.55 - 10.10

Break

10.55 - 11.10

8.55 - 9.10

10.10 - 10.45

Workshop overview, roles, onboarding

11.10 - 11.45

9.10 - 9.45

10.45 - 11.05

Sound

11.45 - 12.05

9.45 - 10.05

11.05 - 11.20

Break

12.05 - 12.20

10.05 - 10.20

11.20 - 11.50

How to prepare a quality screen-share

12.20 - 12.50

10.20 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+
:icecream: Icebreaker
+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :-)

  • +
  • https://media.istockphoto.com/id/148421550/vector/bored-emoticon.jpg?s=612x612&w=0&k=20&c=uo5KBTqdJZbBQb_Xldhzuovx5t08fHfGR7dw7TCk90I=

  • +
  • :saluting_face:

  • +
  • :sleepy:

  • +
  • :coffee:

  • +
  • :umbrella:

  • +
  • :cocktail: :coffee:

  • +
  • :seedling:

  • +
  • :tired_face:

  • +
  • :sun_with_face:

  • +
  • 🥴 (:woozy_face: not converted?)

  • +
  • :coffee:

  • +
  • :sunflower: :book:

  • +
  • :satisfied:

  • +
  • :coffee:

  • +
  • :coffee:

  • +
  • 🥱:tired_face:

  • +
  • :bread: - I am baking bread today so I have been kneading dough while listening!

  • +
+
+
+
Introduction in breakoutrooms
+

Name / Affiliation / Location

+
+
+
Teaching
+
    +
  • Do you teach and organize teaching alone or with others? What would you prefer and why?

    +
      +
    • Coming together is a beginning; keeping together is progress; working together is success. – Edward Everett Hale

    • +
    • These days always with others. Alone is easier to prepare but almost always is harder during it.

    • +
    • Teaching with very diverse partners, it can be challenging to find a common language with people very different than you.

    • +
    • I teach alone, in the future there will be more collaboration with multiple team members. Both approaches have their pros and cons.

    • +
    • Both has its own distinct advantages

    • +
    • Most of my teaching is on my own, as a freelancer its more expensive to work with colleagues than to deliever a course on my own.

    • +
    • Teaching together, learns from each other, feedbacks to improve

    • +
    • Not formally taught yet, only given presentations actually .

    • +
    • collective teaching would benefit the teachers with collaborative curriculumn and experiences sharing.

    • +
    +
  • +
  • If applicable, have you seen any challenges when teaching together and how to overcome them?

    +
      +
    • It actually requires preparation,

    • +
    • Is it about teaching or about inspiring ? Discover the answer and get inspired …

    • +
    • It’s like being in a band: you might be great at improvising and your band-partners might be great at improvising too, but a bit of rehearsing makes even the impro gig much better

    • +
    • Need to plan before session, difficult if people don’t ‘plan’ in the same way, e.g. with the same time frame.

    • +
    • Heterogeneity in learners make it impossible to get the same result from everyone.

      +
        +
      • In fact, the same applies to teachers :D

      • +
      +
    • +
    • Teaching together requires to have similar opinions on how to teach. I share vews only with ~40% of my colleagues I think.

    • +
    +
  • +
  • No Teaching experience but it is good to give the outline of the lessons beforehand and learning goals.

  • +
+
+
+
+
+
:question: Questions
+
+
General / Practicalities
+
    +
  • What is this document for?

    +
      +
    • Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts)

    • +
    +
  • +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms?

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    • BR 1 : The Zoom chat does not work for the breakout room so we should take note of that. No webcam/mic = expect silence.

      +
        +
      • Thanks for notifying! This was not intended. Turned the chat back on.

      • +
      +
    • +
    +
  • +
+
+
+
+
+
Episode 1: CodeRefinery
+

Materials: https://coderefinery.github.io/train-the-trainer/coderefinery-intro/

+
    +
  • (questions continue here)

  • +
  • Is there the plan to build capacity / be paid to deliever courses?

    +
      +
    • We’ve discussed it but right now we don’t have many people who could accept money to do this (and maybe shouldn’t, because of their jobs). But, we would encourage others to use our materials as “independents” to deliver paid courses

    • +
    • One idea we have had is that paid courses could be delivered through the DRA (link below), who we know. Basically, DRA could find instructors and handle the money transfers (If someone wanted a paid course, we could help find someone to do it through DRA or independently)

    • +
    • :smile:

    • +
    +
  • +
  • Have you come across DRA, https://digital-research.academy/, Heidi Seibold, Joyce Kao who are doing similar work? I can connect you if you like.

    +
      +
    • Yes we have been discussing about possible future collaborations and are already sending possible clients their way (we, as a project cannot take money) :+1:

      +
        +
      • Excellent! :-D :smile:

      • +
      +
    • +
    +
  • +
  • .

  • +
+
+
+
Episode 2: Collaborative Notes
+

Materials: https://coderefinery.github.io/train-the-trainer/collaborative-notes/

+
    +
  • So anyone can type anonymously?

    +
      +
    • Yes, as long as you do not log in, you are Guest XXX

    • +
    • And at least in our hedgedoc case you cannot log in so you will always be anonymous. You can do [name=xxx], to add your name to a comment

    • +
    +
  • +
  • Test of +1

    +
      +
    • +1 :+1: :+1:

    • +
    • :-1: a test

    • +
    +
  • +
  • You are hosting your own version of HedgeDoc, and Hackmd.io is a similar (free) option. What are the limitations of the free hackmd.io? Should each center install their own HedgeDoc instance?

    +
      +
    • It seems the free version of HackMD has gotten worse lately. It works still well enough with a few people editing at the same time.

    • +
    +
  • +
  • Have there every been problems with the anonymity and CoC?

    +
      +
    • We haven’t had any issues so far.

    • +
    • With a different anonymous tool in a bachelor course, we had issues with anonymous participants (participants were posting slurs and unsafe links). The course organiser decided to stop allowing anonymous tools.

    • +
    +
  • +
  • Why not google documents?

    +
      +
    • Google documents are actually setting a hard limit for simultaneous writing, no more than 100 concucurrent editors. I am unsure if microsoft onedrive word documents would allow more users writing at the same time.

    • +
    +
  • +
  • What’s the most people you have every had on HackMD / Hedgedoc?

    +
      +
    • I believe about 200 active participants?

    • +
    +
  • +
  • What are your thoughts on using the build-in Zoom Q&A?

    +
      +
    • We haven’t tried this, in part because the way we do streaming now (you’ll see in session 4), participants aren’t in Zoom so don’t have access to that. The doc-format works pretty well though, when we keep it in this limited “write at end” format.

    • +
    +
  • +
  • How do you see what has changed? e.g. if leave the session at the end, can I come back tomorrow and see X has been added? e.g. a diff for this maybe?

    +
      +
    • In the menu up right there is revision, it does show the document and changes at different time step :+1: Thanks!

    • +
    • We recommend people only write at the bottom (and since we answer things live), so as a first level approximation you find where you were and read below that. Think of it more like chat than a full document. (Yes, we do revise questions at the end)

    • +
    +
  • +
  • How about flinga boards or similar tools?

    +
      +
    • My take is that the simplicity of a simple text document wins over free-form in-person-workshop-like tools.

    • +
    • There’s miro, can be a bit confusing though

    • +
    +
  • +
  • How does this work with small groups, e.g. 10-15 people?

    +
      +
    • Good question: it can be hard if people aren’t rigorous about it, people start only using chat/voice. So there seems to be some lower bound in size but we haven’t tested this much

    • +
    • And if the instructors never screenshare it to show what goes on it, then seems to be less used.

    • +
    • And if there aren’t other people to read/answer it during the session (perhaps less likely in a small course), it seems to be less used.

    • +
    +
  • +
+
+

Breakoutrooms until xx:55

+

Exercise/discussion: https://coderefinery.github.io/train-the-trainer/collaborative-notes/#exercise

+
+
    +
  • Breakout room 1:

    +
      +
    • Use of etherpad for collaborative discussion.

    • +
    • Use of slido for polling and quizzing.

    • +
    • Presemo as a slido alternative (https://www.aalto.fi/en/services/presemo-a-fully-web-based-classroom-participation-system)

    • +
    • Use of text based approach for questions rather than live can be helpful if there is a language barrier issue.

    • +
    +
      +
    • A good teaching session which had many questions coming spontaneously to the teacher is a non-entity of sorts. If the overall flow of feedback / questions increases it could indicate that the session will not prove to be a helpful experience. A signal that generates noise is, well, noise, if calling a spade a spade signals anything. Note that the ‘overall’ bit and the ‘to the teacher’ aspect are important. Both the best and the worst teaching session have two things in common: a teacher, and the fact that NO Materials of any kind are used, ie speech is the only channel of communication via a common language. The only difference is that it is not the same teacher, at least not in the same session at the same time.

    • +
    +

    Another less mentioned, but perhaps more relevant indicator of a great session is the simple fact that at the end of the session EVERYONE feels empowered, NOT tired. This is not an easy to quantify thing, but screams out the quality of the experience loud. More often then not, such sessions differ little from each other, apart from in terms of the theme / topic and the participant mix. It ends up being the ‘keep your cake and eat it too,’ of sorts, not quite the far less amusing post-bombardment devastation scenario in the wake of a take it or leave it go at anything.

    +
      +
    • profanity in collaborative documents where people can add content anonymously could be a problem (happens very rarely, fortunately and somewhat surprisingly)

    • +
    +
  • +
  • Breakout Room 2:

    +
      +
    • Good experiences with Zoom polls

    • +
    • Handling questions in hybrid setups: all participants (on-site and online) ask questions in written form

    • +
    • Collaborative notes can be challenging when conducting a course alone (without teaching assistants) :+1:

    • +
    • Providing a method to ask questions anonymously can make asking easier for shy participants

    • +
    • Questions can give valuable feedback on how the course is going

    • +
    • Online collaborative whiteboarding platforms such as Miro

      +
        +
      • Large monitors are useful for this not to have to drag a “periscope” around

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • good experience with whatsapp chat for questions. since most learners have the app already and one thing less to install and set up

      +
        +
      • reply to question is a way to handle multiple questions at the same time but it works well for smaller groups

      • +
      +
    • +
    • experience with collaborative docs in in-person workshops: voice questions might “win” over the document

    • +
    • “seeding” questions may help to not have an empty document

    • +
    • it can help somebody to start and create a structure which helps others to see and follow

    • +
    • we discussed the Carpentries sticky notes system (red sticky note: signal tech issues and use for feedback, green sticky note: signal that exercise worked and for positive feedback)

      +
        +
      • Nice summary of sticky notes system: https://teachtogether.tech/en/#s:classroom-sticky-notes :+1:

      • +
      +
    • +
    • What is the success rate of in-person workshops after COVID? Discussion: Teachers prefer in person and learners prefer remote or recorded to spool back and relearn.

    • +
    +
  • +
  • Room 5

    +
      +
    • Good experience with Collaborative tools as HackMD and HedgeDoc while teaching with no bad feedback

      +
        +
      • When used with smaller groups works best as one-way, like sharing links with students and so on

      • +
      • Needs to be done as a team, quite difficult if teaching alone

      • +
      • Most useful when online/hybrid

      • +
      +
    • +
    • Anonymisity is important for transparent feedback and no biasis in classrooms

    • +
    • Not very collaborative but useful to share history or jupyter notebooks live https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush

    • +
    • Used Flinga before that seems like Figma and also onsite teaching using sticky notes

      +
        +
      • There’s miro.com but can be a bit confusing, more for brainstorming than for teaching

      • +
      +
    • +
    • Using quizzes apps like Kahoot is beneficial while teaching to have more engaging students

    • +
    • +
    +
  • +
  • Room 6

    +
      +
    • teaching teenagers (in presence) but using shared pad becomes quickly very chaotic, so only usable for short moments when answering very precise questions

      +
        +
      • Yeah, I can imagine. For CR we try to keep it in this very limited format (all questions bullet points, only add to the end) and I think that helps.

      • +
      +
    • +
    • using shared notepad for small workshop (5-10 people) to explore common thematic (mainly technical) to keep a shared notes and condense aftwerward (and publish on wiki to archive)

    • +
    • Difference between teaching in person and online. Some people prefer in-person and sometimes you have no option but to organise it online.

    • +
    • There are sometimes cultural differences and learners feel shy to ask / question the knowledge of the Teacher, so shared notes are a good way to safely ask questions.

    • +
    +
  • +
+

Questions continue:

+
    +
  • Have we demonstrated how we do polls in HedgeDoc? Add your vote by adding an o

    +
      +
    • yes: oooo (in session 1)

    • +
    • no:

    • +
    • :smile:

    • +
    • not sure: o

    • +
    +
  • +
+
+
+
Episode 3: One workshop, many perspectives
+

Materials: https://coderefinery.github.io/train-the-trainer/overview/ +Next CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/

+
+

Exercise until xx:39

+

https://coderefinery.github.io/train-the-trainer/overview/#discussion

+
+
    +
  • Room 1

    +
      +
    • Send pre-workshop email with pre-requisite instructions on what should be set-up beforehand.

      +
        +
      • But, also mention that if help is needed for set-up, we will be ready before the session officially starts.

      • +
      +
    • +
    • Discussion on whether we push to work in a pre-ready environment (e.g. Binder, Colab) or in their own environment.

    • +
    • Lots of help needed both before and after.

    • +
    • Installations: as much as we can provide ready made environments for the learners, maybe installations will be something that the learners will face sooner or later. Maybe one should teach more about installations?

    • +
    • My only cherished role in a teaching-learning session is the that of one who is living the moment as if there were no tomorrow. What cuts all ways really is that “By failing to prepare, you are preparing to fail.” ― Benjamin Franklin. A helpful motto: “When one teaches, two learn.” — Robert Heinlein. The best experience cannot be given, it can only be allowed to flow its way, so get out of its way.

    • +
    +
  • +
  • Room 2

    +
      +
    • Frequently, a single person fills all the roles for a single or multi-day workshop

    • +
    • Collaboration with different centers/ universities can be challenging

    • +
    • Preparing participants: it’s essential for the instructor to go through the demos and be sure that they will work (no unpleasant surprises live). This can be extended to advance-prep for participants.

    • +
    • Best experience is to hear (live or in feedback notes) some positive things directed at you :)

    • +
    • Fully prepared environments (eg self-hosted JupyterHub) can make preparation for participants easy

    • +
    +
  • +
  • Room 3

    +
      +
    • Some students have problems with setuping the environment. Maybe having a step by step instructions could help. But some students don’t want to “start” the course before hand.

    • +
    • Preparing the environemnt before hand ensures everyone is onboard from day 1. The same thing happend in CSC training sessions and another session Peng attended.

    • +
    • Had experience in attending as teacher and student in previous workshops

    • +
    +
  • +
  • Room 4

    +
      +
    • knowing the background of the audience is helpful

      +
        +
      • Try and ask in advance of the background of the audience. Do a poll at the start of the workshop. In person one can do it interactive.

      • +
      +
    • +
    • among co-instructors: discuss topics and flow

    • +
    • if more people are involved, it can help changing roles from time to time to see different perspectives

    • +
    • preparation is key

    • +
    • Circulate instructions beforehand

      +
        +
      • Do a poll before session: Have you installed (QGIS) successfully?

      • +
      • Push hard to do this in the welcome email

      • +
      +
    • +
    • communicate clearly to the participants

    • +
    • +
    +
  • +
  • Room 5

    +
      +
    • We’ve all taken most roles

    • +
    • How to prepare in advance?

      +
        +
      • Meet and discuss once or twice

      • +
      • Make a pre-survey to check for interest and background

      • +
      • Going through the materials

      • +
      • Checking the toolkit (zoom)

      • +
      • Agree on the reponsibilities and back-up plans (bit of scenarios planning)

      • +
      +
    • +
    • How to prepare trainings in advance?

      +
        +
      • Collect resources and prepare the workshop plan

      • +
      • Having the material readily available online ans sharing it

      • +
      • Making a pre-survey

      • +
      +
    • +
    • What was the best workshop experience for you as learner, helper or instructor? What made it great?

      +
        +
      • learner

        +
          +
        • Engaging and practical workshop with more exercices and follow-up theoretical part explanations

        • +
        +
      • +
      • helper

        +
          +
        • When the instructor is well prepared and as helper ther’s only typos to fix and interesting questions to answer

        • +
        • Assist the instructor, coordinate the collaborative notes, and make sure that the time is respected

        • +
        +
      • +
      • instructor

        +
          +
        • I have a colleague whom I’ve ran the same workshop a few times already, goes quite smoothly now and we’ve made a few changes. Hard to reach that point with new colleagues but getting there

        • +
        • Students/participants were engaging with the material and many good feedback collected even some of them asked for the next workshop

        • +
        +
      • +
      +
    • +
    +
  • +
  • Room 6

    +
      +
    • What has made a great experience for you as a learner/helper/instructor?

    • +
    • Common ground between learners & teachers

      +
    • +
    • Motivation

      +
        +
      • Teaching is much more enjoyable when the learners want to be there

      • +
      • I spend a lot of time at the start of a workshop making sure learners feel that the content is possible for them to understand and master

      • +
      +
    • +
    +
  • +
+

Poll: I have joined a CodeRefinery workshop before: (add an o for your answer)

+
    +
  • yes (within last 2 years): ooooooo

  • +
  • yes (longer time ago): oo

  • +
  • no: oooooooo

  • +
  • +
+

(questions would continue below:)

+
    +
  • What is the motivation / advantages of streaming workshop versus using zoom?

    +
      +
    • We’ll cover this more in week 4, but roughly: zoom became unmanageable and essentially quiet once things got big. Streaming allowed “one to many” communication with no limit, and collab notes allowed better interaction anyway. By separating the rooms, it was more pleasant to teach. Videos could be released immediately since there was no risk of privacy of participants. There could still be in-person/online small groups who have “watching parties.”

    • +
    +
  • +
  • What are the blue red and green font colors here, does it symbolify anything or just a convention HedgeDoc uses?

    +
      +
    • Visual separation of formatting, mostly. (It helps to quickly realize you’ve missed/ mistyped a control Markdown symbol etc.)

    • +
    • Yeah, it’s bascically “code highlighting” for markdown. No special meaning but quite convenient for us.

    • +
    +
  • +
  • Is this next workshop only for team leads or also open for helpers and coordinators?

    +
      +
    • You mean the next session of this workshop or the upcoming “CodeRefinery workshop”(this one: https://coderefinery.github.io/2024-09-10-workshop/)?

      +
        +
      • The upcoming workshop coordinators are alredy working, but can be joined if you are interested

      • +
      • As helper roles we currently only have “collaborative notes helper”, which is all about helping to answer questions in the collaborative notes

      • +
      • We do have some co-teaching slots open :)

      • +
      • If interested: join the discussion in our chat: https://coderefinery.zulipchat.com/#narrow/stream/316508-coderefinery-tools-workshop/topic/Fall.202024.20CodeRefinery.20workshop

      • +
      +
    • +
    +
  • +
  • Can a person have multiple roles in a workshop as a helper and a teacher?

    +
      +
    • Yes, many teachers also contribute to the rest of the workshop by answering questions in collaborative notes. :+1:

    • +
    • Some teachers also host a local classroom in week one and do their teaching in week two of the workshop

    • +
    • Roles that do not go well together are broadcaster/director/host and instructor (goes well until there is a problem; co-teaching solves that partly)

    • +
    +
  • +
+
+
+
Episode 4: Sound
+

https://coderefinery.github.io/train-the-trainer/sound/

+
    +
  • To me, Richard is a bit quieter than the other two :+1: :+1: :+1:

    +
      +
    • to elaborate: I think that the audio coming from him is missing some mids

    • +
    • Do you have any links about this kind of evaluation and adjustment?

    • +
    +
  • +
  • Do you suggest / recommend a specific headset(s) with mounted microphone?

    +
      +
    • in our experience headsets with a microphone will almost always be better than a separate microphone sitting on the desk or in the monitor

    • +
    • +
    +
  • +
  • Speakers have different tones of voice and speaking styles, is there a recommendation or experience from CR workshops for how this is adjusted and catered to environemnts for listeners?

    +
      +
    • Yeah, people’s voices are different and we haven’t gone as far as voice training or improving.

    • +
    +
  • +
  • How to change the volume for speakers? Tried Zoom settings and system settings and didn’t help.

    +
      +
    • From linux I can use different pulsemixers pavucontrol, pulsemixer to set the gain to above 100%. I’m not sure the equivalent on other OSs but

    • +
    +
  • +
+
+
+

Exercise until xx:10 +https://coderefinery.github.io/train-the-trainer/sound/#exercises

+
+
    +
  • room 1

    +
      +
    • Practically, no typical headset is designed or can capture the technical purity of human voice within its natural environment. But one needs to understand the polar pattern of the (specific) microphone or how much of the signal will be picked up by the microphone from different directions, a sine qua non when it comes to mitigating unwanted sound sources to bleed into the signal.

    • +
    +
  • +
+

For best results, keep the right direction & distance to your (directional) mic. Usually, that’s between 15-30 cm to get get a natural sound. A microphone records everything it can, also silence, so check the headphone output BEFORE adjusting the gain, in some specific cases aim for a dry sound, ie the influence of the room or how audible the room is on the recording ! Finally, adjust the mix between dry and room sound, or change the frequency response in tandem using a compressor to reduce the dynamic range of a signal for a more consistent listening experience = the quietest parts of your signal will appear louder by reducing the loudest parts.

+

It is all about one thing and one thing only - love your voice, let people fall in love with the acoustic quality of your charm. So remember: GIGO, it matters!

+
    +
  • Room 3

    +
      +
    • Had different headsets and we could see the difference (bluetooth low quality)

    • +
    • How to change the volume?

      +
        +
      • It’s surprisingly hard to get more control than the basic slider you see in the apps! You need to look.

      • +
      +
    • +
    +
  • +
  • room 4

    +
      +
    • headset is probably better listening experience but they can be uncomfortable to wear during long meeting days :+1:

      +
        +
      • Yeah. Luckily only instructors

      • +
      • Therefore breaks are non-negotiable

      • +
      +
    • +
    • loud keyboard can be an issue

    • +
    • if one has a silent room that does not echo, it can be ok to teach without headset

    • +
    • on Linux I am using pulsemixer to adjust levels and pavucontrol to change outputs/sources

    • +
    • mic modes on mac

    • +
    • check default microphone for zoom.

    • +
    +
  • +
  • room 5

    +
      +
    • Most tricks help tuning yourself but hard to do it as a group. Perhaps doing a short recording.

      +
        +
      • Yeah. Some independent recording/playing aronud, but also asking for advice. I would do small group/one-on-one things.

      • +
      +
    • +
    • Background noises cancellation tools or wise choice of quiet environments

    • +
    • Audio check with colleagues or through the app with the audience saying numbers for example

    • +
    • Zoom or Teams have sound checks but work different in the app than the browser. They also work different across Operating systems

    • +
    • Some sound issues might be related to network speed or stability, also to RAM available. Worthwhile to try and control those as well

    • +
    • Make it welcoming for the audience to give you feedback on the audio and other settings, give reminders

    • +
    +
  • +
+
+
+
Episode 5: How to prepare a quality screen-share
+

Materials: https://coderefinery.github.io/train-the-trainer/screenshare/

+
    +
  • If your Zoom does not support “share portion of screen”, sharing a tab and resizing it to portrait for yourself is a possible workaround (this at least works when joining the call from Chromium browser)

    +
      +
    • Another workaround is to use an editor/IDE that displays multiple panels in one window and can show a web page, code files and terminal session +10

    • +
    +
  • +
  • Is ‘share a portion of your screen’ where you draw a box in Zoom to share a section?

    +
      +
    • yes :+1:

    • +
    +
  • +
  • When using zsh, one can run something like this in a terminal

    +
    tail -n $NLASTCOMMANDS -f ~/.zsh_history | sed 's/^.............../LAST COMMAND:/g'
    +
    +
    +

    (I place this in a window under the main terminal, I use i3)

    +
  • +
  • I am a bit confused on what platform you are putting this code?

    +
      +
    • Radovan is using Linux with (I think) the “i3 window manager”. It can be quite involved and there is lots of personal customization here.

    • +
    +
  • +
  • When teaching with a custom prompt, is it worth starting with the default (that your learners will see) and explicitly mentioning “I change these things to make it clearer when teaching”

    +
      +
    • One should always comment on what may be different. Thing is “default” may look different for many people :+1:

    • +
    • “I am not going to teach you how to customise your prompt, but here’s an online tutorial, be prepared to lose several days of your life…” :laughing:

    • +
    +
  • +
  • Now I can’t see the last line in the terminal

    +
      +
    • Yep, that’s a problem. It can be good to keep a buffer on the bottom of the screen.

    • +
    • If you move your mouse outside the Zoom window, the controls should go away. But still a good note.

      +
        +
      • My mouse was on another screen.

      • +
      • Ok, thanks.

      • +
      +
    • +
    • I think one can also make the zoom bars not auto-hide (then it won’t display under), but that is annoying also since it wastes space.

    • +
    +
  • +
  • Does anybody still use shellshare? Does it work?

    +
      +
    • We in CR haven’t used it much but we have seen it.

    • +
    +
  • +
  • Does the stacking of the screens work on windows?

    +
      +
    • Don’t know unfortunately

    • +
    +
  • +
+
+

Exercises (done together) +https://coderefinery.github.io/train-the-trainer/screenshare/#exercises

+

Write your cool tips and ideas below. +Stay after xx:00, to

+
+
    +
  • To be safe, I have created on my computer an account that I use only for teaching, so I do not need to do any manual set up

  • +
  • share history or jupyter notebooks live (5-10 secs refresh rate) into a git repo. Share the link with the learners so they can catch up https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush

  • +
+
+
+
+
+

Wrapup

+
    +
  • Next session Tuesday August 27 9 CEST: About teaching & cool things we all would like to share

  • +
  • All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • Cool gems session: If you want to share something, please edit your registration and fill it in there (link to modify in registration confirmation); or e-mail to support@coderefinery.org

  • +
  • If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14:00 (Europe/Stockholm time)

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • Sound and screen share optimization as well as relevant tools and good practices for online instruction. “While you may be unable to control your users’ mindset, you can anticipate it, and make sure that your user experience caters to it.” - Jonathan Cherki

  • +
  • Nice opportunity to (re)think about my online teaching setup :+1: :+1: :+1:

  • +
  • Other ways to display command history :+1:

  • +
  • Did not know that bluetooth gear had so much latency! :+1:

  • +
  • A good reminder about headsets with microphones

  • +
  • Nice and friendly teaching. Thank you!

  • +
  • Screen share with command history and terminal customisation

  • +
  • Really useful tips on sound and screen sharing :+1:

  • +
  • Nice experience share

  • +
  • very useful and practical tips!

  • +
  • Easy to follow along and filled with useful tips on sound, video etc.

  • +
  • +
+

What one thing would you improve about this session?

+
    +
  • Just digging to find something: I have read some of the things you have talked about here already in some blog posts, so perhaps these sessions are not as shokingly full of new content as I imagined (but actually sharing experiences is something I can’t do by reading a blog post)

    +
      +
    • Perhaps: could you link some blog posts or other sources for what you have discussed so far? If it makes sense. Not sure.

    • +
    +
  • +
  • Talking about interface optimization approaches, which applies to sound as much as to visuals or any other aspect either for that matter, it might offer a perspective to bear in mind the concept of introducing asymptotic complexity increment. The latter would mean the goal is measuring how fast the effort of engaging, on one or more of the three parallel levels of interaction, must change to reach higher levels of partial certainty on the correctness of the implementation of the method in question, in this case the pedagogical paradigm. For the former, lower is better I guess, or in this case, in the intended sense, slower is faster. Let us consider an abstract example: People liked using the search engine Google (a Google session to put it in a fancy way) in the early days because it was as simple as it could get, a literally featureless entry point with no bells and whistles. That was the level of its visible complexity, or rather Google set a bar as low as it one could have, and then any higher point of VISIBLE complexity that was to be introduced, such a move would only be on the path of an asymptotic curve curving towards the set bar, never reaching it, as far as the entry point is concerned. We still see the same level of complexity when we fire up google and we never feel distracted to start with, except for the rather forgivable nuisance of the GDPR conformity pop-up notice which appears only AFTER the first move has been made, and thankfully it works plain and simple from there on (unless one starts feeling lucky, pun intended). Now, think about Youtube … the user experience complexity is a totally different matter, the same company today (unfortunately) yet one now has a steadily worsening engagement experience. Good learning sessions tend to be more of the Google search engine experience and a far cry from the current Youtube trend I would opine. Or, to sum it up and keep it sweet and simple, it helps to identify the limits of human-human and human-technology interaction, within the framework of any applicable technology-technology interaction and joy is the result of respecting those limits. Wishful thinking ?

  • +
  • Bring the cat back!

    +
      +
    • I wish it came, but it’s been resting all morning! I don’t bother it or stage apperances…

    • +
    +
  • +
  • Maybe having a digest/ summary of previous iterations of this session might be interesting. I feel a lot of experiences have been exchanged and a lot of techniques/ tools have been mentioned. Spending some time in compiling this into a selected list and adding it as content to the course itself might be worthwhile.

    +
      +
    • Good idea! We will write a blog post about this workshop and will include a summary of all discussions there :)

    • +
    +
  • +
  • Possibly have some command line examples from Windows rather than (just) *nix? I will look at the screenshots after the session. :+1: :+1:

    +
      +
    • Also, a thought if you do do breakout sessions with this work, do one for Unix, one for Windows, one for Mac as an option.

    • +
    +
  • +
  • I could not follow the part Radovan showed codes (Radovan is using Linux with (I think) the “i3 window manager”.)

  • +
  • ..

  • +
+

Any other comments?

+
    +
  • Looking forward to the topics of following sessions.

  • +
  • Looking forward to the next sessions!

  • +
  • Thank you!

  • +
  • Relax, nothing else matters, live a life and have fun ! If you obey all the rules you may end up missing all the fun. ‘The best way to predict your future is to create it.’ - Abraham Lincoln :+1:

  • +
+
+
+

Day 3 : sessiion 3 (27.08.24) - “About teaching and cool things we all would like to share”

+
+
:calendar: Schedule
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 9.45

Computational thinking

10.15 - 10.45

8.15 - 8.45

9.45 - 10.00

Break

10.25 - 11.00

8.25 - 9.00

10.00 - 10.30

Teaching philosophies

11.00 - 11.30

9.00 - 9.30

10.30 - 11.00

Co-teaching

11.30 - 12.00

9.30 - 10.00

11.00 - 11.15

Break

12.00 - 12.15

10.00 - 10.15

11.15 - 11.50

Sharing teaching gems (voluntary)

12.15 - 12.50

10.15 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+
:icecream: Icebreaker
+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • +
  • :sleeping:

  • +
  • :coffee:+2

  • +
  • :robot:

  • +
  • Still little sleeppy :)

  • +
  • 🥴 (:woozy_face: still not converted 🤷‍♂️)

  • +
  • Our planet could be a cube. It has six sides to it. It must be a cube. A cube it is, this Blue Planet … just wondering …

  • +
  • 🦾

  • +
  • :sweat_smile:

  • +
  • computer says no :-) some network trouble

  • +
  • running late, and participating from a :train2:

  • +
+
+
+
Introduction in breakoutrooms
+

Name / Affiliation / Location

+
+
+
Best classroom experiences
+

As a learner or teacher; what was the best workshop/lesson/seminar you have attended? What made the experience great?

+
    +
  • Room 1

    +
      +
    • First summer HPC streamed workshop (as a teacher). Somehow the first felt the best

    • +
    • CSC HPC summer workshop

    • +
    • story telling teaching approach

    • +
    +
  • +
  • Room 2

    +
      +
    • NVIDIA DLI Course on Deep Learning

      +
        +
      • very enthusiastic instructor

      • +
      • intuitive and very accessible way of showing technical details and fostering deeper understanding

      • +
      • a lot of hands-on material and smaller coding exercises

      • +
      +
    • +
    • Anything as long as its interactive and somehow enjoyable from both teacher and learner sides

    • +
    +
  • +
  • Room 4:

    +
      +
    • EPCC MPI Distributed training workshop.

      +
        +
      • Lots of hand on coding / experience gained.

      • +
      • Very interactive instructor who also discussed ideas for more personalised cases of distributed computing.

      • +
      +
    • +
    • Coderefinery RSE course

      +
        +
      • relevance of topic to my current work.

      • +
      • Dynamic / friendly / positive teaching style.

      • +
      • Modular Code Development; very instructive

      • +
      +
    • +
    • Some CSC courses / LinkedIn learning courses

      +
        +
      • up to date materials and topics.

      • +
      • Good way to merge theory with practicalities without making learner feel bored (Example: Jonathan Reichental)

      • +
      • Challenging information to learn more and research about the topic

      • +
      • Trainers are the experts in the field

      • +
      +
    • +
    +
  • +
+
+

Episode on teaching gems

+

If you want to share or demo something about tools and techniques you have found helpful in your teaching, please add your name/initials and rough topic below for smooth transition.

+
+

Note: It does not have to be your tool or your idea, this episode is meant to share experiences and discover new things. You also do not need any slides or materials, a story will do fine :) +Length of the stories will be depending on interest, but be prepared to fit it into 3 min (shortest possible).

+
+ +
+
+
+
+
+
+

:question: Questions

+
+
General / Practicalities
+
    +
  • What is this document for?

    +
      +
    • Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts)

    • +
    +
  • +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms?

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    +
  • +
+
+
+
+
Episode 1 : Computational thinking
+

Materials: https://coderefinery.github.io/train-the-trainer/computational-thinking/ (Link to slides in the middle of material)

+
+
Questions to audience
+

How might breaking down a complex problem into smaller parts change your approach to problem-solving in your current projects?

+
    +
  • Avoids cognitive overload

  • +
  • I used to give an example about this in workshops of cutting long tree into pieces from top to avoid that it falls and destroy a house bloc.

  • +
  • Easier to start on something small

  • +
  • Each individual part is familiar and can take existing solutions.

  • +
  • Only focus on the new things

  • +
  • One can lose oversight of where is supposed to be getting to due to problems with summation of biases introduced during the solving of the parts.

  • +
  • .

  • +
+

Can you think of a research project where identifying patterns in your data led to new insights or breakthroughs?

+
    +
  • Multi-targeted drug design where you need to identify both chemical and biological pathways/patterns

  • +
  • Distilling complex physics problems into simpler 1D statistics is very often done.

  • +
  • I used to do bioinformatics, pretty much everything in biology is about patterns in strings of charachters (DNA, proteins). Finding those patterns and using them is the way to go

  • +
  • Pattern recognition DOES NOT lead to new insight, it is new insight which allows for the recognition of a ‘pattern’, the latter being an allocation of possible bias.

  • +
  • +
  • ..

  • +
+

What challenges do you face when trying to simplify complex concepts in your field, and how do you decide which details to focus on?

+
    +
  • Absence of a terminology / jargon to describe a new idea. :+1:

  • +
  • Similar to above, when teaching often students know what they want to achive, but don’t have the termonology to express it, so working through what they want is helpful, after teaching them some termonology.

  • +
  • Whatever is most useful to the learner first?

  • +
  • I work with researchers in different fields. I don’t always fully understand their domain knowledge but I can take the basiscs or generalities and get code that works for them

  • +
  • A very practical problem is trying to resist going for a coffee in the midst of taking a shot at a complex concept, in the hope that the true details are to be found in the coffee.

  • +
  • not all information is easy to find or a lot of conflicting information or even sometimes imformation explosion

  • +
+

How do you determine the priority of tasks when designing algorithms for your academic projects, and what criteria do you use to ensure that the most critical tasks are addressed first?

+
    +
  • Working chronologically when going through a problem - start at the beginning.

  • +
  • What gives the more insight with the least effort can be a nice start

  • +
  • Talk to colleagues and Subject matter experts to understand various perspective to decide and prioritize.

  • +
  • Logic will get you from A to B. Imagination will take you everywhere. - Albert Einstein.

  • +
  • ..

  • +
+
+
+
Questions from the audience
+
    +
  • About the 4 core concepts, is this based on the model of how human brain works and perceives vision / abstract ideas?

  • +
  • I don’t know if it’s based on how the brain works, but it’s related to creating a framework for solving programming programs that has been extrapolated to solve any other problem as well.

  • +
  • Devil’s advocate question: cooking (by recipe) actually employs all four principles outlined here and has done so since before the advent of computers. Why then is this concept presented as “computational”?

    +
      +
    • Random aside, this is an interesting connection to our “cooking metaphor to HPC”

    • +
    +
  • +
  • Devil’s answer to the Devil’s advocate: Great question, cooking, as far as the act happens in the Devil’s kitchen, does not employ numerical algorithms. The Devil introduced the computer precisely to make man lose apetite for that what is cooked in the Devil’s kitchen to be served to all. Only then can the Devil eat the cake and keep it too …

    +
      +
    • Well, an algorithm without numbers is still an algorithm, i.e. a set of rules :)

    • +
    +
  • +
  • Are there other names for this technique? I may have missed something crucial, but it strikes me as ‘logical thinking’ in a way.

    +
      +
    • Yes, you could also just see it as problem solving. Most people know how to do it and if you’ve worked with programming, you’ve probably applied it. It can be the case that it’s very obvious to some, but not to others.

    • +
    +
  • +
  • Any chance we can ge a link to the slides?

    +
      +
    • They are in the course material: https://coderefinery.github.io/train-the-trainer/computational-thinking/ :thumbs_up:

    • +
    +
  • +
+
+
+
Exercise questions to discuss
+
    +
  1. Conceptually would the strategies provided by computational thinking help you in completing tasks more efficiently?

  2. +
+
    +
  • Room 1:

    +
      +
    • divide and conquer technique

    • +
    • We discussed what happens if you don’t use these, since they are so natural

    • +
    +
  • +
  • Room 2:

    +
      +
    • in some cases yes, if the task is not too small

    • +
    • not sure if more efficiently but it does help at least getting strted

    • +
    • Computational thinking is an extension of what others have called solutionism: the belief that any given problem can be solved by the application of computation. Whatever the practical or social problem we face, there is an app for it. - James Bridle

    • +
    +
  • +
  • Room 3:

    +
      +
    • Helps in starting the task.

    • +
    • For many it is the normal way to do problem solving. Also in Agile & Scrum methodlogies.

    • +
    +
  • +
  • Room 4:

    +
      +
    • Yes, it helped me during my scientific research to manage multiple projects and research publications simultaneously.

    • +
    • +
    +
  • +
+
    +
  1. Do you think that the effectiveness of computational thinking depends on the person’s personality type?

  2. +
+
    +
  • Room 1:

    +
      +
    • yes, we agree it’s quite different. But good vision and motivation this can be effective

    • +
    +
  • +
  • Room 2:

    +
      +
    • yes, laying out all the steps necessary to achieve an overall goal can be very daunting; some people are not good at/ comfortable with following fine-grained instructions

    • +
    • once the problem is broken down, different personalities might choose different ways to tackle the parts

    • +
    • The degree to which something, that is a result of what one means by ‘Computational Thinking,’ is successful in producing a desired result, that is success, cannot be a function of personality.

    • +
    +
  • +
  • Room 3:

    +
      +
    • Yes. Different people have different ways to communicate.

    • +
    • Online tools vs pen and paper

    • +
    +
  • +
  • Room 4:

    +
      +
    • We are all agree that it depends on the personality type but it could be learned and trained

    • +
    +
  • +
+
    +
  1. Would this type of thinking be an option for you to integrate into your current workflow?

  2. +
+
    +
  • Room 1:

    +
      +
    • Yes; we didn’t know the name explicitly; but we use it

    • +
    • It’s quite important for

    • +
    +
  • +
  • Room 2:

    +
      +
    • I’m already doing it implicitly :smile: :+1: :+1:

    • +
    • Writing a program is like writing a song, its all about the tune, lyrics are merely the necessary nuisance a coder needs to put up with. The latter can, if so written, result in a lot of noise.

    • +
    +
  • +
  • Room 3:

    +
      +
    • Easy if you are working alone. But different team may have their own ways of working (inertia). One way would be then to gradually show the rest of the team its effectiveness.

    • +
    • https://teamtopologies.com/key-concepts

    • +
    +
  • +
  • Room 4:

    +
      +
    • We are using it in our daily life so it’s already an option for us, only the terminologies are a bit new.

    • +
    +
  • +
+
+
+
+
Episode 2 : Teaching philosophies
+

Materials: https://coderefinery.github.io/train-the-trainer/teaching-philosophies/

+

Questions to discuss:

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+
Breakout Room exercise
+
    +
  • Room1

    +
      +
    • Motivation

      +
        +
      • For best practices in teaching, learning from each other, collaboration

      • +
      +
    • +
    • Learning applied tech is like an apprecentiship: there is theory, but real learning happens by co-working with others.

    • +
    • Worse is better: teach what can be used more quickly and it can be improved later

    • +
    • +
    • I think there are two bits of teaching - teach the basics and terminology so people know what they want to know, and then teaching how to find out how to do things like Richard said - how to find answers yourself.

    • +
    • Using Jupyter notebooks - good for learning a technique, but not for learning the basics.

    • +
    • Possibly command line usage has a branding problem - “programming other programs”?

    • +
    • the skills we learn in CR training are expected to stay , it is not exam oriented

    • +
    +
  • +
  • Room 2

    +
      +
    • State objectives clearly and repeat them a few times

    • +
    • Try to keep it informal, interactive, flexible

    • +
    • Helps when having practical tasks in mind for the materials taught

    • +
    • Leave some reasoning to the learner, not always giving full answers

      +
        +
      • How to deal with frustration though: try some personal approaches, more clues…

      • +
      +
    • +
    • The mediocre teacher tells. The good teacher explains. The superior teacher demonstrates. The great teacher inspires. — William Arthur Ward

    • +
    • Teaching kids to count is fine, but teaching them what counts is best. –Bob Talbert

    • +
    +
  • +
  • Room 4

    +
      +
    • Question 1: What is your motivation for taking this training?

      +
        +
      • Currently do instruction, wanting to improve as an instructor and helper when conducting software carpentries.

      • +
      • Planning to start some side hustles providing online courses and why not joining the CR in the near future

      • +
      +
    • +
    • Question 2: How structured or informal are your own teaching needs?

      +
        +
      • More recently, follow software carpentries, but look into what aspects can be tailored to keep to different time slots.

      • +
      • I used to be more informal in the past, repetetive practice sessions. Would like to be more structured given the teaching tools.

      • +
      • I’ve done life-coaching and some teaching but I feel i’m both of them

      • +
      +
    • +
    • Question 3: What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

      +
        +
      • Smaller size, and more targetted.

      • +
      • Collaborative tools and targeted audience working with small groups

      • +
      • Academic probably focuses on an audience with a more focused/narrow background, while this style encompasses a wider audience.

      • +
      • Academic teaching keeps theory and practical lab sessions very separate, whereas carpentries combine both.

      • +
      +
    • +
    • Question 4: What other skills need to be taught, but academic teaching isn’t the right setting?

      +
        +
      • Public speaking, collaborative meeting skills

      • +
      • Industrial cases and related work skills

      • +
      +
    • +
    +
  • +
+
+
+
Episode 3: Co-teaching
+

Materials: https://coderefinery.github.io/train-the-trainer/co-teaching/

+
    +
  • In general: Co-teaching is a beast with at least two personalities each of which

    +
      +
    • demand higher preparation requirements

    • +
    • face remarkable complexity in terms of coteacher coordination

    • +
    • in the virtual component face shortcomings related to the technical equipment and the failure of the human factor

    • +
    +
  • +
+
    +
  • Co-teaching requires the framework of co-operative learning. Team teaching does not by default translate into parallel learning, and vice versa.

  • +
+
    +
  • Re: CodeRefinery in-person beginnings – I agree with the “didn’t work so well in-person”, I’m not sure if it’s that we weren’t as ready for it, or that the different characteristics made it not work so much

  • +
  • How do the downsides compare to a single instructor monologuing?

    +
      +
    • That’s a great question! The main difference is that a single instructor can teach himself to be good (i.e. not just boring monologuing) alone, while for teams of 2+ to work well, everyone needs to be baseline-competent. So the effort to avoid downsides gets reduced if (and only if) all team members share it.

    • +
    +
  • +
+
+

Exercise/Discussion: https://coderefinery.github.io/train-the-trainer/co-teaching/#exercise

+

Questions:

+
    +
  • Have you already tried this or similar model in your teaching?

  • +
  • Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best?

  • +
  • Have you tried or seen a different model for two instructors to present? Please share with us how it works.

  • +
+
+
    +
  • room 1

    +
      +
    • We have tendend to do presenter/interviewer more

    • +
    • challenges are co-teaching with different personalities

    • +
    +
  • +
  • room 2

    +
      +
    • Main challenge: finding enough personell :smile:

    • +
    • It’s not always possible/feasible to have colleagues co-teaching

    • +
    • A combination of both, but presenter and interviewer could be difficult to plan an to follow

    • +
    • Guide and demo-giver with technical / non-technical roles could be nice

      +
        +
      • How to plan the guide and demo-giver

        +
          +
        • First guide, then demo

        • +
        • Demo, then guide describes

        • +
        +
      • +
      +
    • +
    • Alternative model: main presenter + ‘technical expert’

      +
        +
      • main presenter introduces concepts from a birdseye view and passes on to the technical expert for additional details, experiences and answers to questions from the audience

      • +
      +
    • +
    • We frequently do a classical division: on person in presenting, one or more are answering questions in the chat; there is rarely any interaction between them however

    • +
    +
  • +
+
    +
  • As has been pointed out by Paolo Freire, in general, ‘education is suffering from narration sickness’ … ‘The outstanding characteristic of this narrative education, then, is the sonority of words, not their transforming power’. Perhaps one approach could be to rephrase the question after having the answer: It is not apriori about the model implemented, it is about whether that what was implemented was judged aposteriori to have succeeded in becoming, or at least could pretend to have done so, the intended context matched model implementation it probably was computed to be.

  • +
+
    +
  • room 4

    +
      +
    • the co-teaching approach does not seem to be widely practiced

    • +
    • it can be interesting to see “mistakes” which are less likely to happen in solo-teaching?

    • +
    • co-teaching can be nicer for audience but maybe more stress/anxiety for instructors to prepare? more stress in terms of not knowing all the questions in advance. less stress worrying about forgetting something.

    • +
    +
  • +
+
+
+
Teaching gems
+

(scroll up to find the green box “Episode on teaching gems”)

+

What’s your favorite way of teaching? Any nice tools you use?

+

Has anyone found a nice online tool to draw?

+
    +
  • I love this tool suite https://excalideck.com/

    +
      +
    • For drawing https://excalidraw.com/

    • +
    +
  • +
  • I have seen Miro …

  • +
  • I think the Code Refineries use something for their graphics that looks a bit ‘cartoony’ - but I cannot remember what it is called!

    +
      +
    • Drawn on remarkable and then coloured and tidied up in Inkscape. :+1:

    • +
    +
  • +
  • I am a big fan of remarkable. I think sharing option is fairly good. Unfortunately bit expensive tool.

    +
      +
    • true, for me it was worth it already for the pdf annotation for research papers, cannot read on computer screen

    • +
    +
  • +
  • https://webwhiteboard.com/

  • +
  • https://www.youtube.com/watch?v=4-l8MY5kYGc

  • +
  • Figma and Kahoot are useful as well

  • +
+

Screenkey: Screenkey for showing keyboard shortcuts

+
    +
  • Is there a Windows version people can recommend?

    +
      +
    • I found this list of alternative for windows users like me: https://alternativeto.net/software/screenkey/ :+1:

    • +
    +
  • +
  • I sometimes use the on-screen keyboard already provided by the OS :+1:

  • +
+
+
+
+

Wrapup

+
    +
  • Next session Tuesday September 3rd 9 CEST: About teaching & cool things we all would like to share

  • +
  • All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14 CEST

  • +
  • Preparations for next week will be sent out by e-mail

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • The co-teaching lesson and experiences from others

  • +
  • Discussions were quite good, had a nice group

  • +
  • Breakout rooms and collaborative tools

  • +
  • Computational thinking and co-teaching are interesting ideas! I have seen it before, but never knew or even recognized it was a method.

  • +
  • Thanks for group discussions working with my chat only interaction! :smile:

  • +
  • ..

  • +
+

What one thing would you improve about this session?

+
    +
  • Minor point - it would be useful to have the teaching gmes box at the bottom of the document rather than the top - tricky to scroll between! In the end I opened two windows which was easier.

    +
      +
    • Thanks, yes agree. Also had that problem, but did not want to move it in between.

    • +
    +
  • +
  • The meaning of teaching “philosophy” wasn’t very clear, felt more like teaching “styles”

    +
      +
    • Thank you, we will take that into consideration

    • +
    +
  • +
  • Some prepared slides to present for an intro about the topics

    +
      +
    • You mean in addition to the materials? To use in the beginning of each session?

    • +
    +
  • +
  • The instructor views segment could be named as additional material, if it was not meant to be discussed within the course.

    +
      +
    • Thank you, we will take that into consideration

    • +
    +
  • +
+

Any other comments?

+
    +
  • Keeping it short and sweet: If at first you don’t succeed in teaching, try to explain it like you’re talking to a room full of cats. Caveat: In a room full of computational thinkers maybe if you tell students that the brain is a computational device that is forbidden, they might get excited and start using it.

  • +
+
+
+

Day4: Session 4 (3.09.24) - Streaming and video editing

+
+
:calendar: Schedule
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 10.00

Why we stream & Behind the scenes

10.15 - 11.00

8.15 - 9.00

10.00 - 10.15

Break

11.00 - 11.15

9.00 - 9.15

10.15 - 10.35

Video Editing

11.15 - 11.35

9.15 - 9.35

10.35 - 10.55

Exercise: Video Editing

11.35 - 11.55

9.35 - 9.55

10.55 - 11.10

Break

11.55 - 12.10

9.55 - 10.10

11.10 - 11.30

Open Broadcaster Software(OBS) introduction

12.10 - 12.30

10.10 - 10.30

11:30 - 11:50

OBS setup & what next

12.30 - 12.50

10.30 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+
:icecream: Icebreaker
+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :coffee: +

  • +
  • :runner:

  • +
  • :tired_face: Tired!

  • +
  • :nerd_face:

  • +
  • +
  • :cloud: :tea:

  • +
+
+
+
Introduction in breakoutrooms
+
    +
  • Name / Affiliation / Location

  • +
+

What’s the most number of people you have taught to?

+
    +
  • 20 at a time, with 1 asleep, 2 fidgiting with some silly device and the rest were… well… staring at their good luck… straight ahead it was of course, right before them.

  • +
  • ~35

  • +
  • ~80 in a lecture in a previous (lecturer) role, 26 in a training course setting

  • +
  • ~30

  • +
  • ~50 in training spaces and more than 100 for public audience talk

  • +
  • 35 (software carpentry)

  • +
  • CodeRefinery answer: The biggest ones are maybe 200-300 people. “small” for a stream is ~100 people.

  • +
+

What’s the most number of people you have taught with?

+
    +
  • 5 or so

  • +
  • 2 or 3 in total

  • +
  • 3, as in three, none of them smiling. I wish I could figure out why… it was such fun really…

  • +
  • 7

  • +
  • 2 or 3

  • +
  • 3 (helpers, not really co-teaching)

  • +
  • CodeRefinery answer: our biggest workshops are something like 10-20 people helping out in many different roles.

  • +
+

How can you divide teaching into separate independent tasks?

+
    +
  • By content blocks, having roles like main and assistant…

  • +
  • Having responsibility for different sections of the course.

  • +
  • Wow, now thats what we call a question… bravo… indeed, how does one separate sleeping and snoring into separate independent tasks…

  • +
  • Course, exercices, resources, tools and forms.

  • +
  • Different people teach different topics

  • +
  • CodeRefinery answer: the big logical blocks are instructors, in-person and breakout room helpers, and Notes-questions answers.

  • +
+

What’s the most interesting or useful thing you’ve learned from an online workshop, and how have you applied it/planning to apply in your life or work

+
    +
  • Having breaks every hour or so

  • +
  • New approach to screensharing, using the ‘portrait’ approach

  • +
  • Manage breathing: reduce stress and use silence to let the audience grasp what you’re saying

  • +
  • Well, the most interesting or useful thing I’ve learned from online workshops is how not to conduct a workshop, or at least some elements of the same, and I have applied this understanding by engaging in the global effort to discover more about how not to conduct a workshop, or at least some elements of the same, with the motto: That’s one small step for a man, one giant leap for mankind..

  • +
+
+
+
+
:question: Questions
+
+
+
Why we stream
+
    +
  • If during streaming there is no interaction between the teacher and the audience, why don’t we just record the lectures and stream them? So one can do a better job, perhaps?

    +
      +
    • Streaming it making it a “thing” that’s a group experience. It feels good to be a part of it, so we hope that encourages people to actually attend. All the mass Q&A is fun, and the audience helps to make it easier to present. Still, this is a good question.

    • +
    • I really appriciate it being “a thing”. If it was just recorded, I would say I would watch it tomorrow, and then I never would.

      +
        +
      • But then you can just fake it, and still have all the breakout rooms and collaborative document and so on. I appreciate the value of having a proper “event”.

        +
          +
        • I think I follow you, but if you pre-recorded the talking bits, then the presentors couldn’t change what they do based on the feedback in the shared document.

          +
            +
          • true, but I assumed that the teachers were too busy to actually do that. The more (less )division of labor between the teachers and the helpers (or collaborative document editors), the more (less) sense it makes to pre-record - IMHO

          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • What interaction options do ‘streamers’ use, e.g. on Twitch/YouTube (not Code Refinary)?

    +
      +
    • I’m besides chat and things that happen in chat, I’m not sure. The Notes-doc is definitely unique to us.

    • +
    +
  • +
  • Streaming is a kind of exercise for the movie star type. If you cannot be one, act like one, pretend, fool the listener into thinking you are one, take their brains and emotions under control. And if they don’t leave the session with tears of love for learning running down their chubby cheeks you know who to kick for doing a job just that bit worse than it should have been necessary.

  • +
  • Have you kept track of streming stats? like how many people logged in and stayed troughout, how many interacted?

    +
      +
    • Yes please, it would be good to see the stats

    • +
    • Here is stats repo

    • +
    • Thanks, I get a 404 error, is it private?

    • +
    • No, I don’t think so. https://github.com/coderefinery/workshop-stats

    • +
    • Still get 404. Does it work for anyone else?

      +
        +
      • Yeah I think it’s private. We need to fix this…

      • +
      +
    • +
    +
  • +
  • How big is small (10-15), medium (~30-40)?

    +
      +
    • I would say below 50 is small.

    • +
    +
  • +
  • Have you considered scaling to more events instead of to a larger audience? I mean, this seems the opposite of scaling, but this kind of content would be more useful the more often is it taught (“I need to learn GIT/Python/* in December!”)

    +
      +
    • We would, but right now we simply don’t have enough time and people to do more small events. But yes, “scheduling conflict” is a big problem - the best we can do right now is written material+videos to follow up on (and hope it’s interesting enough)

    • +
    • Python for Scientific Computing 5-7/November/2024

      +
        +
      • This was just an example. I mean, if I am a PHD student that needs to start working on a topic on Month X which happens to be inconveniently placed in the year, I will not benefit as much from having a workshop at Month X+3

        +
          +
        • The materials are open and the videos are publically available on YouTube channel

          +
            +
          • What’s the ratio of people watching videos afterwards vs people attending the event? That ratio can give an idea of the popularity of the two possible approaches.

          • +
          +
        • +
        +
      • +
      +
    • +
    • The more you scale up the less interactive the course / workshop will need to be. It then becomes a question of priorities, and if teaching is a lower priority then learning than I guess there really should be no prizes for guessing which approach should reign the airwaves.

    • +
    +
  • +
  • I guess outside Europe / Africa, time zones could be a problem?

    +
      +
    • yes, that is true

    • +
    • +
    +
  • +
  • Sorry, I might have missed this: have you been rehearsing and/or doing dry runs?

    +
      +
    • With instructors I like to try to do a dry run. I often don’t do a live broadcast dry run these days since I’m confidente enough, but when you are just starting, it’s a good idea.

    • +
    +
  • +
  • Do you always use Zoom for the ‘presenter end’ or have you tried other things? Teams? Jitsi? etc.?

    +
      +
    • we use mostly zoom

    • +
    • It was first pioneered using Jitsi. You can probably use others, too.

    • +
    +
  • +
  • A comment: for deRSE24 we have been using the GWDG streaming service and OBS, it worked quite well (with a 20s delay or so)

    +
      +
    • Cool! Yes, there is plenty of livestreaming options. Twitch+our OBS config gives us 2-3s of latency (which is low enough for live Notes interaction). You might be able to tune this if needed.

    • +
    +
  • +
+
+
+
Behind the stream
+
    +
  • Does OBS take a lot of RAM or CPU? what are the specs on your machine?

    +
      +
    • Richard have a relatively powerful computer with 8 AMD CPUs.

    • +
    • 4 CPUs are relatively enough for a good OBS setup, most important is a stable internet connection (ideally wired).

    • +
    • An extra monitor is recommended for the setup

    • +
    • See the hardware notesrecommendation here

    • +
    +
  • +
  • Do you do a screenshare from Zoom -> OBS or OBS -> Zoom?

    +
      +
    • Instructors share to Zoom, OBS captures Zoom, OBS sends to the world.

    • +
    • When I am using OBS sfor a single-person presentation recording, I go the other way: OBS captures my desktop/camera, OBS generates the preview window, and then Zoom captures and broadcasts the preview window.

    • +
    +
  • +
+
+
+
Video editing
+
+
Poll
+
    +
  • Have you tried video editing? Add ano as answer below

    +
      +
    • yes: ooooo

    • +
    • no :

    • +
    • Video editing makes all the difference. I have never known a way to avoid this sacred of steps, so to speak. In short, no recording can ever be production ready by default in the books of the wiser among the streamers. In fact, during the editing one can considerably refine and improve the learning experience in great ways. But then one would need to invest both time and effort.

    • +
    +
  • +
  • If yes Which are the tools you use?

    +
      +
    • Windows Movie Maker / ClipChamp

    • +
    • (raw stream from Zoom)

    • +
    • I think it was shotcut - I did only basic trimming

    • +
    • Kdenlive

    • +
    • Clipchamp, OpenShot, Sony Vegas

    • +
    • also ffmpeg from command line to cut beginning and end

    • +
    +
  • +
+
+
+
Questions
+
    +
  • What is Whisper?

    +
      +
    • Open-source model from OpenAI that converts speech to text transcripts.

    • +
    • this one? https://openai.com/index/whisper/

    • +
    • curious if anyone has tried it with languages other than english

    • +
    • I heard that one of my spanish colleague try it with another software. I don’t remember the tool. But with AI bloom there are many licensed tools that can do it with fifferent language

    • +
    +
  • +
  • What do you use to crop the videos?

    +
      +
    • I see now, ffmpeg

    • +
    +
  • +
  • how to merge multiple parts in one? I asked because you edited only the icebreaker part?

    +
      +
    • you can manage it in input part, see ffmpeg-editlist readme.

    • +
    +
  • +
  • Do you generate custom thumbnails for the video?

    +
      +
    • no, because of the time, but its good to have. If we had a volunteer to manage that, then we should!

    • +
    +
  • +
  • Does anyone recommend any other (GUI) tools that work well? ffmpeg is very new to me!

    +
      +
    • if you want a basic trimming and editing , you can use Quicktime player/imovies on mac

    • +
    • Clipchamp as the Microsoft video editor

    • +
    • Thanks :smile:

    • +
    +
  • +
  • How do subtitles get uploaded to YouTube?

    +
      +
    • You upload the video and subtitles as part of upload.

    • +
    • :+1:

    • +
    +
  • +
  • How does codewhisperer compare against youtube’s automatically generated subtitles?

    +
      +
    • by experience, whisper was better couple of years ago. We haven’t compared it recently

    • +
    • I guess and advantage is that you can edit whisper subtitles in case something is odd or whatever, probs cannot do that in YouTube

    • +
    +
  • +
+
+
+
+
Open Broadcaster Software (OBS) introduction & setup
+
    +
  • Are the profiles public?

    +
      +
    • Yes, you can see it here

    • +
    +
  • +
  • Does it work in Linux+Wayland?

    +
      +
    • I think everything we do with OBS would.

    • +
    +
  • +
+
+
+
+

Wrapup

+ +
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • ffmpeg seems great, will give a try for fun!

  • +
  • great to see everything in practice!

  • +
  • Very insightful to see what happens behind the scenes.

  • +
+

What one thing would you improve about this session?

+
    +
  • Some more interactivity would’ve been nice but since most the group preferred demo instead of exercise perhaps it’s only a personal opinion

  • +
  • It would have been good to share the OBS profiles repo beforehand in the setup email - so I could have had it to hand. (https://github.com/coderefinery/obs-config)

    +
      +
    • +1 good idea, we should do this next time

    • +
    +
  • +
  • Perhaps a simpler starter OBS setup?

    +
      +
    • Good idea… I should have, but basically ran out of time to prepare.

    • +
    +
  • +
+

Any other comments?

+
    +
  • Cool to see the switch from RSE to trainer to AV guy, impressive!

  • +
+
+
+
+
+

Instructor guide

+
+

Target audience

+
    +
  • Everyone teaching online workshops about computational topics or interested in teaching.

  • +
  • Previous and future instructors and helpers of CodeRefinery workshops.

  • +
+
+
+

Timing

+

Session 1

+
    +
  • 15 min: Intro

  • +
  • 45 min: Lesson design and development

  • +
  • 15 min: Break

  • +
  • 45 min: Lesson template

  • +
  • 15 min: Break

  • +
  • 30 min: How we collect feedback and measure impact

  • +
  • 10 min: Outro and feedback

  • +
+

Session 2

+
    +
  • 15 min: Intro

  • +
  • 10 min: About the CodeRefinery project and CodeRefinery workshops in general

  • +
  • 30 min: Collaborative notes and interaction

  • +
  • 15 min: Break

  • +
  • 35 min: Workshop overview, roles, onboarding/installation, helpers

  • +
  • 20 min: Sound

  • +
  • 15 min: Break

  • +
  • 30 min: Screenshare

  • +
  • 10 min: Outro and feedback

  • +
+

Session 3

+
    +
  • 15 min: Intro

  • +
  • 30 min: Computational thinking

  • +
  • 15 min: Break

  • +
  • 30 min: Teaching philosohies

  • +
  • 30 min: Co-teaching

  • +
  • 15 min: Break

  • +
  • 35 min: Sharing teaching tips, tricks, tools etc

  • +
  • 10 min: Outro and feedback

  • +
+

Session 4

+
    +
  • 15 min: Intro

  • +
  • 10 min: Why we stream

  • +
  • 20 min: Behind the stream

  • +
  • 15 min: Video editing (part 1)

  • +
  • 15 min: Break

  • +
  • 25 min: Video editing (part 2, exercise)

  • +
  • 20 min: OBS introduction

  • +
  • 15 min: Break

  • +
  • 30 min: OBS setup

  • +
  • 15 min: What’s next?

  • +
+
+
+

Talking points for each sessions intro

+
    +
  • Brief CodeRefinery intro

  • +
  • Instructors intros

  • +
  • Notes intro

    +
      +
    • Check-in

    • +
    • Icebreaker

    • +
    • Participant intros in breakoutrooms (Random assign first, then same for whole session)

    • +
    +
  • +
  • Daily schedule, learning objectives

  • +
  • Code of conduct

  • +
  • Chat (please use collaborative notes)

  • +
+
+
+

Participant preparations for each session

+

Copied from e-mail communication with participants before each session.

+

Session 1: +In general you will only need your brain for the exercises and discussions, but some will have the option to go deeper, which may require some accounts or tools to be set-up. We will inform about these things the week before each session.

+

For Session 1 we recommend to have a GitHub account (https://coderefinery.github.io/installation/github/#github). There will be an optional exercise where you can build a lesson locally. This requires a basic Python environment (https://github.com/coderefinery/sphinx-lesson-template/blob/main/requirements.txt), but do not worry if you cannot or do not want to set up these, there will be plenty of other exercises.

+

Session 2: +In general you will only need your brain for the exercises and discussions. To get the most out of this workshop day we recommend that you join the session with the same computer, display and microphone setup as you would usually use for teaching/ presenting. It may also help to get familar with the different options your computer and Zoom setup provides for screenshare and audio adjustments. +But it is not a must.

+

Session 3: +In general you will only need your brain for the exercises and discussions. If you want to share some “cool gem” in the last episode of this workshop day, please update your registration (link to edit can be found in the registration confirmation e-mail sent by support@coderefinery.org or noreply@neic.org). This is very low barrier, you do not have to be the developer of a tool or technique to share with the group what makes it useful for you; and it does not even have to be cool, sometimes the small “normal” things are the best. You can check out some topics that have been proposed so far in this GitHub issue (#90), you can also comment there if you want to add or change your topic. These will be lightning talk length, so something between 2-5 min depending on how many are interested to share something, but we can collect them all in the collaborative notes for further exploration/reading. +But it is not a must.

+

Session 4: +This upcoming session (session number 4) will cover the technical aspects of CodeRefinery-style online teaching. These topics have never before been covered in this much detail, so if it’s interesting to you, don’t miss it. (You might also want to pass this on to others who are interested in technical production of online events; registration is still open!).

+

First, we talk about why we stream (how we got here, advantages, disadvantages, how to be an instructor in a livestreamed workshop, and what it looks like from a broad level from the production side)

+

Then, we show how we are able to release videos so quickly. This is useful far beyond CodeRefinery, and there are also some hands-on exercises. Come prepared to set up a Python environment and the ffmpeg command line tool if you want to try these.

+

Finally, we see details about how to set up Zoom→Livestream environment for yourself. There isn’t time to do this as a proper exercise, but it’s the starting point and the instructor will offer help after the course for those interested. If you want to try this out during the session, install OBS Studio in advance.

+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright CodeRefinery project.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/singlehtml/objects.inv b/branch/main/singlehtml/objects.inv new file mode 100644 index 0000000..e7d370e Binary files /dev/null and b/branch/main/singlehtml/objects.inv differ diff --git a/branch/main/sound/index.html b/branch/main/sound/index.html new file mode 100644 index 0000000..040b61f --- /dev/null +++ b/branch/main/sound/index.html @@ -0,0 +1,366 @@ + + + + + + + Sound — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Sound

+
+

Objectives

+
    +
  • Understand that sound quality is very important

  • +
  • Evaluate your and others sound quality and know how to improve it

  • +
  • Test tips and tricks for achieving good sound quality

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Exercises: 10 min

  • +
+
+
+

The importance of audio

+
    +
  • Pleasing audio quality makes events much more enjoyable

  • +
  • Audio is one of the most important things you can control

  • +
  • Things that can go wrong:

    +
      +
    • Too quiet

    • +
    • Too loud

    • +
    • Instructors’ volumes imbalanced

    • +
    • Background noise

    • +
    • Low-quality/breaking up audio hard to hear.

    • +
    • “Ducking” (first words lower volume, or lower volume other times)

    • +
    +
  • +
+
+
+

Tips for good sound quality

+
    +
  • Have a headset with mounted microphone

    +
      +
    • Even if you have a professional external microphone, it doesn’t +matter if your room has bad acoustics.

    • +
    • The close pickup can’t be beat with normal tools.

    • +
    • As long as it’s headset mounted, price doesn’t seem to matter +that much.

    • +
    +
  • +
  • Don’t use Bluetooth

    +
      +
    • Bluetooth can have too much latency (300-500ms)

    • +
    • This may seem small but for interactive work, it’s a lot

    • +
    • Use a wired headset, or wireless with a non-Bluetooth USB plug +(like gaming headsets have). These have much lower latency.

    • +
    • Bluetooth 5 can have much lower latency, but you probably +shouldn’t count on that without testing.

    • +
    • It can also have lower sound quality on some devices due to +bandwidth limitations.

    • +
    +
  • +
  • Once you have a headset, turn input noise cancellation to low +(wherever it might be: headphone, meeting software, etc.).

  • +
+
+
+

Balancing and dynamic adjustment

+
    +
  • It’s important that instructors volumes match.

  • +
  • An exercise will go over a systematic procedure for matching +volumes.

    +
      +
    • Practice so that you can do this quickly.

    • +
    +
  • +
  • May need re-adjusting when instructors swap out or start getting +excited.

  • +
  • An exercise below will demonstrate our procedure.

  • +
+
+
+

Speak up when there are problems

+
    +
  • If you notice someone with audio issues, let them know right away +(voice if bad, or chat/notes if less urgent).

  • +
  • Take the time to fix it as soon as practical.

  • +
  • Make a culture of speaking up, helping, and not suffering.

  • +
+
+
+

Recommendations

+
    +
  • Procure some reasonable headset.

  • +
  • Low/medium-priced gaming-type headsets have worked well for us.

    +
      +
    • (gaming headsets usually aren’t Bluetooth, because gaming needs +low latency.)

    • +
    +
  • +
  • Show this page to your workplace (if you have one) and call a good +headset work equipment.

  • +
+
+
+

Exercises

+
+

Sound-1: Evaluate sound quality

+

It’s important to be able to discuss with others the quality of their +audio. They can’t hear themselves, after all.

+
    +
  • Within the teams, discuss each person’s audio quality and what kind +of setup they have.

  • +
  • Be respectful and constructive (and realize that people came +prepared to listen, not teach).

  • +
  • Consider, for example

    +
      +
    • Volume

    • +
    • Clarity

    • +
    • Background noise

    • +
    • Noise cancellation artifacts

    • +
    • “Ducking”: first words at lower volume or missing

    • +
    +
  • +
  • Discuss how to bring this up during other courses and meetings.

  • +
+
+
+

Sound-2: Adjust volume up and down

+

In addition to individual quality, it is important that sound is +balanced among all instructors. Have you ever been to a event when +one person is too quiet and they can’t make themselves any louder? +And they can’t adjust it?

+

You should ensure that you have a range of volumes available to you. +You might have to look into several different locations in order to +make the full adjustment ().

+
    +
  • Go to your sound settings

  • +
  • One by one, each person

    +
      +
    • Adjusts their microphone volume so quiet that they can’t be heard.

    • +
    • Adjusts their microphone volume so that it is extremely loud (this +may require going beyond 100% if possible).

    • +
    +
  • +
  • Basically, make sure you aren’t so close to either end that you have +no potential to make an adjustment in that direction.

  • +
  • Everyone tries to set the volume to something reasonable, in +preparation for the next exercise.

  • +
+

Once you know where these settings are , you won’t be panicked when the +volume is too low or high during a course.

+
+
+

Sound-3: Do a balance check

+

It’s important that instructor audio is balanced (the same volume). +But how can you do this?

+
    +
  • Pick a leader.

  • +
  • The leader decides the order (“I am first, then [name-1] and +[name-2]”)

  • +
  • The leader says “one”. Everyone else says “one” in the order +specified.

  • +
  • The leader says “two”. Everyone else says “two” in the order.

  • +
  • The leader asks for opinions on who they think is louder or softer. +If there are more than three people, you can figure it out +yourselves. With less than two, you have to ask someone in the +audience.

  • +
+

Example:

+
    +
  • Leader: Let’s do a sound check. I am first, then AAA and BBB.

  • +
  • Leader: One

  • +
  • AAA: One

  • +
  • BBB: One

  • +
  • Leader: Two

  • +
  • AAA: Two

  • +
  • BBB: Two

  • +
  • Leader: Three

  • +
  • AAA: Three

  • +
  • BBB: Three

  • +
  • Leader: How did that sound to everyone?

  • +
  • [Someone else]: Leader and BBB were pretty similar but AAA is a bit +lower.

  • +
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Audio quality is important and one of the most notable parts of the +workshop.

  • +
  • Improving audio isn’t hard or expensive, but does require preparation.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/streaming-whats-next/index.html b/branch/main/streaming-whats-next/index.html new file mode 100644 index 0000000..916e18c --- /dev/null +++ b/branch/main/streaming-whats-next/index.html @@ -0,0 +1,202 @@ + + + + + + + What’s next? — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

What’s next?

+
+

Objectives

+
    +
  • Know next steps if you want to do streaming

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 5 min

  • +
  • Q&A 5 min

  • +
+
+

What comes next?

+
    +
  • We talked a lot about theory, and gave demonstrations.

  • +
  • Hands-on is very different. We recommend working with someone to +put it in practice.

  • +
  • +
+
    +
  • Work with someone who can show you the way

  • +
  • Use it for smaller courses with a backup plan

  • +
+
+

See also

+
+

Keypoints

+
    +
  • These lessons about streaming have been the theoretical part of +streaming training.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/streaming/index.html b/branch/main/streaming/index.html new file mode 100644 index 0000000..54c786f --- /dev/null +++ b/branch/main/streaming/index.html @@ -0,0 +1,274 @@ + + + + + + + Behind the stream — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Behind the stream

+
+

Objectives

+
    +
  • Take a first look at the broadcaster’s view.

  • +
  • Get to know what happens “behind the stream” of a workshop

  • +
  • See what the “broadcaster” sees and what they need to do.

  • +
  • Not yet: learn details of how to do this.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Q&A 10 min

  • +
+
+

In this episode, you’ll see an end-to-end view of streaming from the +broadcaster’s point of view. It’s a tour but not an explanation or +tutorial.

+
+

Who does what

+

We have certain role definitions:

+
    +
  • Broadcaster: Our term for the person who manages the streaming.

  • +
  • Director: Person who is guiding the instructors to their +sessions, changing the scenes, calling the breaks, etc.

    +
      +
    • Could be the same as broadcaster.

    • +
    +
  • +
  • Instructor: One who is teaching. They don’t have to know +anything else about how streaming works.

  • +
+

This lesson describes what the Broadcaster/Director sees.

+
+
+

Window layouts

+

What does the broadcaster see on their screen?

+
    +
  • What are the main windows you see?

  • +
  • What do each of them do?

  • +
  • Which ones do you need to focus on?

  • +
  • How do you keep all this straight in your head?

  • +
+
+
+

CodeRefinery control panel

+
    +
  • A custom application that controls scenes

  • +
  • Based on OBS-websocket (remote control connection for OBS - we’ll +learn about this later)

  • +
  • Can also work remotely, so that you can have a remote director

  • +
+
+
+

How scenes are controlled

+

What has to be done during a course?

+
    +
  • How do you start the stream?

  • +
  • How do you change the view?

  • +
  • How do you adjust things based on what the instructors share?

  • +
  • How do you coordinate with the instructors?

  • +
  • How do you know when to change the view?

  • +
+
+
+

Getting it set up

+
    +
  • How hard was it to figure this out?

  • +
  • How hard is it to set it up for each new workshop?

  • +
+
+
+

What can go wrong

+
    +
  • What’s the worst that has happened?

  • +
  • What if you need to walk away for a bit?

  • +
  • Someone broadcasts something unexpectedly

  • +
+
+
+

Alternatives

+
    +
  • Youtube vs Twitch

  • +
  • Zoom stream directly to YouTube/Twitch

  • +
  • Direct streaming platform, e.g. streamyard

  • +
+
+
+

Q&A

+

Q&A from audience

+
+

Keypoints

+
    +
  • The broadcaster’s view shouldn’t be so scary.

  • +
  • There is a lot to manage, but each individual part isn’t that hard.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/teaching-philosophies/index.html b/branch/main/teaching-philosophies/index.html new file mode 100644 index 0000000..155b81a --- /dev/null +++ b/branch/main/teaching-philosophies/index.html @@ -0,0 +1,314 @@ + + + + + + + CodeRefinery teaching philosophies — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CodeRefinery teaching philosophies

+
+

Objectives

+
    +
  • Get to know the teaching philosophies of CodeRefinery instructors

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Discussion: 20 min

  • +
+
+
+

Introduction

+

During this episode we split into breakoutrooms and discuss own teaching philosophies. +Collect your teaching philosophies in the collaborative document. We will be going through +these and the end of the lesson.

+
+

Ice-breaker in groups (20 minutes)

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+
+

Instructor views

+

Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops.

+

It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us.

+
+

Video recordings

+

We have recorded some of the below as videos: https://www.youtube.com/playlist?list=PLpLblYHCzJAAHF89P-GCjEXWC8CF-7nhX

+
+
+

Bjørn Lindi

+

My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this “BLOB” (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the “BLOB”, to be able to share it with others.

+

In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic.

+

When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson.

+

Tools that I find useful in preparing a lesson is concept maps and Learner Personas (though I have developed too few of them):

+ +
+
+

Radovan Bast

+

My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos.

+

My goal for a lesson is to spark curiosity to try things after the lesson, both +for the novices (“This looks like a useful tool, I want to try using it after +the workshop.”) and the more experienced participants (“Aha - I did not know +you could do this. I wonder whether I can make it work with X.”). I like to +start lessons with a question because this makes participants look up from +their browsers.

+

Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise.

+

For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate the +answer.

+

I try to avoid jargon and “war stories” from the professional developers’ +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid “customer”, +“production”, also a lot of Agile jargon is hard to relate to.

+

Less and clear is better than more and unclear. Simple examples are better than +complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +“simply”, “just”, “easy”. If participants take home one or two points from a +lesson, that’s for me success.

+

I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don’t want to be +surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or slide. +This allows me to skip and distill the essence and not read bullet point by +bullet point.

+

I try to never deviate from the script and if I do, be very explicit about it.

+

A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel listening to me.

+

I very much like the co-teaching approach where the other person helps +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson.

+
+
+

Sabry Razick

+

My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case.

+
+
+

Richard Darst

+

Like many people, I’ve often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I’ve realized long ago that my most important lessons weren’t +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I’ve realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds.

+

My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I’m often start at the +very basics, because this is what I see missing most often.

+

When teaching, I like lots of audience questions and don’t mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don’t have to know everything perfectly, just show how +you’d approach a problem.

+
+
+

Stepas Toliautas

+

I aim for my learners to understand things (concepts, techniques…), instead of just memorizing them. The phrase I use from time to time when teaching information technology topics (be it hardware or software) is “there is no magic”: everything can be explained if necessary. While CodeRefinery also emphasizes usefulness/ immediate applicability of the content, often having the correct notions actually helps to start using them sooner and with less mistakes.

+

I try to guide my audience through the presented material with occasional questions related to previous topics and common knowledge – to help them link the concepts already during the lesson. I’m also fully aware that waiting for someone to answer is quite uncomfortable in-person and doubly so in an online environment, especially if no one uses their cameras :)

+

And if I get the question I don’t have the answer for (or material to show it) at the moment, in university classes I prepare and come back to it next time. While with one-off workshops there might not be a “next time”, open-source material used by CodeRefinery allows to have the same outcome: the latest and greatest version stays available for self-study afterwards.

+
+
+
+

Summary

+
+

Keypoints

+
    +
  • People have different viewpoints on teaching.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/video-editing/index.html b/branch/main/video-editing/index.html new file mode 100644 index 0000000..bdf96d4 --- /dev/null +++ b/branch/main/video-editing/index.html @@ -0,0 +1,606 @@ + + + + + + + Video editing — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Video editing

+
+

Objectives

+
    +
  • Get to know ways of quick video editing to be able to provide +accessible videos

  • +
  • Learn how video editing can be distributed and done the same day.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 20 min

  • +
+
+

Video recordings could be useful for people watching later, +but also are (perhaps more) useful for immediate review and catching +up after missing a day in a workshop. For this, they need to be +released immediately, within a few hours of the workshop. +CodeRefinery does this, and you can too.

+

Hypothesis: videos must be processed the same evening as they were +recorded, otherwise (it may never happen) or (it’s too late to be +useful). To do that, we have to make processing good enough (not +perfect) and fast and the work distributeable.

+
+

Primary articles

+ +
+
+

How this relates to streaming

+
    +
  • If you stream, then the audience can not appear in the recorded +videos

  • +
  • This allows you to release videos very quickly if you have the +right tools.

  • +
  • When you have a large audience, the videos start helping more +(review a missed day, catch up later, review later)

  • +
  • Thus

    +
      +
    • If you would never want videos, there may never be a benefit to +streaming

    • +
    • If you want videos, it gives motivation to stream.

    • +
    +
  • +
+
+
+

Summary

+
    +
  • Basic principle: privacy is more important than any other factor. +If we can’t guarantee privacy, we can’t release videos at all.

    +
      +
    • Disclaimers such as “if you don’t want to appear in a recording, +leave your video off and don’t say anything”, since a) accidents +happen especially when coming back from breakout rooms. b) it +creates an incentive to not interact or participate in the course.

    • +
    +
  • +
  • Livestreaming is important here: by separating the instruction from +the audience audio/video, there is no privacy risk in the raw +recording. They could be released or shared unprocessed.

  • +
  • Our overall priorities

    +
      +
    1. No learner (or anyone not staff) video, audio, names, etc. are +present in the recordings.

    2. +
    3. Good descriptions.

    4. +
    5. Removing breaks and other dead time.

    6. +
    7. Splitting videos into useful chunks (e.g. per-episode), perhaps +equal with the next one:

    8. +
    9. Good Table of Contents information so learners can jump to the +right spots (this also helps with “good description”.)

    10. +
    +
  • +
  • ffmpeg-editlist +allows us to define an edit in a text file (crowdsourceable on +Github), and then generate videos very quickly.

  • +
+
+
+

How we do it

+

The full explanation is in the form of the exercises below. As a +summary:

+
    +
  • Record raw video (if from a stream, audience can’t possibly be in +it)

  • +
  • Run Whisper to get good-enough subtitles. Distribute to someone for +checking and improving.

  • +
  • Define the editing steps (which segments become which videos and +their descriptions) in a YAML file.

  • +
  • Run ffmpeg-editlist, which takes combines the previous three steps +into final videos.

  • +
+
+
+

Exercises

+
+

Exercise A

+

These exercises will take you through the whole sequence.

+
+

Editing-1: Get your sample video

+

Download a sample video:

+ +
+

Editing-2: Run Whisper to generate raw subtitles and test video.

+

First off, install Whisper and generate the base subtitles, based +on the. Since this is probably too much to expect for a short +lesson, they are provided for you (above), but if you want you can +try using Whisper, or generating the subtitles some other way.

+

You can start generating subtitles now, while you do the next +steps, so that they are ready by the time you are ready to apply +the editlist. ffmpeg-editlist can also slice up the subtitles from +the main video to make subtitles for each segment you cut out.

+

Whisper is left as an exercise to the reader.

+ +
+
+
+

Editing-3: Create the basic editlist.yaml file

+

Install +ffmpeg-editlist and +try to follow its instructions, to create an edit with these features:

+
    +
  • The input definition.

  • +
  • Two output sections: the “Intro to the course”, and “From data +storage to your science” talks (Remember it said the recording +started at 11:35… look at the schedule for hints on when it +might start!). This should have a start/end timestamp from the +original video.

  • +
+

A basic example:

+
- input: day1-raw.mkv
+
+# This is the output from one section.  Your result should have two of these sections.
+- output: part1.mkv
+  title: something
+  description: >-
+    some long
+    description of the
+    segment
+  editlist:
+    - start: 10:00    # start timestamp of the section, in *original* video
+    - end: 20:00      # end timestamp of the section, in the *original* video
+
+
+ +
+
+

Discussion: what makes a video easy to edit?

+
    +
  • Clear speaking and have high audio quality.

  • +
  • For subtitle generation: Separate sentences cleanly, otherwise it +gets in a “stream of words” instead of “punctuated sentences” +mode.

  • +
  • Clearly screen-sharing the place you are at, including section +name.

  • +
  • Clear transitions, “OK, now let’s move on to the next lesson, +LESSON-NAME. Going back to the main page, we see it here.”

  • +
  • Clearly indicate where the transitions are

  • +
  • Hover mouse cursor over the area you are currently talking about.

  • +
  • Scroll screen when you move on to a new topic.

  • +
  • Accurate course webpage and sticking to the schedule

  • +
+

All of these are also good for learners. By editing videos, you +become an advocate for good teaching overall.

+
+
+

Editing-4: Run ffmpeg-editlist

+

Install ffmpeg-editlist: pip install ffmpeg-editlist[srt] (you +may want to use a virtual environment, but these are very minimal +dependencies).

+

The ffmpeg command line tool must be available in your +PATH.

+ +
+
+

Editing-5: Add more features

+
    +
  • Several chapter definitions.(re-run and you should see a +.info.txt file also generated). Video chapter definitions +are timestamps of the original video, that get translated to +timestamps of the output video.

    +
    - output: part1.mkv
    +  editlist:
    +  - start: 10:00
    +  - -: Introduction    #  <-- New, `-` means "at start time"
    +  - 10:45: Part 1      #  <-- New
    +  - 15:00: Part 2      #  <-- New
    +  - end: 20:00
    +
    +
    +

    Look at the .info.txt files that come out now. What is new in it?

    +
  • +
  • Add in “workshop title”, “workshop description”, and see the +.info.txt files that come out now. This is ready for +copy-pasting into a YouTube description (first line is the title, +rest is the description).

    +

    Look at the new .info.txt files. What is new?

    +
  • +
+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+
+
+

Editing-7: Generate the final output file.

+
    +
  • Run ffmpeg-editlist with the --reencode option: this +re-encodes the video and makes sure that there is no black point +at the start.

  • +
  • If you re-run with --check, it won’t output a new video file, +but it will re-output the .info.txt and .srt files. +This is useful when you adjust descriptions or chapters.

  • +
+
+
+

Discussion: how to distribute this?

+

Create a flowchat of all the parts that need to be done, and which +parts can be done in parallel. Don’t forget things that you might +need to do before the workshop starts.

+

How hard was this editing? Was it worth it?

+
+
+
+

Exercise B

+

This is a more limited (and older) version of the above exercise, +using an synthetic example video.

+
+

Use ffmpeg-editlist to edit this sample video

+

Prerequisites: ffmpeg must be installed on your computer +outside of Python. Be able to install ffmpeg-editlist. This is +simple in a Python virtual environment, but if not the only +dependency is PyYAML.

+ + +
+
+
+
+

See also

+ +
+

Keypoints

+
    +
  • Video editing is very useful for learning

  • +
  • Set your time budget and make it good enough in that time

  • +
  • Reviewing videos improves your teaching, too.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/branch/main/why-we-stream/index.html b/branch/main/why-we-stream/index.html new file mode 100644 index 0000000..666d0cf --- /dev/null +++ b/branch/main/why-we-stream/index.html @@ -0,0 +1,298 @@ + + + + + + + Why we stream — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Why we stream

+
+

Objectives

+
    +
  • Learn the general history of CodeRefinery streaming.

  • +
  • Discuss the benefits of streaming and recording

  • +
  • Discuss the downsides and difficulties

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 10 min

  • +
  • Q&A: 5 min

  • +
  • Exercises: 0 min

  • +
+
+

This is a general discussion of the topics of the day, focused on the +history of why we stream and record, how we got here, and how people +feel about it. We won’t focus on how anything is done.

+
+

Icebreaker questions

+
    +
  • What is the most people you have taught for?

  • +
  • What are the distinct parts of teaching, that can be +separated? (teaching, helping, etc)

  • +
+
+
+

What is streaming and recording?

+
    +
  • Streaming is mass communication: one to many

    +
      +
    • Interaction audience→presenters is more limited (but different)

    • +
    +
  • +
  • Using consumer-grade tools, normal people can reach huge audiences +by Twitch/YouTube/etc.

  • +
  • This isn’t actually that hard: people with much less training than +us do it all the time.

  • +
  • They reach huge audiences and maintain engagement for long events.

  • +
+

Recording and rapid video editing is useful even without +streaming.

+
+
+

History

+
    +
  • In-person workshops

    +
      +
    • 3 × full day, required travel, infrequent, one-shot

    • +
    +
  • +
  • Covid and remote teaching

    +
      +
    • Traditional “Zoom” teaching several times

    • +
    +
  • +
  • Mega-CodeRefinery workshop

    +
      +
    • 100-person Zoom teaching

    • +
    • Emphasis on teams

    • +
    +
  • +
  • Research Software Hour

    +
      +
    • Livestream free-form discussions on Twitch

    • +
    +
  • +
  • Streamed “HPC Kickstart” courses

  • +
+
+
+

Benefits and disadvantages

+

Benefits:

+
    +
  • Larger size gives more (but different) interaction possibility

    +
      +
    • “Notes” for async Q&A

    • +
    +
  • +
  • Recording (with no privacy risk) allows instant reviews

  • +
  • Stream-scale allows for many of the things you have learned about in +days 1-3.

  • +
+

Disadvantages:

+
    +
  • Requires training for using the tools

  • +
  • Requires a certain scale to be worth it

  • +
  • Coordination is much harder for big events

  • +
+

When would I recommend it?

+
    +
  • No: For small courses

  • +
  • Questionable: Medium sized courses with no videos

  • +
  • Yes: When you want the largest audience

  • +
  • Yes: When you want without registration required

  • +
  • Yes: When you want good reusability/fast videos

  • +
+
+
+

Future prospects (briefly)

+
    +
  • Streaming probably stays as a CodeRefinery tool

  • +
  • We can scale our courses much larger than they are now. Why don’t +we, together with others?

  • +
  • These tools are useful in other places too

    +
      +
    • I’ve used them to record my own talks to make videos of my +single-person presentations or record conference talks nicer than Zoom.

    • +
    +
  • +
+
+
+

Q&A

+

Q&A from audience

+
+

Keypoints

+
    +
  • Streaming optimizes a course for different things

  • +
  • The disadvantages can be compensated for

  • +
  • There are benefits and disadvantages

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/co-teaching/index.html b/co-teaching/index.html new file mode 100644 index 0000000..fee9eb9 --- /dev/null +++ b/co-teaching/index.html @@ -0,0 +1,301 @@ + + + + + + + Co-teaching — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Co-teaching

+
+

Objectives

+
    +
  • Get to know the principle of co-teaching: How we do it and how you can too.

  • +
  • Learn the team teaching concept and how to tailor it to your situation.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 15 min

  • +
  • Exercises: 10 min

  • +
  • Discussion: 5 min

  • +
+
+
+

Overview

+

CodeRefinery lessons benefit from the application of the concepts of co-teaching.

+
+

Co-teaching

+

Co-teaching can be defined as “the division of labor between educators to plan, organize, instruct and make assessments on the same group of students, generally in a common classroom, and often with a strong focus on those teaching as a team complementing one another’s particular skills or other strengths”.

+
+

Co-teaching can be used in various forms, some of which are present in our workshops:

+
    +
  • Teaching + support, e.g. one of the teachers leading instruction while the other watches over and maintains the collaborative document (HackMD/HedgeDoc/…).

  • +
  • Another similar example is remote learning groups that watch the streamed CodeRefinery lessons guided by the local instructors.

  • +
  • Having open-source material and planning jointly allows multiple instances of a lesson to be held by multiple teachers:

    +
      +
    • parallel teaching, to different audiences at the same time,

    • +
    • alternative teaching, to different audiences at the same or different time, with potential content adjustments (for example, different installation procedures).

    • +
    +
  • +
  • Team teaching, where the lesson is presented by multiple (in most cases, two) teachers who actively engage in conversation with each other. The team-teaching concept is explained in more detail in the CodeRefinery manual.

  • +
+

In reality, different forms are very often mixed or fused together, even within a single lesson.

+

Co-teaching is not an online-only concept. However, it is very practical in online teaching due to larger number of instructors and learners potentially available to join a teaching session.

+
+
+

Co-teaching and team teaching benefits

+
    +
  • It saves preparation time. Co-teachers can rely on each other’s strengths while creating/ revising the material as well as in unexpected situations during the lesson.

  • +
  • It helps with onboarding new instructors. One of the co-teachers can be learning at the same time, either the subtleties of the material taught (in this case literally being the “voice of the audience”) or the teaching process itself.

  • +
  • Team teaching looks more interactive and engaging to the audience in many cases, without forcing the learners to speak up if they can’t or don’t want to do so.

  • +
  • It also ensures responsive feedback and less workload by having more active minds.

  • +
+
+

Are there any downsides?

+

Not every learner and not every instructor might like the team-teaching approach.

+
    +
  • It might seem less structured, unprepared, and chaotic, even with preparation.

    +
      +
    • It might create situations where instructors accidentally talk over each other or “interrupt” and change the flow of the lesson.

    • +
    • For some instructors it can be stressful to not know in advance what questions they get asked from the co-instructor.

    • +
    • Sometimes when an unexpected question is asked that throws the other instructor off, it can add to the feeling of chaos and unpreparedness.

    • +
    +
  • +
  • It can be interactive and engaging but it can also end up awkward if the co-teachers don’t have a good synergy.

    +
      +
    • Can sound awkward: Main instructor talking all the time and at the end asking co-instructor whether everything is clear and co-instructor only saying “yes”.

    • +
    • Possibly more engaging: Co-instructor asking questions which help with the flow and a common understanding of the material.

    • +
    +
  • +
+
+
+
+

Team teaching specifics

+
    +
  • For successful team teaching, additional coordination is needed, first of all to agree on the teaching model (see below) and the person in control (the director) for the lesson or its parts.

  • +
  • It’s useful to keep track of the lecture plan. The discussion is a good way to make lesson more interactive and adjust to the audience, but deviating too much will become disorienting (for example, if someone dropped their attention for a minute and now is trying to catch-up by reading lecture notes).

  • +
  • Experienced solo teacher might have a habit to keep talking (lecturing), while the co-teacher might not want to “interrupt”. Therefore, it is important for the leading presenter to anticipate and allow for remarks/ questions, and this can be different from one’s previous teaching style at first.

  • +
+
+
+

Team teaching models

+

We propose two basic models, but of course there is a constant continuum.

+
+

Guide and demo-giver

+

One person serves the role of guide, explaining the big picture and context of the examples.

+

Another, the demo-giver,

+
    +
  • shows the typing and does the examples,

  • +
  • might take the role of a learner who is asking about what is going on, to actually explain the details, or to comment occasionally.

  • +
+

Hands-on demos and exercises work especially well like this.

+
+
+

Presenter and interviewer

+

In this case, one is the presenter who is mostly explaining (including demos or examples), and trying to move the forward through the material.

+

Another, the interviewer,

+
    +
  • serves as a learner or spotter,

  • +
  • fills in gaps by asking relevant questions,

  • +
  • tries to comment to the presenter when things are going off track.

  • +
+

This can be seen as closer to classical teaching, but with a dedicated and prepared “voice of the audience”.

+
+
+

Exercise

+
+

Discuss the models of team teaching (10 min)

+

While in breakout rooms, discuss one of the basic team-teaching models presented here:

+
    +
  • Have you already tried this or similar model in your teaching?

  • +
  • Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best?

  • +
+

Write your comments in the collaborative document.

+
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Co-teaching focuses on complementing individual skills and strengths in teaching process.

  • +
  • Co-teaching may save time, reduce teachers’ workload and make lessons more interactive/ engaging.

  • +
  • Team teaching requires some adjustments in lesson preparation and delivery.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/coderefinery-intro/index.html b/coderefinery-intro/index.html new file mode 100644 index 0000000..1e52a61 --- /dev/null +++ b/coderefinery-intro/index.html @@ -0,0 +1,280 @@ + + + + + + + About the CodeRefinery project and CodeRefinery workshops in general — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • + Edit on GitHub +
  • +
+
+
+
+
+ +
+

About the CodeRefinery project and CodeRefinery workshops in general

+
+

Objectives

+
    +
  • Discuss what CodeRefinery is and how we got here

  • +
  • Understand about the challenges to define our target audience

  • +
+
+

CodeRefinery is a +Nordic e-Infrastructure Collaboration (NeIC) +project that has started in October 2016 and is currently +funded until February 2025. We are working on the continuation plans.

+

The funding from 2022-2025 is designed to keep this project active +beyond 2025 by forming a support network and building a community of +instructors and contributors.

+
+

History

+

The CodeRefinery project idea grew out of two SeSE courses given at KTH Stockholm in 2014 and 2016. +The project proposal itself was submitted to NeIC in 2015, accepted in 2015, and started in 2016.

+

We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form.

+
+
+

Goals

+
    +
  • Develop and maintain training material on good enough software development practices for researchers that write code/scripts/notebooks.

  • +
  • Our material addresses all academic disciplines and tries to be as programming language-independent as possible.

  • +
  • Provide a code repository hosting service that is open and free +for all researchers based in universities and research institutes from Nordic countries.

  • +
  • Provide training opportunities in the Nordics using (Carpentries and) CodeRefinery training materials.

  • +
  • Evolve the project towards a community-driven project with a network of instructors and contributors.

  • +
+
+
+

Community

+
+../_images/community.png +
+

Image showing the key areas of the CodeRefinery community: Workshops, chat inlcuding help channel, online meetings and co-working, +other collaborative training, eg on High Performance Computing topics.

+
+
+

CodeRefinery is not just workshops, we are community and want you to be part of it!

+

There are many different levels of involvement, from the occasional commenter in chat, +CodeRefinery ambassador (people who like the project and workshops and help us spreading the word) or lesson issue creators and lesson contributors to +local host, co-instructor or co-organizer.

+

Best first step in any case is to join the CodeRefinery Zulip chat +or let us know about your interest at support@coderefinery.org.

+
+
+

Target audience

+

One common question we get is how do we relate to the Carpentries. +This section describes how we see it:

+
+

Carpentries audience

+

The Carpentries aims to teach computational competence to learners through an applied approach, +avoiding the theoretical and general in favor of the practical and specific.

+

Mostly, learners do not need to have any prior experience in programming. +One major goal of a Carpentries workshop is to raise awareness on the tools researchers can learn/use to speed up their research.

+

By showing learners how to solve specific problems with specific tools and providing hands-on practice, +learners develops confidence for future learning.

+
+

Novices

+

We often qualify Carpentries learners as novices: they do not know what they need to learn yet. +A typical example is the usage of version control: the Carpentries lesson +Version Control with Git +aims to give a +very high level conceptual overview of Git but it does not explain how it can be used in research projects.

+
+
+
+

CodeRefinery audience

+

In that sense, CodeRefinery workshops differ from Carpentries workshops as we assume +our audience already writes code and scripts and we aim at teaching them best software practices.

+

Our learners usually do not have a good overview of best software practices but are aware of the need to learn them. +Very often, they know of the tools (Git, Jupyter, etc.) we are teaching +but have difficulties to make the best use of them in their software development workflow.

+

Whenever we can, we direct learners that do not have sufficient coding experience to Carpentries workshops.

+
+

Competent practitioners

+

We often qualify CodeRefinery learners as competent practitioners because they already have an understanding of their needs.

+
+ +
+
+

Keypoints: CodeRefinery

+
    +
  • Teaches intermediate-level software development tool lessons

  • +
  • It is difficult to define “best practices”, we try to teach “good enough” practices

  • +
  • Training network for other lessons

  • +
  • Publicly-funded discrete projects (3 projects actually) transitioning towards an open community project

  • +
  • We have online material, teaching, and exercise sessions

  • +
  • Our main target audience are competent practitioners, but also novices and experts can get something out of the workshops

  • +
  • We want more people to work with us, and to work with more people

  • +
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/collaborative-notes/index.html b/collaborative-notes/index.html new file mode 100644 index 0000000..6062c6d --- /dev/null +++ b/collaborative-notes/index.html @@ -0,0 +1,530 @@ + + + + + + + Collaborative notes — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Collaborative notes

+
+

Objectives

+
    +
  • Be able to provide a highly interactive online workshop environment with collaborative documents

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Exercise: 15 min

  • +
  • Questions & Answers: 5 min

  • +
+
+
+

Introduction

+

The Collaborative document is how you interact with the participants. +The participants can ask questions and give feedback through the collaborative +document. During a CodeRefinery session there can be a large a volume of questions. +A dedicated person, a Collaborative document-manager, is needed to answer and edit the collaborative document. +Let us see how the collaborative document is used, then discuss the role of +the editor or collaborative document-manager.

+
+
+

Collaborative document mechanics and controls

+

Technologies that can be used as a collaborative document are Hackmd, HedgeDoc, +or Google Docs

+

Hackmd or HedgeDoc are real-time text editor online. We use it to:

+
    +
  • As a threaded chat, to answer questions and provide other information without +interrupting the main flow of the room.

  • +
  • provide everyone with a more equal opportunity to ask questions.

  • +
  • create notes which will be archived, for your later reference.

  • +
+

You do not need to login/create an account to be able to edit the document.

+
+

Basic controls

+
+../_images/hackmd--controls.png +
+

This may look slightly different on mobile devices and small windows.

+
+
+
    +
  • At the top (left or right), you can switch between view, +edit, and split view and edit modes.

  • +
  • You write in markdown here. Don’t +worry about the syntax, just see what others do and try to be like +that! Someone will come and fix any problems there may be.

  • +
  • Please go back to view mode if you think you won’t edit for a +while - it will still live update.

  • +
+
+
+

Asking questions

+

Always ask questions and add new sections at the very bottom. +You can also answer and comment on older questions, too.

+
+../_images/hackmd--questions2.png +
+

Questions and answers in bullet points

+
+
+

Since we plan to publish the questions and answers later as part +of the workshop page, we recommend to not use any names. You can indicate +your own name to make it easier to discuss more during the workshop but +then always use this form: [name=Myname]. This makes it easier for +us to automatically remove all names before publishing the notes.

+

Other hints:

+
    +
  • Use +1 to agree with a statement or question (we are more likely +to comment on it).

  • +
  • Please leave some blank lines at the bottom

  • +
  • NOTE: Please don’t “select all”, it highlights for everyone and adds a +risk of losing data (there are periodic backups, but not instant).

  • +
  • It can be quite demanding to follow the collaborative document closely. Keep an eye +on it, but consider how distracted you may get from the course. For +things beyond the scope of the course, we may come back and answer +later.

  • +
+
+
+

Don’t get overwhelmed

+

There can be a flood of information on the collaborative document. Scan for what is +important, then if you would like come back later. But it is +important to keep checking it.

+
+
+

Privacy

+
    +
  • Assume the collaborative document is public and published: you never +need to put your name there.

  • +
  • The collaborative document will be published on the website afterwards. We will +remove all non-instructors names, but it’s easier if you don’t add +it there in the first place.

  • +
  • Please keep the link private during the workshop, since since +security is “editable by those who have the link”.

  • +
  • You can use [name=YOURNAME], to name yourself. We will remove +all names (but not the comments) before archiving the notes (use +this format to make it easy for us).

  • +
+
+
+
+

Exercise

+
+

Discuss how to collaborate and handle questions (15 min)

+

Write down your conclusions in the shared document. Items to discuss are:

+
    +
  • What is your experience with questions and discussions while teaching?

  • +
  • How do you deal with them?

  • +
  • What kind of technologies do you prefer: chat, shared document, or voices +and discussion raised during instruction? And why?

  • +
+
+
+
+

Collaborative Document Manager

+

We have one person who is a “Collaborative Document helper”. This isn’t the only +person that should edit and answer, but one person shouldn’t have too +much else on their mind so can focus on it. They also make sure that +the collaborative document is updated with exercise, break, and other meta-information to +keep people on track.

+

Below, (*) = important.

+
+

Before the workshop

+
    +
  • Create a new collaborative document for the workshop

  • +
  • make sure that editing is enabled for anyone without login

  • +
  • Add workshop information, links to the workshop page and material +and an example question and answer to the top of the collaborative document(see below)

  • +
+
+
+

Most things to edit (everyone)

+

Make it easy to post after the course and consistent to follow:

+
    +
  • Tag all names with [name=XXX] (so they can be removed later), +remove other personal data or make it obvious.

  • +
  • Add in information on exercises (new section for them, link, end +time, what to accomplish)

  • +
  • Make a logical section structure (# for title, ## for sections, +### for episodes, etc. - or what makes sense)

  • +
+
+
+

General Collaborative Document practices

+
+../_images/hackmd--full-demo.png +
+

A live demo of a Collaborative Document during a Q&A time. The two instructors are +discussing some of the import answers. Multiple learners have asked +questions, multiple answers, and some remaining to be answered

+
+
+

Keep it formatted well:

+
    +
  • (*) Tag names you see with [name=XXX] so that we can remove it +later.

  • +
  • Heading level # is only the page title

  • +
  • Add a new ## heading when a new lesson or similar thing is +started (introduction, icebreaker, break between lessons, etc)

  • +
  • Add a new ### heading when a new episode, exercise, break +(within exercise session)

  • +
  • Ensure people are asking questions at the bottom, direct them there +if they aren’t.

  • +
  • (*) Ensure each question is a bullet point. Each answer or follow-up +should be a bullet point below.

    +
      +
    • Should you use more deeply nested bullet points, or have only one +level below the initial question? It depends on the context, but +if a conversation goes on too long, try not to let it go too +deep.

    • +
    +
  • +
+

Update with meta-talk, so that learners can follow along easily:

+
    +
  • Add Icebreaker and introductory material of the day. Try to talk to +people as they joined to get them to open the collaborative document and answer.

  • +
  • Anything important for following along should not be only said via +voice. It needs to be in the collaborative document, too.

  • +
  • New lessons or episodes, with links to them.

  • +
  • For exercises, link to exercise and add the duration, end time, +goals. If these are unclear, bring it up to the instructor by voice.

  • +
  • Add a status display about breaks.

  • +
+

Screenshare it when necessary:

+
    +
  • During breaks and other times, share the collaborative document(including the +notification about break, and when it ends).

  • +
  • It is nice if the arrangement allows some of the latest questions to +be seen, so people are reminded to ask there.

  • +
  • Someone else may do this, but should make sure it happens.

  • +
+

Answer questions

+
    +
  • If there is an question that should be answered by the instructor by +voice, bring it up (by voice) to the instructor immediately.

  • +
  • How soon do you answer questions? Two points of view:

    +
      +
    • Answer questions right away: can be really intense to follow.

    • +
    • Wait some so that we don’t overload learners: reduces the info +flow. But then do people need to check back more often.

    • +
    • You need to find your own balance. Maybe a quick answer right +away, and more detailed later. Or delay answers during the most +important parts of the lecture.

    • +
    +
  • +
  • Avoid wall-of-text answers. If reading an answer takes too long, it +puts the person (and other people who even try to read it) behind +even more by taking up valuable mental energy. If an answer needs a +wall of text, consider these alternatives:

    +
      +
    • Progressive bullet points getting more detailed (first ones +useful alone for basic cases)

    • +
    • Don’t be worried to say “don’t worry about this now, let’s talk +later.”

    • +
    • Figure out the root problem instead of answering every possible +interpretation

    • +
    • Declare it advanced and that you will come back later.

    • +
    +
  • +
+

Ensure it can be posted quickly:

+
    +
  • The collaborative document gets posted to the workshop webpage. For this, it needs some +minimal amount of formatting (it doesn’t need to be perfect, just +not horrible).

  • +
  • All names and private information needs to be stripped. This is why +you should rigorously tag all names with [name=XXX] so they can be +removed (see above).

    +
      +
    • Learner names can be completely removed. CR staff names can be +[name=CR] or something similar.

    • +
    • There may be other private URLs at the top or bottom.

    • +
    +
  • +
  • If possible, send the PR adding the collaborative document to the workshop webpage +(though others can do this, too).

  • +
+
+
+

Collaborative document format example

+
# Workshop, day 1
+
+
+## Lesson name
+https://coderefinery.github.io/lesson/
+
+### Episode name
+https://coderefinery.github.io/01-episode/
+
+- This is a question
+  - Anwser
+  - More detailed answer
+- question
+  - answer
+
+### Exercises:
+https://link-to-exercise/.../.../#section
+20 minutes, until xx:45
+Try to accomplish all of points 1-3.  Parts 4-5 are optional.
+
+Breakout room status:
+- room 2, need help with Linux permissions
+- room 5, done
+
+### Break
+:::danger
+We are on a 10 minute break until xx:10
+:::
+
+
+## Lesson 2
+https://coderefinery.github.io/lesson-2/
+
+
+
+
+
+

Posting the collaborative document to the website

+

The collaborative document should be posted sooner rather than later, and hopefully the +steps above will make it easy to do so quickly. You could wait a few +hours, to allow any remaining questions to be asked an answered.

+
    +
  • Download as markdown

  • +
  • Remove any private links at the top

  • +
  • Adjust headings so that they are reasonable

  • +
  • Look for private info and remove it

    +
      +
    • Search document for [name=???] (change to [name=staff] or +[name=learner])

    • +
    • Any names not tagged with [name=]

    • +
    • usernames in URLs

    • +
    • private links

    • +
    +
  • +
+
+
+

Feedback template

+
## Feedback, day N
+
+:::info
+### News for day N+1
+- .
+- .
+:::
+
+### Today was (multi-answer):
+- too fast: 
+- just right: 
+- too slow: 
+- too easy: 
+- right level: 
+- too advanced: 
+- I would recommend this course to others: 
+- Exercises were good: 
+- I would recommend today to others: 
+- I wouldn't recommend today: 
+
+### One good thing about today:
+- ...
+- ...
+
+### One thing to be improved for next time:
+- ...
+- ...
+
+### Any other comments:
+- ...
+- ...
+
+
+
+

Keypoints

+
    +
  • Having a collaborative document improves communication and interaction.

  • +
  • Answering questions requires a dedicated person - A Collaborative Document Manager.

  • +
  • The collaborative document should be posted on the web site as soon as possible.

  • +
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/computational-thinking/index.html b/computational-thinking/index.html new file mode 100644 index 0000000..26bd609 --- /dev/null +++ b/computational-thinking/index.html @@ -0,0 +1,189 @@ + + + + + + + Computational thinking — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Computational thinking

+
+

Objectives

+
    +
  • Explain what is computational thinking

  • +
  • Get to know how the theory of computational thinking can be used in teaching

  • +
  • Short exercise

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 10 min

  • +
+
+

Materials available as slides.

+
+

Keypoints

+
    +
  • Computational Thinking consists of 4 main parts: decomposition, pattern recognition, abstraction and algorithmic design.

  • +
  • How can this be a useful framework for solving problems?

  • +
  • How can this be used practically?

  • +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/cool-gems/index.html b/cool-gems/index.html new file mode 100644 index 0000000..d173047 --- /dev/null +++ b/cool-gems/index.html @@ -0,0 +1,181 @@ + + + + + + + Sharing teaching gems — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Sharing teaching gems

+
+

Objectives

+
    +
  • Our goal is to share our teaching tricks and tools and demonstrate them in +very short presentations/discussions.

  • +
+
+
+

Instructor note

+
    +
  • Demonstrations: 35 min

  • +
+
+

Here we encourage participants to take the screen share for 3 minutes and +demonstrate either some tool or trick they found useful for their teaching or +something from a course you liked.

+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/feedback-and-impact/index.html b/feedback-and-impact/index.html new file mode 100644 index 0000000..37a1f37 --- /dev/null +++ b/feedback-and-impact/index.html @@ -0,0 +1,421 @@ + + + + + + + How we collect feedback and measure impact — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

How we collect feedback and measure impact

+
+

Objectives

+
    +
  • Discuss how one can collect feedback from learners (“what can we improve?”).

  • +
  • Discuss how we convert feedback into actionable items.

  • +
  • Discuss how we measure the impact of teaching (“did we achieve our goals?”).

  • +
  • Discuss the “why”.

  • +
  • Get to know the reasons and sources of inspiration behind major lesson and workshop updates.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 20 min

  • +
  • Exercises: 10 min

  • +
+
+
+

Asking questions before the workshop

+ +
+
+

Collecting feedback as we teach

+
    +
  • Each day we ask for feedback in the collaborative notes.

    +
      +
    • One good thing about today.

    • +
    • One thing to improve for next time.

    • +
    • Any other comments?

    • +
    +
  • +
  • During the workshop we sometimes check in and ask about the pace, example:

    +
    How is the speed so far? (add an "o")
    +- Too fast:   oooooo
    +- Too slow:   ooo
    +- Just right: ooooooooooooooooooo
    +
    +
    +
  • +
  • We publish all questions, answers, and feedback. Example: https://coderefinery.github.io/2024-03-12-workshop/questions/

  • +
  • How we follow up:

    +
      +
    • Some problems we can fix already before the next workshop day.

    • +
    • We convert feedback/problems into GitHub issues and track these close to the lesson material.

    • +
    +
  • +
+
+
+

Trying to measure impact with longer-term surveys

+ +
+
+

Lessons learned

+
    +
  • Think about how to measure impact/success from the beginning.

  • +
  • Make the feedback and survey results public.

  • +
  • Make the results persistent and citable.

  • +
  • Have a mechanism to follow-up on feedback.

  • +
  • Anonymization is more than just removing or dissociating names.

  • +
  • Take time designing your survey and collect feedback on the survey itself.

  • +
+
+
+

Take time designing your survey

+

We are not experts in survey design but we reached out to RISE Research +Institutes of Sweden to get feedback on our survey questions. They provided us +with a lot of valuable feedback and suggestions for improvements. +Below are few examples.

+
+

Example 1

+

First version of our survey question about impact:

+
    +
  • “Do our workshops help to save time in future?” Please quantify in hours saved: …

  • +
+

Feedback:

+
    +
  • Difficult to answer.

  • +
  • Since when? Until all eternity?

  • +
+
+Screenshot of earlier version of the survey question about impact. +
+

Earlier version of the survey question about impact.

+
+
+

Feedback:

+
    +
  • The question “Do our workshops help to save time in future?” is unspecified, +unnecessary, and leading.

  • +
  • “No time saving” does not match the wording “save time” in the question.

  • +
+
+Screenshot of later version of the survey question about impact. +
+

Later version of the survey question about impact.

+
+
+
    +
  • The wording “have you saved” now matches “No time saved”.

  • +
+
+
+

Example 2

+
    +
  • Earlier version:

    +
    Would you judge your code to be better reusable/reproducible/modular/documented
    +as a result of attending the workshop?
    +
    +- More reusable
    +- More reproducible
    +- More modular
    +- Better documented
    +- None of the above
    +
    +
    +
  • +
  • Feedback: The question is not neutrally formulated and risks leading to +over-reporting of yes answers. Consider balancing so that the questions are +formulated more neutrally.

  • +
  • Reformulated to:

    +
    After attending the workshop, would you judge your code to be
    +more reusable or not more reusable?
    +
    +- My code is more reusable
    +- My code is not more reusable
    +- Not sure
    +
    +
    +
  • +
+
+
+

Example 3

+
    +
  • Early version:

    +
    What else has changed in how you write code since attending the workshop?
    +
    +[free-form text field]
    +
    +
    +
  • +
  • Feedback: Leading and assumes that something has changed.

  • +
  • Reformulated to:

    +
    Has anything else changed in how you write code for your research after
    +attending the workshop?
    +
    +[free-form text field]
    +
    +
    +
  • +
+
+
+

Example 4

+
    +
  • Earlier version:

    +
    Has it become easier for you to collaborate on software development with your
    +colleagues and collaborators?
    +
    +- Yes
    +- Not sure
    +- No
    +
    +
    +
  • +
  • Feedback:

    +
      +
    • Leading question.

    • +
    • Avoid “Yes” and “No” response options because respondents tend to answer +“Yes” if that option is available, leading to a risk of measurement error +(acquiescence bias).

    • +
    • Do not place “Not sure” in the middle of the scale because it captures +participants who actually don’t know and should therefore be placed at the +bottom instead of in the middle of the scale.

    • +
    +
  • +
  • Reformulated to:

    +
    After attending the workshop, has it become easier or not for you to
    +collaborate on software development with your colleagues and collaborators?
    +
    +- Collaboration is easier
    +- Collaboration is not easier
    +- Not sure
    +
    +
    +
  • +
+
+
+
+

Exercise: Group discussion (10 min)

+
+

Group discussion using the collaborative notes

+
    +
  • What tricks/techniques have you tried in your teaching or seen in someone +else’s teaching that you think have been particularly effective in collecting +feedback from learners?

  • +
  • Can you give tips or share your experiences about how to convert feedback +into actionable items?

  • +
  • How do you measure the impact of your teaching? Any tips or experiences about +what you have tried or seen other courses do?

  • +
  • Anybody knows of good resources on survey design? Please link them in +the collaborative notes.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/genindex/index.html b/genindex/index.html new file mode 100644 index 0000000..4e3dc6b --- /dev/null +++ b/genindex/index.html @@ -0,0 +1,170 @@ + + + + + + Index — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/guide/index.html b/guide/index.html new file mode 100644 index 0000000..9586f8a --- /dev/null +++ b/guide/index.html @@ -0,0 +1,260 @@ + + + + + + + Instructor guide — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Instructor guide

+
+

Target audience

+
    +
  • Everyone teaching online workshops about computational topics or interested in teaching.

  • +
  • Previous and future instructors and helpers of CodeRefinery workshops.

  • +
+
+
+

Timing

+

Session 1

+
    +
  • 15 min: Intro

  • +
  • 45 min: Lesson design and development

  • +
  • 15 min: Break

  • +
  • 45 min: Lesson template

  • +
  • 15 min: Break

  • +
  • 30 min: How we collect feedback and measure impact

  • +
  • 10 min: Outro and feedback

  • +
+

Session 2

+
    +
  • 15 min: Intro

  • +
  • 10 min: About the CodeRefinery project and CodeRefinery workshops in general

  • +
  • 30 min: Collaborative notes and interaction

  • +
  • 15 min: Break

  • +
  • 35 min: Workshop overview, roles, onboarding/installation, helpers

  • +
  • 20 min: Sound

  • +
  • 15 min: Break

  • +
  • 30 min: Screenshare

  • +
  • 10 min: Outro and feedback

  • +
+

Session 3

+
    +
  • 15 min: Intro

  • +
  • 30 min: Computational thinking

  • +
  • 15 min: Break

  • +
  • 30 min: Teaching philosohies

  • +
  • 30 min: Co-teaching

  • +
  • 15 min: Break

  • +
  • 35 min: Sharing teaching tips, tricks, tools etc

  • +
  • 10 min: Outro and feedback

  • +
+

Session 4

+
    +
  • 15 min: Intro

  • +
  • 10 min: Why we stream

  • +
  • 20 min: Behind the stream

  • +
  • 15 min: Video editing (part 1)

  • +
  • 15 min: Break

  • +
  • 25 min: Video editing (part 2, exercise)

  • +
  • 20 min: OBS introduction

  • +
  • 15 min: Break

  • +
  • 30 min: OBS setup

  • +
  • 15 min: What’s next?

  • +
+
+
+

Talking points for each sessions intro

+
    +
  • Brief CodeRefinery intro

  • +
  • Instructors intros

  • +
  • Notes intro

    +
      +
    • Check-in

    • +
    • Icebreaker

    • +
    • Participant intros in breakoutrooms (Random assign first, then same for whole session)

    • +
    +
  • +
  • Daily schedule, learning objectives

  • +
  • Code of conduct

  • +
  • Chat (please use collaborative notes)

  • +
+
+
+

Participant preparations for each session

+

Copied from e-mail communication with participants before each session.

+

Session 1: +In general you will only need your brain for the exercises and discussions, but some will have the option to go deeper, which may require some accounts or tools to be set-up. We will inform about these things the week before each session.

+

For Session 1 we recommend to have a GitHub account (https://coderefinery.github.io/installation/github/#github). There will be an optional exercise where you can build a lesson locally. This requires a basic Python environment (https://github.com/coderefinery/sphinx-lesson-template/blob/main/requirements.txt), but do not worry if you cannot or do not want to set up these, there will be plenty of other exercises.

+

Session 2: +In general you will only need your brain for the exercises and discussions. To get the most out of this workshop day we recommend that you join the session with the same computer, display and microphone setup as you would usually use for teaching/ presenting. It may also help to get familar with the different options your computer and Zoom setup provides for screenshare and audio adjustments. +But it is not a must.

+

Session 3: +In general you will only need your brain for the exercises and discussions. If you want to share some “cool gem” in the last episode of this workshop day, please update your registration (link to edit can be found in the registration confirmation e-mail sent by support@coderefinery.org or noreply@neic.org). This is very low barrier, you do not have to be the developer of a tool or technique to share with the group what makes it useful for you; and it does not even have to be cool, sometimes the small “normal” things are the best. You can check out some topics that have been proposed so far in this GitHub issue (#90), you can also comment there if you want to add or change your topic. These will be lightning talk length, so something between 2-5 min depending on how many are interested to share something, but we can collect them all in the collaborative notes for further exploration/reading. +But it is not a must.

+

Session 4: +This upcoming session (session number 4) will cover the technical aspects of CodeRefinery-style online teaching. These topics have never before been covered in this much detail, so if it’s interesting to you, don’t miss it. (You might also want to pass this on to others who are interested in technical production of online events; registration is still open!).

+

First, we talk about why we stream (how we got here, advantages, disadvantages, how to be an instructor in a livestreamed workshop, and what it looks like from a broad level from the production side)

+

Then, we show how we are able to release videos so quickly. This is useful far beyond CodeRefinery, and there are also some hands-on exercises. Come prepared to set up a Python environment and the ffmpeg command line tool if you want to try these.

+

Finally, we see details about how to set up Zoom→Livestream environment for yourself. There isn’t time to do this as a proper exercise, but it’s the starting point and the instructor will offer help after the course for those interested. If you want to try this out during the session, install OBS Studio in advance.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..b00b341 --- /dev/null +++ b/index.html @@ -0,0 +1,275 @@ + + + + + + + Train the trainer workshop — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Train the trainer workshop

+
+

August/September 2024 CodeRefinery train the trainer workshop

+

Do you teach the use of computers and computational tools? Are you curious about scaling your training and learn about tested and proven practices from CodeRefinery workshops and other trainers? Join us for the CodeRefinery train the trainer workshop: four self-contained sessions on tools and techniques for computational training offer a great chance to enhance your teaching skills and learn about new tools and practices. What you will learn is also used a lot outside CodeRefinery, whenever good beginner friendly training is needed.

+

Learning objectives:

+
    +
  • Learn about tools and techniques and practice to create engaging online teaching experiences (screenshare, audio, etc.).

  • +
  • Become mentally ready to be an instructor in a collaborative interactive online workshop (not only large workshops but in general).

  • +
  • Learn how to design and develop lesson material collaboratively.

  • +
+

Target audience:

+
    +
  • Everyone teaching online workshops about computational topics or interested in teaching.

  • +
  • Previous and future instructors and helpers of CodeRefinery workshops.

  • +
+

Prerequisites: +An interest in teaching.

+

Workshop structure: +We aim for a mix of modular presentations and work in small groups. The latter will be done in breakoutrooms - +be prepared to switch on your camera and have a fruitful exchange with fellow participants!

+

Organizers and instructors:

+

The workshop is organized by partner organizations of the CodeRefinery project.

+

Facilitators and instructors:

+
    +
  • Radovan Bast

  • +
  • Richard Darst

  • +
  • Bjørn Lindi

  • +
  • Dhanya Pushpadas

  • +
  • Jarno Rantaharju

  • +
  • Stephan Smuts

  • +
  • Stepas Toliautas

  • +
  • Samantha Wittke

  • +
+

Content and timing:

+

The workshop consists of four sessions every Tuesday between August +13th and September 3rd 2024, + to +:

+
    +
  • Session 1: About lesson design, deployment and iterative improvement (Aug 13)

  • +
  • Session 2: Tools and techniques adopted in CodeRefinery workshops (Aug 20)

  • +
  • Session 3: About teaching & cool things we all would like to share (Aug 27)

  • +
  • Session 4: Workshop streaming practices and post-workshop tasks (Sep 3)

  • +
+

You can join all sessions, or the just the ones that interest you. More details on each session will be shared later.

+

The workshop is free of charge for everyone, please register below to get the Zoom link and other useful information for the workshop.

+

The workshop is over and registration is closed now.

+

If you have any questions, please write to support@coderefinery.org.

+
+ + + + + +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/lesson-development/index.html b/lesson-development/index.html new file mode 100644 index 0000000..ba986b1 --- /dev/null +++ b/lesson-development/index.html @@ -0,0 +1,424 @@ + + + + + + + Lesson design and development — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Lesson design and development

+
+

Objectives

+
    +
  • We share our design processes for teaching material and presentations.

  • +
  • Learn how to design lessons “backwards”, starting from learning objectives +and learner personas.

  • +
  • Learn good practices for improving existing material based on feedback.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 20 min

  • +
  • Exercises: 35 min

  • +
+
+
+

Exercise: How do you design your teaching material?

+
+

We collect notes using a shared document (5 min)

+
    +
  • When you start preparing a new lesson or training material, where do you start?

  • +
  • What tricks help you with “writer’s block” or the empty page problem?

  • +
  • Maybe you haven’t designed training material yet. But how do you start when creating a new presentation?

  • +
  • If your design process has changed over time, please describe what you used to do and what you do now instead.

  • +
  • What do you know now about preparing lessons/training/presentations that you wish you knew earlier?

  • +
+
+
+
+

Creating new teaching material

+
+

Typical problems

+
    +
  • Someone creates a lesson, but they think about what is interesting to them, +not what is important for the learners.

  • +
  • “I want to show a number of things which I think are cool about +tool X - how do I press these into 90 minutes?”

  • +
  • Write down material you want to cover and then sprinkle in some exercises.

  • +
  • Thinking about how I work, not how the learners work.

  • +
  • Trying to bring learners to their level/setup, not trying to meet the learners +where they are.

  • +
  • Not really knowing the learning objectives or the learner personas.

  • +
+
+
+

Better approach

+

Good questions to ask and discuss with a group of colleagues from diverse backgrounds:

+
    +
  • What is the expected educational level of my audience?

  • +
  • Have they been already exposed to the technologies I am planning to teach?

  • +
  • What tools do they already use?

  • +
  • What are the main issues they are currently experiencing?

  • +
  • What do they need to remember/understand/apply/analyze/evaluate/create +(Bloom’s taxonomy)?

  • +
  • Define learner personas.

  • +
  • It may be an advantage to share an imperfect lesson with others early to +collect feedback and suggestions before the lesson “solidifies” too much. +Draft it and collect feedback. The result will probably be better than +working in isolation towards a “perfect” lesson.

  • +
+
+
+

The process of designing a lesson “backwards”

+

As described in “A lesson design process” in the book Teaching Tech +Together:

+
    +
  1. Understand your learners.

  2. +
  3. Brainstorm rough ideas.

  4. +
  5. Create an summative assessment to know your overall goal.

    +
    +

    [Think of the things your learners will be able to do at the end of the lesson]

    +
    +
  6. +
  7. Create formative assessments to go from the starting point to this.

    +
    +

    [Think of some engaging and active exercises]

    +
    +
  8. +
  9. Order the formative assessments (exercises) into a reasonable order.

  10. +
  11. Write just enough material to get from one assessment (exercise) to +another.

  12. +
  13. Describe the course so the learners know if it is relevant to them.

  14. +
+
+
+
+

Improving existing lessons

+
+

All CodeRefinery lessons are on GitHub

+ +
+

Collect feedback during the workshop:

+
    +
  • Collect feedback from learners and instructors (Example from a past +workshop).

  • +
  • Convert feedback about lessons and suggestions for improvements into issues +so that these don’t get lost and stay close to the lesson material.

  • +
+

Collect feedback before you start a big rewrite:

+
    +
  • First open an issue and describe your idea and collect feedback before you +start with an extensive rewrite.

  • +
  • For things still under construction, open a draft pull/merge request to collect +feedback and to signal to others what you are working on.

  • +
+

Small picture changes vs. big picture changes:

+
    +
  • Lesson changes should be accompanied with instructor guide changes (it’s like +a documentation for the lesson material).

  • +
  • Instructor guide is essential for new instructors.

  • +
  • Before making larger changes, talk with somebody and discuss these changes.

  • +
+
+
+

Use case: our lessons

+

As an example to demonstrate the process of designing and improving lessons, we +will have a look at one of our own lessons: Introduction to version control +with Git.

+
    +
  • Initial 2014-2016 version

    + +
  • +
  • Some time in 2014-2015 attended Carpentries instructor training.

  • +
  • 2016: CodeRefinery started.

  • +
  • 2017: Started a new repository based on the Carpentries lesson template (at the time using Jekyll).

    +
      +
    • Exercises become part of the lesson.

    • +
    • We start in the command line and only later move to GitHub.

    • +
    +
  • +
  • 2019: A lot more thought about learning objectives and personas.

    +
      +
    • Also license change to CC-BY.

    • +
    +
  • +
  • 2022: Convert lesson from Jekyll to Sphinx.

    +
      +
    • Using the tools that we teach/advocate.

    • +
    • We can have tabs and better code highlighting/emphasis.

    • +
    • Easier local preview (Python environment instead of Ruby environment which we were not used to in our daily work).

    • +
    +
  • +
  • 2024: Big redesign. We move the lesson closer to where learners are.

    +
      +
    • Start from GitHub instead of on the command line.

    • +
    • Start from an existing repository instead of with an empty one.

    • +
    • Offer several tracks to participate in the lesson (GitHub, VS Code, and command line) and learners can choose which one they want to follow.

    • +
    • Blog post: We have completely changed our Git lessons. Hopefully to the better.

    • +
    +
  • +
  • Next steps?

    +
      +
    • Making the lesson citable following +our blog post.

    • +
    • Improvements based on what we learn from this workshop.

    • +
    +
  • +
+

The overarching trend was to make the lesson simpler and more accessible - to +meet the learners where they are instead of pulling them to the tool choices of +the instructors. Looking back, we learned a lot and the learning process is +not over yet.

+
+
+

Exercise: Discussion about learning objectives and exercise design

+
+

We work in groups but use the shared document as result (20 min)

+
    +
  1. As a group pick a lesson topic. It can be one of the topics listed here but +you can also choose something else that your group is interested in, or a topic +that you have taught before or would like to teach. Some suggestions:

    +
      +
    • Git: Creating a repository and porting your project to Git and GitHub

    • +
    • Git: Basic commands

    • +
    • Git: Branching and merging

    • +
    • Git: Recovering from typical mistakes

    • +
    • Code documentation

    • +
    • Jupyter Notebooks

    • +
    • Collaboration using Git and GitHub/GitLab

    • +
    • Using GitHub without the command line

    • +
    • Project organization

    • +
    • Automated testing

    • +
    • Data transfer

    • +
    • Data management and versioning

    • +
    • Code quality and good practices

    • +
    • Modular code development

    • +
    • How to release and publish your code

    • +
    • How to document and track code dependencies

    • +
    • Recording environments in containers

    • +
    • Profiling memory and CPU usage

    • +
    • Strategies for parallelization

    • +
    • Conda environments

    • +
    • Data processing using workflow managers

    • +
    • Regular expressions

    • +
    • Making papers in LaTeX

    • +
    • Making figures in your favorite programming language

    • +
    • Linux shell basics

    • +
    • Something non-technical, such as painting a room

    • +
    • Introduction to high-performance computing

    • +
    • A lesson you always wanted to teach

    • +
    • +
    +
  2. +
  3. Try to define 2-3 learning objectives for the lesson and write them down. +You can think of these as “three simple enough messages that someone will +remember the next day” - they need to be pretty simple.

  4. +
  5. Can you come up with one or two engaging exercises that could be used to +demonstrate one of those objectives? +They should be simple enough people can actually do them. Creating simple exercises is not easy. +Some standard exercise types:

    +
      +
    • Multiple choice (easy to get feedback via a classroom tool - try to design each wrong answer so that it identifies a specific misconception).

    • +
    • Code yourself (traditional programming)

    • +
    • Code yourself + multiple choice to see what the answer is (allows you to get feedback)

    • +
    • Inverted coding (given code, have to debug)

    • +
    • Parsons problems (working solution but lines in random order, learner must only put in proper order)

    • +
    • Fill in the blank

    • +
    • Discussions, self directed learning exercises

    • +
    +
  6. +
+
+
+
+

Great resources

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/lesson.pdf b/lesson.pdf new file mode 100644 index 0000000..eab5b37 Binary files /dev/null and b/lesson.pdf differ diff --git a/lessons-with-git/index.html b/lessons-with-git/index.html new file mode 100644 index 0000000..01601a5 --- /dev/null +++ b/lessons-with-git/index.html @@ -0,0 +1,433 @@ + + + + + + + Lessons with version control — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Lessons with version control

+
+

Objectives

+
    +
  • Understand why version control is useful even for teaching material

  • +
  • Understand how version control managed lessons can be modified.

  • +
  • Understand how the CodeRefinery lesson template is used to create new lessons

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 25 min

  • +
  • Exercises or demos: 20 min

  • +
+
+
+

Why version control?

+
    +
  • If you are in CodeRefinery TTT, you probably know what version +control is and why it is important.

  • +
  • The benefits of version control also extend to lessons:

    +
      +
    • Change history

    • +
    • Others can submit contributions

    • +
    • Others can make derived versions and sync up later

    • +
    • Same workflow as everything else

    • +
    • Write it like documentation: probably more reading after than +watching it as a presentation.

    • +
    +
  • +
  • Disadvantages

    +
      +
    • “What you see is what you get” editing is hard

    • +
    • Requires knowing version control

    • +
    +
  • +
+
+

Accepting the smallest contribution

+

Question: if someone wants to make a tiny fix to your material, can they?

+
+
+
+

Tour of lesson templates options

+

There are different ways to make lessons with git. Some dedicated to +teaching:

+ +

Our philosophy is that anything works: it doesn’t have to be just +designed for lessons

+
    +
  • Jupyter Book

    +
      +
    • Example: https://jupyterbook.org/

    • +
    • Note: is based on sphinx, many extensions here are used in CR lessons

    • +
    +
  • +
  • Various ways to make slides out of Markdown

  • +
  • Cicero: GitHub-hosted Markdown to slides easily

    + +
  • +
  • Whatever your existing documentation is.

  • +
+

We like the CodeRefinery format, but think that you should use +whatever fits your needs the most.

+
+
+

Sphinx

+
    +
  • We build all our lesson material with Sphinx

  • +
  • Generate HTML/PDF/LaTeX from RST and Markdown.

  • +
  • Many Python projects use Sphinx for documentation but Sphinx is not limited to Python.

  • +
  • Read the docs hosts public Sphinx documentation for free!

  • +
  • Also hostable anywhere else, like Github pages, like our lesson material

  • +
  • For code a selling point for Sphinx is that also API documentation +is possible.

  • +
+

Sphinx is a doc generator, not HTML generator. It can:

+
    +
  • Markdown, Jupyter, and ReST (and more…) inputs. Executable inputs.

    +
      +
    • jupyter-book is Sphinx, so anything it can do we can do. This was one of the +inspirations for using Sphinx

    • +
    +
  • +
  • Good support for inline code. Much more than static code display, if +you want to look at extensions.

  • +
  • Generate different output formats (html, single-page html, pdf, epub, etc.)

  • +
  • Strong cross-referencing within and between projects

  • +
+
+
+

CodeRefinery lesson template

+

It is “just a normal Sphinx project” - with extensions:

+
    +
  • Sphinx lesson extension

    +
      +
    • adds is various directives (boxes) tuned to lesson purposes

    • +
    • provides a sample organization and template repo you can use so that lessons look consistent

    • +
    +
  • +
  • Sphinx gives us other nice features for free

    +
      +
    • Tabs: they are very important for us and allow us to customize in-place instead of copying everything and fragmenting lessons

    • +
    • Emphasize lines: they make it easier to spot what has changed in longer code snippets

    • +
    • Various input formats

      +
        +
      • Markdown (via the MyST-parser), ReStructured text, Jupyter +Notebooks.

      • +
      +
    • +
    • Many other features designed for presenting and interacting with code

    • +
    +
  • +
  • It’s fine if you use some other static site generator or git-based lesson method.

  • +
+
+

Instructors go through the building and contributing process

+

Depending on the course, instructors will demo what is roughly +exercise 4 below. Or a course might go straight to exercises.

+
    +
  • Instructors decide what change they would want to make

  • +
  • Instructors clone the repository

  • +
  • Instructors make the change

  • +
  • Instructors set up the build environment

  • +
  • Instructors build and preview

  • +
  • Instructors command and send upstream

  • +
+
+
+
+

Exercises

+

Some exercises have prerequisites (Git or Github accounts). Most +instances of this course will have you do 1 and 2 below.

+
+

Lesson-VCS-1: Present and discuss your own lesson formats

+

We don’t want to push everyone towards one format, but as long as you +use Git, it’s easy to share and reuse.

+
    +
  • Discuss what formats you do use

  • +
  • Within your team, show examples of the lessons formats you use +now. Discuss what is good and to-be-improved about them.

  • +
  • Look at how they source is managed and how easy it might be to edit.

  • +
+
+
+

Lesson-VCS-2: Tour a CodeRefinery or Carpentries lesson on Github

+
    +
  • Look at either a CodeRefinery or Carpentries lesson

    + +
  • +
  • Can you find

    +
      +
    • Where is the content of the lessons?

    • +
    • What recent change propsals (pull requests) have been made?

    • +
    • What are the open issues?

    • +
    • How you would contribute something?

    • +
    • How would you use this yourself?

    • +
    +
  • +
+
+
+

Lesson-VCS-3: Modify a CodeRefinery example lesson on Github

+

In this, you will make a change to a lesson on Github, using only the +Github interface. (Github account required, and we assume some +knowledge of Github. Ask for help in your team if it is new to you!)

+
    +
  • Navigate to the example lesson we have set up: +repo, web

  • +
  • Go to some page and follow the link to go to the respective page on +Github. (Alternatively, you can find the page from the Github repo directly).

  • +
  • Follow the Github flow to make a change, and open a Pull Request +with the change proposal:

    +
      +
    • Click on the pencil icon

    • +
    • Make a change

    • +
    • Follow the flow to make a commit and change. You’ll fork the +repository to make your own copy, add a message, and open a pull +request.

    • +
    +
  • +
+

We will look at these together and accept some changes.

+
+
+

Lesson-VCS-4: Clone and build a CodeRefinery lesson locally

+

In this exercise, you will use Git to clone one a CodeRefinery lesson +and try to preview it locally. It assumes installation and knowledge +of Git.

+
    +
  • Use this sample repository: +git-intro (or whatever +else you would like)

  • +
  • Clone the repository to your own computer

  • +
  • Create a virtual environment using the requirements.txt +contained within the repository.

  • +
  • Build the lesson.

    +
      +
    • Most people will probably run: sphinx-build content/ _build/

    • +
    • If you have make installed you can make html

    • +
    • Look in the _build directory for the built HTML files.

    • +
    +
  • +
+

Overall, this is pretty easy and straightforward, if you have a Python +environment set up. The CodeRefinery documentation +lesson teaches +this for every operating system.

+

This same tool can be used to build documentation for other software +projects and is pretty standard.

+
+
+

Lesson-VCS-5: (advanced) Create your own lesson using the CodeRefinery format

+

In this lesson, you’ll copy the CodeRefinery template and do basic +modifications for your own lesson.

+
    +
  • Clone the lesson template: +https://github.com/coderefinery/sphinx-lesson-template

  • +
  • Attempt to build it as it is (see the previous exercise)

  • +
  • How can you do tabs?

  • +
  • How can you highlight lines in code boxes?

  • +
  • How can you change color, logo and fonts?

  • +
  • What directives are available?

  • +
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Version control takes teaching materials to the next level: +shareable and easy to contribute

  • +
  • There are different formats that use version control, but we like +Sphinx with a sphinx-lesson extension.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/notes-archive/index.html b/notes-archive/index.html new file mode 100644 index 0000000..084aa0b --- /dev/null +++ b/notes-archive/index.html @@ -0,0 +1,2862 @@ + + + + + + + Collaborative notes archives from workshops — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Collaborative notes archives from workshops

+
+

August/September 2024

+
+

Day1: Session 1 (13.08.24) - About lesson design, deployment and iterative improvement

+
+

:calendar: Schedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 10.00

Lesson design and development

10.15 - 11.00

8.15 - 9.00

10.00 - 10.15

Break

11.00 - 11.15

9.00 - 9.15

10.15 - 11.00

Lessons with version control

11.15 - 12.00

9.15 - 10.00

11.00 - 11.15

Break

12.00 - 12.15

10.00 - 10.15

11.15 - 12.00

How we collect feedback and measure impact

12.15 - 13.00

10.15 - 11.00

+
+
+

:icecream: Icebreaker

+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :Decaffed … and going strong …

  • +
  • :coffee: 🤔

  • +
  • :100: (ironically!) :coffee: intake happening

  • +
  • :smile:

  • +
  • :tired_face:

  • +
  • :coffee: :party:

  • +
  • :coffee: :happy:

  • +
  • 😪

  • +
  • just got zoom installed / before my coffee

  • +
  • :smil-

  • +
  • :sweat_smile: (+)

  • +
  • :yawning_face:

  • +
  • :is it morning already?

  • +
  • :smile:

  • +
  • :yawning_face:

  • +
  • :nerded_face:

  • +
  • 🥵

  • +
  • :smile:

  • +
  • :sleeping:

  • +
  • :sleepy: :coffee: :smiley_cat:

  • +
  • 🥳

  • +
  • :coffee:

  • +
  • :coffee:

  • +
+
+
+
Introduction in breakoutrooms.
+
    +
  • Name / Affiliation / Location

  • +
+
+
+
About teaching
+

What is the hardest thing about teaching for you?

+
    +
  • Knowing how “it’s going”, whether learners are happy or not (especially when teaching online) :+1:

  • +
  • The preparation the night before. It is always much more that I would hope, no matter how prepared I want it to be :+1: :+1:

  • +
  • Managing groups with vastly different academic backgrounds

  • +
  • Teaching wide spectrum of skill level at the same time. :+1: :+1: :+1: :+1:

  • +
  • Time management! (Knowing how much can fit in a sessions) :+1: :+1:

  • +
  • General preparation time, how to fit it into the regular work schedule, and estimate how much time is needed for prep.

  • +
  • How to reduce too much text into just the right amount

  • +
  • Preparation of the session material and estimating the right amount of time for each section

  • +
  • Getting learners to take the first step: sign up for and attend a workshop, when they don’t think programming is a skill they can learn

  • +
  • Getting learners to take the second step: translating what they’ve learned in a workshop into something they can apply

  • +
  • preparation and time management

  • +
  • Engaging with the students which was much easier for me when I used to coach

  • +
  • Finding the right depth for an unknown audience for “my topic”

  • +
  • education background of participants and their learning objectives

  • +
+

What is the best thing about teaching for you?

+
    +
  • Seeing when learner gets interested/curious about something and takes inspiration from the course. :+1:

  • +
  • Seeing it works and someone can do something new.

  • +
  • Motivated students grasping new stuff

  • +
  • Students picking up and running with the matertial and skills I give them and using it for their own work. :+1:

  • +
  • The “ah-ha!” moment when a student gets it! :+1::100: :+1:

  • +
  • Learning from students who know about some topic more than you do. :+1:

  • +
  • Being able to help people reach their goals, by showing them something new.

  • +
  • Teaching is optimism acted out in the hope of making a difference both ways I suppose.

  • +
  • The feeling of accomplishment when you see learning grow and implement the learnings :book:

  • +
  • mutual learning and impact on learners :+1:

  • +
  • Results and feedbacks / Mutual interests and interesting discussions

  • +
  • mutual learning and I can also learn lots of things and new ideas from participants

  • +
+
+
+
+

:question: Questions

+
+
General / Practicalities
+
    +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms? I’m not in a place where I can talk, so if we’re going to talk a lot I’ll need to move offices

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    +
  • +
  • +
+
+
+
Episode 1: Lesson design and development
+

Materials: https://coderefinery.github.io/train-the-trainer/lesson-development/ +Discussion:

+
    +
  • When you start preparing a new lesson or training material, where do you start?

    +
      +
    • I look at existing materials on the same topic, but chose/refine topics based on the perceived needs/interests of the presumed audience

    • +
    • Outline of structure and Material collection for a new lesson :+1:

    • +
    • What material I have already? (what other material is already out there?)

    • +
    • Start by looking for related resources (documents, videos, courses, etc) to have a base data and better understanding of what have been done around the topic

    • +
    • Know your audience

    • +
    • Review existing material

    • +
    • Think about learning objectives (to keep focus on essential things)

    • +
    • Think of three things simple enough that they will be remembered the next day. Design around that.

    • +
    • I write down the thoughts that I have and then go back and structure it.

    • +
    +
  • +
  • What tricks help you with “writer’s block” or the empty page problem?

    +
      +
    • Write anything down that comes to mind, sometimes draw something, looking out the window :)

    • +
    • Do a mind map - what concepts do I want to get across?

    • +
    • Starting small, for example a list of headings and then building around it. :+1:

    • +
    • What does one know about the target audience and why should they be spending longer than 1 minute listening to what they will eventually get to hear?

    • +
    • Get some inspiration from another source.

    • +
    • Start with the three things above

    • +
    • Start with the plan and the overview design

    • +
    • Some kind of outline / main message(s)

    • +
    • Start with three things. Three supporting points for each of these.

    • +
    +
  • +
  • Maybe you haven’t designed training material yet. But how do you start when creating a new presentation?

    +
      +
    • Think about the learning objectives and try to break them down into steps

    • +
    • Title, Objectives, target audience and Plan

    • +
    • Some kind of outline / main message(s). Get as many images as I can, instead of words

    • +
    • Draft an outline and use chatgpt to fill in details

    • +
    • Example of how the teaching content is applied in a real-world context

    • +
    +
  • +
  • If your design process has changed over time, please describe what you used to do and what you do now instead.

    +
      +
    • I look more at existing materials and try to get more information about the audience. Unfortunately getting information about the audience before the event is hard

    • +
    • I used to start from the begginning and get from there but that often meant a very polished start and a rushed end. Now I try an overview first, then fil out sparsed details at every section

    • +
    • Updating the data and tweak the presentation

    • +
    • If I am teaching a small group (or one to one) talk to them before hand - find out what they know already, what they want to learn.

    • +
    +
  • +
  • What do you know now about preparing lessons/training/presentations that you wish you knew earlier?

    +
      +
    • less is more. It’s better to have 2-3 main messages rather than trying to show everything in one go :+1: :+1: :+1: :+1:

    • +
    • how much practice time the learners need to master what’s taught

    • +
    • Don’t worry about something going wrong. It often makes the lesson (and thus the material) more presistent in memory. :+1:

    • +
    • Try and remove everything except what you want the person to learn

      +
        +
      • That’s a very tough part for me in the sense that I never know how much of an underlying “black box” is still ok….

      • +
      +
    • +
    • Designing intermediate materials is hard, and requires putting some “gatekeeping” making sure that learners are directed to appropriate courses

    • +
    • When I see a cool graphic, concept, slide, etc., download it and save it in my ‘new-materials’ folder to use later on!

    • +
    • I have come to the conclusion that perhaps a more “agile” approach to developing materials (try to do design/teaching iterations quickly) might be the best way to go, but there are risks with this approach too

    • +
    +
  • +
+

Questions

+
    +
  • From zoom chat: Can you expand on what a learner persona is?

    +
      +
    • A defined example person described in terms of the materials you are preparing, making up a story about the background and interest of t

    • +
    • Answer from chat: A learner persona is a blackbox which has a very simple algorithm inside: GIGO.

    • +
    • Answer from chat: I think it’s the same as ICP (Ideal customer persona) where you describe the learner as a customer

    • +
    • Answer from chat: I’m a big fan of “How Learning Works” by Ambrose et al https://bookshop.org/p/books/how-learning-works-eight-research-based-principles-for-smart-teaching-michele-dipietro/18640868?ean=9781119861690

    • +
    • See also book: Teaching tech together

    • +
    +
  • +
+
+

CodeRefinery lessons: https://coderefinery.org/lessons/

+
+
    +
  • From chat: Do you have an example of an instructor guide?

    + +
  • +
  • From zoom chat: Do you have a “measure” of how better are the new lesson compared to the old ones? Does it make sense to talk about measurements here?

    +
      +
    • So far we only have daily feedback that we collect at the end of the day and we can compare that to earlier daily feedbacks. More about that in the last episode of today. But measuring this is indeed not easy and it also takes time to capture the effect during longer-term surveys. Some of the changes were more leap-of-faith than based on data.

    • +
    • I guess that sometimes one can use “compelling arguments” instead of data to justify a decision

    • +
    +
  • +
  • Software Carpentry does teach using the command line, and gives a session on the command line before. What do you think about this approach? Are you stating that a 3-hour lesson about CLI is not sufficient to make people comfortable enough to use that for version control?

    +
      +
    • Yes, good question. For CR we consider it a more advanced step: we do think people should learn command line, but it’s for a different course. We accept some people might not know it or want to know it so adapt to that.

    • +
    • In general, we’ve found the “you need X, but have to learn A, B, and C first” approach should be avoided if possible: people are busy, try to reach people where they are.

    • +
    +
  • +
+
+

Exercise in breakoutrooms

+
+
    +
  • Room 1

    +
      +
    • Research data management

    • +
    • Objectives

      +
        +
      • Research life cycle

      • +
      • FAIR principles (Findable, Accessible, Interoperable, Reusable)

      • +
      +
    • +
    • Exercise

      +
        +
      • develop a data management plan (DMP) that outlines how their research data will be handled throughout its lifecycle.

      • +
      +
    • +
    +
  • +
  • Room 2: What is the difference between eating breakfast and sitting through a lecture? (Tip: Start by listing the similarities …)

  • +
  • Room2 : Making papers in LaTeX +- What is LaTex and how is it different from editors like Word +- Basic Structures +- How to find and use a template +- Including figure & table +- How to use references and labels +- Exercise: to create a new LaTeX document & edit it +- Excercise: common error messages: can you find the error in this code? +- Exce

  • +
  • Room 3

    +
      +
    • GPU Programming (1 hour intro)

    • +
    • Learning objectives:

      +
        +
      • What is GPU programming.

      • +
      • When is it usable, beneficial to use GPU programming?

      • +
      • What are technologies to do GPU programming?

      • +
      • [What are and how to manage typical issues]

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • Git / Figures / Project management / data cleaning

    • +
    • Chose data cleaning

    • +
    • Three learning objectives:

      +
        +
      1. What do we mean by “clean”? How to identify it?

      2. +
      3. Identify some common problems in a dataset

      4. +
      5. Identifying and handling missing values/fields

      6. +
      +
    • +
    • Exercise

      +
        +
      1. Discuss problems, find the most common ones

        +
          +
        • In small groups

        • +
        • What problems have you run into with datasets you’ve worked with?

        • +
        • What problems can you imagine, or have you heard about from colleagues/news/social media?

        • +
        • Report back, instructor collects all problems into a list

        • +
        +
      2. +
      3. Have a dataset to clean; a clean and a messy example

        +
          +
        • (identifying) Using a visualisation or overviewing tool?

        • +
        +
      4. +
      +
    • +
    +
  • +
  • Room 5

    +
      +
    • Jupyter Notebooks

    • +
    • Learning Objectives

      +
        +
      • Can setup an enviroment you can reuse / can share with others / a project.

      • +
      • The order you run the commands in needs to match the order of the code in the Notebook - otherwise you end up in a pickle.

      • +
      • Why use a Jupyter Notebook? What are the advantages? Easy to use environment.

      • +
      +
    • +
    • Exercise

      +
        +
      • Print variable assignments from different cells - show that the order you run the code is important.

      • +
      • hand out a domain specific notebook that does some calculations and visualization to run and modify, to show that you can share easily

      • +
      • show !pip install to add dependencies/features

      • +
      +
    • +
    +
  • +
  • Room 6

    +
      +
    • Using GitHub without the command line

    • +
    • Learning Outcomes:

      +
        +
      • Be able to discuss changes before merging changes into the main repository.

      • +
      • Publish a personal repository page ( I think its called intro repository)

      • +
      • Share their script/notebook/code/small data on GitHub

      • +
      • Homepage using GitHub pages or the README that becomes the “index page” of the GitHub user account page

      • +
      +
    • +
    • Learner personas:

      +
        +
      • Check the Personas of the learners

        +
          +
        • Somebody who has seen/heard of GitHub but hasn’t used it yet

        • +
        • Someone using it for their own work but struggling with collaboration

        • +
        +
      • +
      +
    • +
    • Exercises:

      +
        +
      • Upload/share an example dataset or script

      • +
      • Review another collaborators pull request.

      • +
      • Take part in the discussion on a pull request.

      • +
      +
    • +
    +
  • +
  • Room 7 +Linux shell basics: why do we want to teach them? +(this took most of the time for the discussion)

    +
      +
    • Learning objectives:

      +
        +
      1. Filesystem: Directory (CLI) - Folder (GUI) analogy

      2. +
      3. Basic commands (which commands are basic? make a survey of shell histories and get the most common ones)

      4. +
      5. Basic constructs (e.g., for loops, pipes, while loops… which ones are basic? See above)

      6. +
      +
    • +
    +
  • +
+
+

Note from chat: Zoom timer: https://support.zoom.com/hc/en/article?id=zm_kb&sysparm_article=KB0068677

+
+
+
+
Episode 2: Lessons with version control
+

Materials: https://coderefinery.github.io/train-the-trainer/lessons-with-git/

+

Poll options: I want to hear about:

+
    +
  • A: Why use version control for teaching materials

  • +
  • B: Different template options

  • +
  • C: How CodeRefinery does it; CodeRefinerys lesson template

  • +
+

Poll vote (multi-select): add a o to your answer +- A: ooo +- B: oooooo +- C: oooooooo :ghost:

+

Question to audience: if someone wants to make a tiny fix to your material, how hard is it?

+
    +
  • If my material is only in pdf format which is not online, then it is hard.

  • +
  • I hope it is easy - my material is in GitHub. Nobody has ever done that though!

  • +
  • Slides: hard to find, easy to edit; Git repos somewhat easy, unless they have to be built locally or with an action; HackMD easiest to edit.

    +
      +
    • if you use something like google slides they are not that difficult to find

    • +
    • known permanent address. Google docs et al fail on that/same for many pads.

    • +
    +
  • +
  • For this material today - very easy! e.g. https://github.com/coderefinery/train-the-trainer/pull/128

  • +
  • Template with an edit button in the HTML pointing to the source-code in the repo.

  • +
+

Questions/Discussion topics

+
+

Upcoming CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/ +Please share with your networks, and let us know if you would like to co-teach a lesson (to support@coderefinery.org or in our Zulip chat)

+
+
    +
  • Changes to the material are sometimes not just tiny fixes. For example, one wants to present a slightly different selection of topics, but maybe some topics are “coupled” (perhaps naturally or perhaps just because of how they are presented), or change the general “theme” (e.g., life sciences vs theoretical physics) while keeping the actual topics the same. How could a lesson be developed to avoid having to do a huge rewrite?

    +
      +
    • You can try to modularize your material and keep non topic specific parts non themed. E.g. where you explain the functionality, don’t make reference to the example (not simple), so the example can be changed depending on the audience.

    • +
    +
  • +
  • What are the pros/cons of renaming a course / changing a repo name in GitHub?

    +
      +
    • It should be relatively unproblematic since GitHub will forward to the new name.

      +
        +
      • How long does Github keep the “old” name linked? Is there a max time it’s blocked, or changed as soon as a new one appears with the name?

        +
          +
        • in my experience it forwards “forever” until I create a new repo with the old name which will break the forward

        • +
        +
      • +
      +
    • +
    +
  • +
  • what should be in the readme for the git repo? (canonical address? contact points? license!)

    +
      +
    • https://coderefinery.github.io/mini-workshop/2/documentation/#often-a-readme-is-enough-checklist

      +
        +
      • I miss the url to the (main) repo in the readme

        +
          +
        • Do you mean the link to the rendered (lesson) page?

        • +
        +
      • +
      +
    • +
    • Link to rendered page: We often have this in the “about” section of the readme (see up right: https://github.com/coderefinery/train-the-trainer)

    • +
    • this gets lost in a fork, doesn’t it? so 20 folks forking and or reuploading the repo somewhere means the url gets lost?

      +
        +
      • True, but they might want to have their own version rendered?

        +
          +
        • yes, I have had issues finding and contributing to the “master” repo so all benefit. Else it gets cluttered. Both is valid

          +
            +
          • Good point though, the link to rendered page should probably also be included in the readme for completeness; ah and the link to the repository too, yes

            +
              +
            • so realistically we need a content folder and some more next to the readme as a best practice. sounds good!

            • +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • Is myst (markdown renderer) enabled by default in sphinx now?

    +
      +
    • to my knowledge no. we add the “myst_parser” extension to conf.py.

    • +
    +
  • +
+
+

Cicero: https://cicero.readthedocs.io/ +Sphinx documentation: https://www.sphinx-doc.org/en/master/ +Carpentries workbench for creating Carpentries lessons: https://carpentries.github.io/workbench/ +This is the testing lesson Richard showed: https://coderefinery.github.io/testing/ +And the corresponding repository: https://github.com/coderefinery/testing +You can lean back and watch, exercise coming in a bit :) +Richard will now edit our train the trainer material repository: https://github.com/coderefinery/train-the-trainer +The Sphinx extension for CodeRefinery lessons: https://github.com/coderefinery/sphinx-lesson +Empty lesson template to build your own lesson: https://github.com/coderefinery/sphinx-lesson-template

+
+

More questions

+
    +
  • Does the coderefinery.org page built on sphinx?

    +
      +
    • It’s built also from markdown but it uses https://www.getzola.org/ (which is more optimized to render websites, but we could do teaching also with Zola or create the project page using Sphinx)

    • +
    +
  • +
  • Is there a way to build and preview CR lessons without the command line?

    +
      +
    • The GitHub workflow we use creates HTML from all branches. This means that one can push a branch to GitHub, preview it there, and then open a pull request. One thing that would be nice but we don’t have yet is if a bot automatically posts the link to the preview to a pull request.

    • +
    +
  • +
  • For VCS-2, for the Carpentries Linux shell example, Lesson, Github repo, to me it seemed as though the Sandpaper setup they have makes a very nice interface, complicates the relationship between source and output. E.g on the soucre page https://github.com/swcarpentry/shell-novice/blob/main/index.md I could only see to ‘Prerequisits’ and not ‘Download files’ on the page https://swcarpentry.github.io/shell-novice/. Perhaps I have missed something?

    +
      +
    • I am sorry I don’t know the new Sandpaper setup well enough to answer this question.

    • +
    +
  • +
  • Do we have the instructions to build the lessons available somewhere to try out later?

    +
      +
    • https://github.com/coderefinery/sphinx-lesson

    • +
    +
  • +
+
+

Exercise VCS-1 (and VCS-2 (if time)) (https://coderefinery.github.io/train-the-trainer/lessons-with-git/#exercises) in breakoutrooms until xx:05

+

then short summary in main room and then break.

+

Use the notes below. Collect a list of lesson formats and discuss what you like about each of them.

+
+
    +
  • PDF slides by a presentation program

  • +
  • pdf slides with beamer in latex under source control.

  • +
  • Markdown slides via Github

  • +
  • CodeRefinery template

  • +
  • Carpentries template

  • +
  • Google Slides

  • +
  • git-book

  • +
  • Jupyter Book - allows creating a structured reference website using RST/Markdown, including Jupyter Notebooks to show result of running code

  • +
  • mdbook - create simple/minimal website using Markdown

  • +
  • Binder - allows learners to run their own live version of a github repository with Jupyter Notebooks, with only a web browser

  • +
  • Jupyter notebooks and jupyterhub platform

  • +
  • Jupyter + Nbviewer and custom css (read only) + Binder link (hands on)

  • +
  • RMarkdown

  • +
  • Quarto Slides

  • +
  • Reveal.js - write slides in HTML (also supports markdown)

    +
      +
    • Example: https://bl-presentations.erambler.co.uk/2024-02-21-idcc24/

    • +
    +
  • +
  • Remark.js - write slides in markdown

    +
      +
    • Example: https://bl-presentations.erambler.co.uk/2024-02-19-idcc-pids-workshop/

    • +
    +
  • +
+

Room discussions:

+
    +
  • Room 1

    +
      +
    • (https://smc-aau-cph.github.io/SPIS/README.html)

    • +
    • CodeRefinery template

    • +
    • Shared notes & blogs

    • +
    +
  • +
  • Room 2

    +
      +
    • demo the exercise

    • +
    +
  • +
  • Room 3

    +
      +
    • Mix of JupyterLab, Terminal within that, and traditional slides

    • +
    • Jupyter + RISE (benefit: slides that are editable and executable live)

    • +
    • Challenges

      +
        +
      • present code in an interactive way

      • +
      • handle lots of images/ figures without too much additional overhead when setting up the material

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • Material and tools depend on instructors

    • +
    • Some slide building tools

      +
        +
      • https://revealjs.com/

      • +
      • https://remarkjs.com/

      • +
      • https://github.com/rust-lang/mdBook

      • +
      +
    • +
    • Using flat git repos without fancy styling to make it easier to edit but still version controlled

    • +
    +
  • +
  • Room 5

    +
      +
    • Using R as a GIS: https://github.com/nickbearman/intro-r-spatial-analysis

      +
        +
      • Workbook: RMarkdown, Slides: Quarto

      • +
      • No continuous intergration

      • +
      +
    • +
    • Having a jupyter nbinder link to test the notebook

    • +
    • repo lives on codeberg in this example

    • +
    +
  • +
  • Room 7

    +
      +
    • Ex 1:

      +
        +
      • Sphinx, similar to CR

      • +
      • Sometimes pdfs generated with beamer package (or from pptx and odt), but blows up repository size if in version control

      • +
      +
    • +
    • Ex 2:

      +
        +
      • Content

        +
          +
        • CR: Content commonly found int the content folder

        • +
        • SC: Mostly under episodes

        • +
        +
      • +
      +
    • +
    • Question that came up:

      +
        +
      • is CR/Sphinx approach mostly for technical topics? What about language.

      • +
      • I guess by our nature it’s focused there. But probably could be used for others (I guess it it’s much easier to use git in a technical audience.)

      • +
      +
    • +
    +
  • +
+
+
+
Episode 3: How we collect feedback and measure impact
+

Materials: https://coderefinery.github.io/train-the-trainer/feedback-and-impact/

+

Questions to audience

+
    +
  • What tricks/techniques have you tried in your teaching or seen in someone else’s teaching that you think have been particularly effective in collecting feedback from learners?

    +
      +
    • preparing a survey and emailing it to participants as soon as the event ends (usually get <50% of answers but it’s a representative enough sample)

    • +
    • do engage with the audience, give them the time to get the courage to speak up

    • +
    • Be the audience yourself

      +
        +
      • yes! some problems/issues I don’t notice as instructor, only as listener

      • +
      +
    • +
    • Have time (e.g. 5 min) in the session to fill out the feedback form

    • +
    • If the course/workshop has several days/sections do a couple questions every change, then a full one afterwards

    • +
    • “Traffic light” feedback (e.g. for pacing or progress on exercises): give each learner two different coloured post-it notes for in-person, or use emoji for online, to indicate a current status

    • +
    +
  • +
  • Can you give tips or share your experiences about how to convert feedback into changes or actionable items?

    +
      +
    • ask questions about things you know you don’t know

    • +
    • “Don’t let the noise of others’ opinions drown out your own inner voice.” — Steve Jobs

    • +
    +
  • +
  • When people ask questions / get stuck with a specific step. Is there a typo I can change there and then in the workbook?

    +
      +
    • Being able to fix small things on the fly helps sometimes, otherwise open issues if working on github

    • +
    • If multiple people have the same question, then this is an indication that I should look at this in more detail

    • +
    +
  • +
  • How do you measure the impact of your teaching? Any tips or experiences about what you have tried or seen other courses do?

    +
      +
    • “How likely are you to recommend this workshop to others? (0/5)”

    • +
    • Check the ‘Garbage Out’ bin, what you find there will be what went across. The rest will be history…

    • +
    +
  • +
  • Anybody knows of good resources on survey design? Please link them here.

    +
      +
    • “Our job is to figure out what they’re going to want before they do… Our task is to read things that are not yet on the page.” - Steve Jobs

    • +
    +
  • +
+

Questions/Discussion points

+
    +
  • Feedback is necessary to design good lessons. Improvement can only be done iteratively. So the faster the iteration (design/teach), the better. But on the other hand, I cannot constantly bomb our community with training event emails. So I would like to try proposing a course many times a year, but I don’t want to spam everybody many times a year.

    +
      +
    • :+1:

    • +
    • With CR we also have a calendar that can be imported to different calendar applications, where we add all workshops: https://github.com/coderefinery/calendar/

    • +
    +
  • +
  • Does an even split of too fast / too slow mean speed is about right?!

    +
      +
    • I take it to mean “it’s roughly where it should be”. Would be better to accomdate the sides better though… (we do try to design for a broad audience: some easy stuff, some advanced stuff, so people can make their own path)

    • +
    • It could also indicate that the prerequisites/scope are not well defined :+1:

      +
        +
      • Based on long term surveys we also know though that even though the workshop might have been to fast, people appreciate having “heard things before and know where to find them later”

      • +
      +
    • +
    • perhaps the even split between too fast/too slow is ok only if the majority of votes goes for “just right” :+1:

    • +
    +
  • +
  • One of the most important disciplines in journalism is to challenge your working premises. (Bill Keller) This applies equally to learning as well.

    +
      +
    • Participants can be encouraged to write some posts on LinkedIn. If it is helpful some blurbs can be created for pre and post-workshop to generate more traction for Code Refinery and future participation.

    • +
    • Ask participants if they use Dev.to, hashnode etc to blog their work or use twitter etc to have a memory of their work.

    • +
    +
  • +
  • Do you have any suggestions for prerequisites? I try to make them clear, but occasionally people attend who clearly do not meet them. :+1:

    +
      +
    • I guess it depends how much it matters for the workshop itself. If you have group exercises etc, it probably matters? , lecture style maybe not so much?; important is that the participants themselves know that prerequisites exist and if they meet them

    • +
    • Sometimese people that do not meet the prerequisites join to get to “know what they don’t know”, find out where to find information on topics they might get interested in future etc

    • +
    • Other suggestions? Viewpoints? :)

    • +
    • Thank you - things for me to think about there :-)

    • +
    • With CR’s latest ideas, we try to make the prerequisites clear, but there is no capicity limit: it’s OK if people drop by and are less than prepared: it’s livestream, anyone can come. We try to have something for these people, too: learn what you are missing, why you might want to study more in the future.

    • +
    • Any thoughts on applying this to a more practical focused course, with a total capacity limit (i.e. not like CodeRefinery).

    • +
    +
  • +
  • Everytime you do a course on CodeRefinery, think of it as trying to bake a new cake with an old recipe with no idea about the individual taste preferences of the one you bake the cake for. Then, you will not experience too many surprises. Fine-tuning the recipe for one cohort still remains the ‘old recipe’ as far as the next ‘new cohort’ will be concerned. C’est la vie.

    +
      +
    • nice analogy!

    • +
    +
  • +
  • Question from chat: For examples 2 & 4, would you also consider using something like a Likert scale? E.g. Rate how well you agree with the statement “My code is more reusable as a result of attending a CodeRefinery workshop” (from 1 Strongly disagree to 5 Strongly agree)

    +
      +
    • Thanks! I am new to Likert scale and will read up on it. In my experience numbered answers can be useful for reporting. But I also like questions where we ask for what actually to change.

    • +
    +
  • +
  • Comment from chat: Richard, your point crowns the point of having CodeRefinery, With Radovan’s and Samantha’s acquiescence assured, I would like to suggest you wear a crown going forward, especially for the CodeRefinery session. Do we have a deal ?

    +
      +
    • I don’t quite understand this

    • +
    • I think it’s a tongue-in-cheek-comment (joke) but I am not sure…..

    • +
    +
  • +
  • What is the ideal way to allow people to interact while course is going on in the main online session, i.e. without a breakout room? Taking a pause or discussion in the background?

    +
      +
    • I’ve had some success with WhatsApp groups for a course - particually ones that run over 4 (or 2) sessions.

    • +
    • A quick survey/quiz

    • +
    • Question to the audience that we take time to answer but it helps to show the answers

    • +
    +
  • +
+
+
+
+
+
+

Wrapup

+
    +
  • Thank you for active participation :)

    +
      +
    • We’ll continue answering questions after the workshop and make the cleaned up (no names etc) available from the materials

    • +
    +
  • +
  • Next session Tuesday August 20, 9 CEST: Tools and techniques adopted in CodeRefinery workshops

    +
      +
    • we will talk about on-boarding, install help, roles, screensharing, sound, collaborative notes

    • +
    +
  • +
  • All workshop materials will stay available (after the full workshop also on Zenodo :tools:)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • If you want to co-teach with us in the upcoming (or next) CodeRefinery workshop (https://coderefinery.github.io/2024-09-10-workshop/); or just want to learn more about this opportunity: Send your name and e-mail address to support@coderefinery.org; we will contact you!

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • Lesson design approach

  • +
  • I liked the backwards lesson design, gives a name to a practice I’ve already been doing :+1: :+1:

  • +
  • Lessons from code refinery on lesson design. Learning about Sphinx.

  • +
  • Collaborative notes and anonymized archive of notes.

  • +
  • it’s nice to have a community to discuss these kinds of problems

  • +
  • Hearing the variety of tools people use for slides (PDF, Quarto, Beamer etc.)

  • +
  • Good intro of the tools, the jargon and the pedagogical philosophy of teaching tech.

  • +
  • The absolute openess in having everything publicly available - materials ofc but also questions, discussions, feedback, …

  • +
  • Thinking about all content being available publicly and as a git repo

  • +
  • Thanks for explaining the HedgeDoc interface, with view and edit options

    +
      +
    • Is there anyway to come back to this document later (e.g. tomorrow) and see what has changed since now? So I can see if any other questions have been asked/answered?

      +
        +
      • There is a “revision” point under “Menu” up right, which shows you different versions of this document

      • +
      +
    • +
    +
  • +
  • Modesty: the gentle art of enhancing your charm by pretending not to be aware of it. - Oliver Herford

  • +
  • +
+

What one thing would you improve about this session?

+
    +
  • Perhaps some more interactivity but can be hard to plan and time

    +
      +
    • We’ll see what we can do.

    • +
    +
  • +
  • Maybe mix the breakout groups up for each breakout session (although there are advantages to consistency too) :+1:

    +
      +
    • yes, pros and cons! For me, having consistency worked well this time.

    • +
    • Likely we will have different participants next week, and a bit of mixing will happen naturally.

    • +
    +
  • +
  • The pace of the presentations could be a little tighter (the pace is good for a discussion though)

  • +
  • Richard’s voice was only 80% audible

    +
      +
    • Sorry to hear that. It seemed fine on my end. Will check better for next session.

    • +
    +
  • +
  • Hands on simulation and collaborative notes

  • +
  • I found it difficult to follow the presentation and the collaborative notes at the same time

    +
      +
    • We will highlight the collaborative notes more in the next session. Our strategy usually is to say to focus on the “teaching part” and use the notes only when needed. Since you can go back and also check the notes later.

      +
        +
      • My problem is that I want to follow both since I don’t want to miss out on anything. As such, I have both windows (zoom and the notes) open side-by-side. Since there is near-constant real-time typing in the editor, and as such visible movement on screen, I get constantly distracted. This makes following the event quite exhausting.

      • +
      +
    • +
    +
  • +
  • Heads up to participants on using the break out rooms on voice interaction and screen sharing.

    +
      +
    • Do you mean that we should have mentioned it more clearly in the pre workshop email?

    • +
    +
  • +
  • I found it hard to follow with so many things going on at once…

    +
      +
    • A collaborative document being changed at the same time as…

    • +
    • Someone speaking and explaining content at the same time as…

    • +
    • Chat in a different application at the same time as…

    • +
    • Content changing in a termin application.

      +
        +
      • Thank you for the feedback. We will remove the Zoom chat out for the next session and explain the use of the collaborative notes more.

      • +
      +
    • +
    +
  • +
  • Make more use of defining and then making sure the learning objectives are met

    +
      +
    • True we did not talk about them much, will pick that up better for next session.

    • +
    +
  • +
  • UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. - Dennis Ritchie. You need to do a lot to prove that to be wrong, simply put.

  • +
  • Allocate some time for learners to type in the answers so that we don’t have to listen and type at the same time.

  • +
+

Any other comments?

+
    +
  • It’s great to hear other people’s experience

    +
      +
    • Good to hear :)

    • +
    +
  • +
  • Looking to meet you onsite if there are any events and get more emails from you :)

    +
      +
    • We will keep you informed :)

    • +
    +
  • +
  • Thanks for putting this together, I got a lot of inspiration for my own courses

    +
      +
    • Good to hear :)

    • +
    +
  • +
  • I didn’t know where to ask questions. It would work best for me to do it in zoom chat as that’s the application that I’m watching in..

    +
      +
    • Sorry for that, just to figure out why: Did you join a bit late?

      +
        +
      • No. Perhaps I just missed that or it was too quick for me or something?

        +
          +
        • Ok, sorry. Will try to make this more clear in next session.

        • +
        +
      • +
      • Perhaps also because there were so many things going on and jumping around. For me, the zoom chat is the constant (and obvious) place to ask questions while watching a shared screen, trying to find the right place in a moving collaborative document is difficult. It tears my attention into too many pieces. :+1:

      • +
      +
    • +
    +
  • +
  • Had a lot of content that assumed extant knowledge that I didn’t have. This wasn’t in the pre-requisites.

    +
      +
    • Do you have examples?

      +
        +
      • Yes! The code refinery templates and even just the way of doing that. I was expecting more on “when designing a lesson you should think about these steps” rather than this is how we do it and this is our tool for doing it. I guess I should have read the pre-workshop content better?

      • +
      • Ok, thank you for your feedback. You are right that we actually had some content that for sure would have been easier to follow for people with background knowledge about a certain topic.

      • +
      • “If you are in CodeRefinery TTT, you probably know what version control is and why it is important.” - extant knowledge, why not just add a sentence or two?

        +
          +
        • Please can you update in preparation for the next workshops so that I can decide whether or not they will be right for me?

          +
            +
          • Yes, we will think more thoroughly about this and send the info in the next email going out Wed/Thu

            +
              +
            • Thank you!

            • +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • Lots of the content was relevant to code refinery but not the wider topic (e.g. it was how to design a code refinery lesson and not how to design a lesson as stated in the session title)

    +
      +
    • We thought of the content of showing one way of doing things, ie “what we have learned”, if you have suggestions on how we could make that more clear on the event page, please let us know :)

      +
        +
      • “in a code refinery lesson” in the lesson/workshop description?

      • +
      +
    • +
    +
  • +
  • When you have pre-written “thank you for your active participation” it feels fake!

    +
      +
    • He, that is true, did not think about that. Thank you for the feedback. I would not have added it if Radovan and Richard would not have provided good feedback from circling the rooms.

    • +
    +
  • +
  • I found it vague and disorganised and difficult to follow. It felt like the instructors were presenting the content for the first time and didn’t know what to do next.

    +
      +
    • Thank you for your feedback. This is not the first time we have this training, but it is the first time in this constellation/way. The way of teaching may also sometimes make it seem new to instructors.

    • +
    +
  • +
  • I really liked the active exchange with other participants, but I also would have enjoyed a bit more technical content in the presentations. In a sense it felt less like a ‘training’ and more like a get-together :+1:.

    +
      +
    • Thank you for your feedback. We thought the name “workshop” would combine the training and exchange nature of this event. But maybe it didn’t do so enough? Do you have suggestions on how to clarify it on the event page?

      +
        +
      • Well, the ‘train the trainer’ title created the anticipation of being trained ;) don’t get me wrong, I liked the exchange, but I felt that the training aspect fell a little short. imho the workshop would benefit from a little more (instructional) content that is presented in a more structured way by the instructors (as opposed to ‘crowd-sourced knowledge’ that is collated in a loose collection of questions, notes and links)

      • +
      • Other than that, you could add another section on the main page, sth like ‘Workshop structure: we aim for a mix of modular presentations and work in small groups. The latter will be done in breakout rooms - be prepared to switch on your camera and have a fruitful exchange with fellow participants!’

        +
          +
        • Thank you for the suggestions, will add something like this :tools:

          +
            +
          • +

            Added : https://github.com/coderefinery/train-the-trainer/commit/03308595436e636b3bb37ed9d1f0dee39eeccd0f

            +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • My understanding (so far) of what (unlike the competition) CodeRefinery DOES NOT seek to exemplify - +https://images.ctfassets.net/rxqefefl3t5b/2k45BFtw4sBMlBfjr1OZ90/5c6ecd3628a43b0cdc79815f665e224a/Screenshot_2023-05-02_at_09.35.23.png?fl=progressive&q=80

  • +
  • My understanding of what (unlike the competition) today’s session of CodeRefinery DID exemplify - Definition of ‘Workshop’ from the Oxford dictionary of the English language “a period of discussion and practical work on a particular subject, in which a group of people share their knowledge and experience”

  • +
  • In my experience, even for the most seasoned Programmer coding, by its very nature, is nothing trivial, this being a simple straightforward fact just like there is no such thing as an egg which is a cube. I mean there is a reason why not just about everybody is a poet either. But, other minds have pointed this out without having to first explain why the universe is what it is in a way that could be understood without effort … https://i.pinimg.com/originals/7b/7e/c4/7b7ec4b91d2cf9d8e1b064678d205467.jpg

  • +
  • The inclusive environment feels very welcoming. Keep up the good work!

  • +
+

Thank you all for your feedback! Highly appreciated!

+
+
+
+

Day 2 : Session 2 (20.08.24)- Tools and techniques adopted in CodeRefinery workshops

+
+

:calendar: Schedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 9.25

About CodeRefinery workshops

10.15 - 10.25

8.15 - 8.25

9.25 - 9.55

Collaborative notes and interaction

10.25 - 10.55

8.25 - 8.55

9.55 - 10.10

Break

10.55 - 11.10

8.55 - 9.10

10.10 - 10.45

Workshop overview, roles, onboarding

11.10 - 11.45

9.10 - 9.45

10.45 - 11.05

Sound

11.45 - 12.05

9.45 - 10.05

11.05 - 11.20

Break

12.05 - 12.20

10.05 - 10.20

11.20 - 11.50

How to prepare a quality screen-share

12.20 - 12.50

10.20 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+

:icecream: Icebreaker

+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :-)

  • +
  • https://media.istockphoto.com/id/148421550/vector/bored-emoticon.jpg?s=612x612&w=0&k=20&c=uo5KBTqdJZbBQb_Xldhzuovx5t08fHfGR7dw7TCk90I=

  • +
  • :saluting_face:

  • +
  • :sleepy:

  • +
  • :coffee:

  • +
  • :umbrella:

  • +
  • :cocktail: :coffee:

  • +
  • :seedling:

  • +
  • :tired_face:

  • +
  • :sun_with_face:

  • +
  • 🥴 (:woozy_face: not converted?)

  • +
  • :coffee:

  • +
  • :sunflower: :book:

  • +
  • :satisfied:

  • +
  • :coffee:

  • +
  • :coffee:

  • +
  • 🥱:tired_face:

  • +
  • :bread: - I am baking bread today so I have been kneading dough while listening!

  • +
+
+
+
Introduction in breakoutrooms
+

Name / Affiliation / Location

+
+
+
Teaching
+
    +
  • Do you teach and organize teaching alone or with others? What would you prefer and why?

    +
      +
    • Coming together is a beginning; keeping together is progress; working together is success. – Edward Everett Hale

    • +
    • These days always with others. Alone is easier to prepare but almost always is harder during it.

    • +
    • Teaching with very diverse partners, it can be challenging to find a common language with people very different than you.

    • +
    • I teach alone, in the future there will be more collaboration with multiple team members. Both approaches have their pros and cons.

    • +
    • Both has its own distinct advantages

    • +
    • Most of my teaching is on my own, as a freelancer its more expensive to work with colleagues than to deliever a course on my own.

    • +
    • Teaching together, learns from each other, feedbacks to improve

    • +
    • Not formally taught yet, only given presentations actually .

    • +
    • collective teaching would benefit the teachers with collaborative curriculumn and experiences sharing.

    • +
    +
  • +
  • If applicable, have you seen any challenges when teaching together and how to overcome them?

    +
      +
    • It actually requires preparation,

    • +
    • Is it about teaching or about inspiring ? Discover the answer and get inspired …

    • +
    • It’s like being in a band: you might be great at improvising and your band-partners might be great at improvising too, but a bit of rehearsing makes even the impro gig much better

    • +
    • Need to plan before session, difficult if people don’t ‘plan’ in the same way, e.g. with the same time frame.

    • +
    • Heterogeneity in learners make it impossible to get the same result from everyone.

      +
        +
      • In fact, the same applies to teachers :D

      • +
      +
    • +
    • Teaching together requires to have similar opinions on how to teach. I share vews only with ~40% of my colleagues I think.

    • +
    +
  • +
  • No Teaching experience but it is good to give the outline of the lessons beforehand and learning goals.

  • +
+
+
+
+
+

:question: Questions

+
+
General / Practicalities
+
    +
  • What is this document for?

    +
      +
    • Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts)

    • +
    +
  • +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms?

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    • BR 1 : The Zoom chat does not work for the breakout room so we should take note of that. No webcam/mic = expect silence.

      +
        +
      • Thanks for notifying! This was not intended. Turned the chat back on.

      • +
      +
    • +
    +
  • +
+
+
+
+
+

Episode 1: CodeRefinery

+

Materials: https://coderefinery.github.io/train-the-trainer/coderefinery-intro/

+
    +
  • (questions continue here)

  • +
  • Is there the plan to build capacity / be paid to deliever courses?

    +
      +
    • We’ve discussed it but right now we don’t have many people who could accept money to do this (and maybe shouldn’t, because of their jobs). But, we would encourage others to use our materials as “independents” to deliver paid courses

    • +
    • One idea we have had is that paid courses could be delivered through the DRA (link below), who we know. Basically, DRA could find instructors and handle the money transfers (If someone wanted a paid course, we could help find someone to do it through DRA or independently)

    • +
    • :smile:

    • +
    +
  • +
  • Have you come across DRA, https://digital-research.academy/, Heidi Seibold, Joyce Kao who are doing similar work? I can connect you if you like.

    +
      +
    • Yes we have been discussing about possible future collaborations and are already sending possible clients their way (we, as a project cannot take money) :+1:

      +
        +
      • Excellent! :-D :smile:

      • +
      +
    • +
    +
  • +
  • .

  • +
+
+
+

Episode 2: Collaborative Notes

+

Materials: https://coderefinery.github.io/train-the-trainer/collaborative-notes/

+
    +
  • So anyone can type anonymously?

    +
      +
    • Yes, as long as you do not log in, you are Guest XXX

    • +
    • And at least in our hedgedoc case you cannot log in so you will always be anonymous. You can do [name=xxx], to add your name to a comment

    • +
    +
  • +
  • Test of +1

    +
      +
    • +1 :+1: :+1:

    • +
    • :-1: a test

    • +
    +
  • +
  • You are hosting your own version of HedgeDoc, and Hackmd.io is a similar (free) option. What are the limitations of the free hackmd.io? Should each center install their own HedgeDoc instance?

    +
      +
    • It seems the free version of HackMD has gotten worse lately. It works still well enough with a few people editing at the same time.

    • +
    +
  • +
  • Have there every been problems with the anonymity and CoC?

    +
      +
    • We haven’t had any issues so far.

    • +
    • With a different anonymous tool in a bachelor course, we had issues with anonymous participants (participants were posting slurs and unsafe links). The course organiser decided to stop allowing anonymous tools.

    • +
    +
  • +
  • Why not google documents?

    +
      +
    • Google documents are actually setting a hard limit for simultaneous writing, no more than 100 concucurrent editors. I am unsure if microsoft onedrive word documents would allow more users writing at the same time.

    • +
    +
  • +
  • What’s the most people you have every had on HackMD / Hedgedoc?

    +
      +
    • I believe about 200 active participants?

    • +
    +
  • +
  • What are your thoughts on using the build-in Zoom Q&A?

    +
      +
    • We haven’t tried this, in part because the way we do streaming now (you’ll see in session 4), participants aren’t in Zoom so don’t have access to that. The doc-format works pretty well though, when we keep it in this limited “write at end” format.

    • +
    +
  • +
  • How do you see what has changed? e.g. if leave the session at the end, can I come back tomorrow and see X has been added? e.g. a diff for this maybe?

    +
      +
    • In the menu up right there is revision, it does show the document and changes at different time step :+1: Thanks!

    • +
    • We recommend people only write at the bottom (and since we answer things live), so as a first level approximation you find where you were and read below that. Think of it more like chat than a full document. (Yes, we do revise questions at the end)

    • +
    +
  • +
  • How about flinga boards or similar tools?

    +
      +
    • My take is that the simplicity of a simple text document wins over free-form in-person-workshop-like tools.

    • +
    • There’s miro, can be a bit confusing though

    • +
    +
  • +
  • How does this work with small groups, e.g. 10-15 people?

    +
      +
    • Good question: it can be hard if people aren’t rigorous about it, people start only using chat/voice. So there seems to be some lower bound in size but we haven’t tested this much

    • +
    • And if the instructors never screenshare it to show what goes on it, then seems to be less used.

    • +
    • And if there aren’t other people to read/answer it during the session (perhaps less likely in a small course), it seems to be less used.

    • +
    +
  • +
+
+

Breakoutrooms until xx:55

+

Exercise/discussion: https://coderefinery.github.io/train-the-trainer/collaborative-notes/#exercise

+
+
    +
  • Breakout room 1:

    +
      +
    • Use of etherpad for collaborative discussion.

    • +
    • Use of slido for polling and quizzing.

    • +
    • Presemo as a slido alternative (https://www.aalto.fi/en/services/presemo-a-fully-web-based-classroom-participation-system)

    • +
    • Use of text based approach for questions rather than live can be helpful if there is a language barrier issue.

    • +
    +
      +
    • A good teaching session which had many questions coming spontaneously to the teacher is a non-entity of sorts. If the overall flow of feedback / questions increases it could indicate that the session will not prove to be a helpful experience. A signal that generates noise is, well, noise, if calling a spade a spade signals anything. Note that the ‘overall’ bit and the ‘to the teacher’ aspect are important. Both the best and the worst teaching session have two things in common: a teacher, and the fact that NO Materials of any kind are used, ie speech is the only channel of communication via a common language. The only difference is that it is not the same teacher, at least not in the same session at the same time.

    • +
    +

    Another less mentioned, but perhaps more relevant indicator of a great session is the simple fact that at the end of the session EVERYONE feels empowered, NOT tired. This is not an easy to quantify thing, but screams out the quality of the experience loud. More often then not, such sessions differ little from each other, apart from in terms of the theme / topic and the participant mix. It ends up being the ‘keep your cake and eat it too,’ of sorts, not quite the far less amusing post-bombardment devastation scenario in the wake of a take it or leave it go at anything.

    +
      +
    • profanity in collaborative documents where people can add content anonymously could be a problem (happens very rarely, fortunately and somewhat surprisingly)

    • +
    +
  • +
  • Breakout Room 2:

    +
      +
    • Good experiences with Zoom polls

    • +
    • Handling questions in hybrid setups: all participants (on-site and online) ask questions in written form

    • +
    • Collaborative notes can be challenging when conducting a course alone (without teaching assistants) :+1:

    • +
    • Providing a method to ask questions anonymously can make asking easier for shy participants

    • +
    • Questions can give valuable feedback on how the course is going

    • +
    • Online collaborative whiteboarding platforms such as Miro

      +
        +
      • Large monitors are useful for this not to have to drag a “periscope” around

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • good experience with whatsapp chat for questions. since most learners have the app already and one thing less to install and set up

      +
        +
      • reply to question is a way to handle multiple questions at the same time but it works well for smaller groups

      • +
      +
    • +
    • experience with collaborative docs in in-person workshops: voice questions might “win” over the document

    • +
    • “seeding” questions may help to not have an empty document

    • +
    • it can help somebody to start and create a structure which helps others to see and follow

    • +
    • we discussed the Carpentries sticky notes system (red sticky note: signal tech issues and use for feedback, green sticky note: signal that exercise worked and for positive feedback)

      +
        +
      • Nice summary of sticky notes system: https://teachtogether.tech/en/#s:classroom-sticky-notes :+1:

      • +
      +
    • +
    • What is the success rate of in-person workshops after COVID? Discussion: Teachers prefer in person and learners prefer remote or recorded to spool back and relearn.

    • +
    +
  • +
  • Room 5

    +
      +
    • Good experience with Collaborative tools as HackMD and HedgeDoc while teaching with no bad feedback

      +
        +
      • When used with smaller groups works best as one-way, like sharing links with students and so on

      • +
      • Needs to be done as a team, quite difficult if teaching alone

      • +
      • Most useful when online/hybrid

      • +
      +
    • +
    • Anonymisity is important for transparent feedback and no biasis in classrooms

    • +
    • Not very collaborative but useful to share history or jupyter notebooks live https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush

    • +
    • Used Flinga before that seems like Figma and also onsite teaching using sticky notes

      +
        +
      • There’s miro.com but can be a bit confusing, more for brainstorming than for teaching

      • +
      +
    • +
    • Using quizzes apps like Kahoot is beneficial while teaching to have more engaging students

    • +
    • +
    +
  • +
  • Room 6

    +
      +
    • teaching teenagers (in presence) but using shared pad becomes quickly very chaotic, so only usable for short moments when answering very precise questions

      +
        +
      • Yeah, I can imagine. For CR we try to keep it in this very limited format (all questions bullet points, only add to the end) and I think that helps.

      • +
      +
    • +
    • using shared notepad for small workshop (5-10 people) to explore common thematic (mainly technical) to keep a shared notes and condense aftwerward (and publish on wiki to archive)

    • +
    • Difference between teaching in person and online. Some people prefer in-person and sometimes you have no option but to organise it online.

    • +
    • There are sometimes cultural differences and learners feel shy to ask / question the knowledge of the Teacher, so shared notes are a good way to safely ask questions.

    • +
    +
  • +
+

Questions continue:

+
    +
  • Have we demonstrated how we do polls in HedgeDoc? Add your vote by adding an o

    +
      +
    • yes: oooo (in session 1)

    • +
    • no:

    • +
    • :smile:

    • +
    • not sure: o

    • +
    +
  • +
+
+
+

Episode 3: One workshop, many perspectives

+

Materials: https://coderefinery.github.io/train-the-trainer/overview/ +Next CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/

+
+

Exercise until xx:39

+

https://coderefinery.github.io/train-the-trainer/overview/#discussion

+
+
    +
  • Room 1

    +
      +
    • Send pre-workshop email with pre-requisite instructions on what should be set-up beforehand.

      +
        +
      • But, also mention that if help is needed for set-up, we will be ready before the session officially starts.

      • +
      +
    • +
    • Discussion on whether we push to work in a pre-ready environment (e.g. Binder, Colab) or in their own environment.

    • +
    • Lots of help needed both before and after.

    • +
    • Installations: as much as we can provide ready made environments for the learners, maybe installations will be something that the learners will face sooner or later. Maybe one should teach more about installations?

    • +
    • My only cherished role in a teaching-learning session is the that of one who is living the moment as if there were no tomorrow. What cuts all ways really is that “By failing to prepare, you are preparing to fail.” ― Benjamin Franklin. A helpful motto: “When one teaches, two learn.” — Robert Heinlein. The best experience cannot be given, it can only be allowed to flow its way, so get out of its way.

    • +
    +
  • +
  • Room 2

    +
      +
    • Frequently, a single person fills all the roles for a single or multi-day workshop

    • +
    • Collaboration with different centers/ universities can be challenging

    • +
    • Preparing participants: it’s essential for the instructor to go through the demos and be sure that they will work (no unpleasant surprises live). This can be extended to advance-prep for participants.

    • +
    • Best experience is to hear (live or in feedback notes) some positive things directed at you :)

    • +
    • Fully prepared environments (eg self-hosted JupyterHub) can make preparation for participants easy

    • +
    +
  • +
  • Room 3

    +
      +
    • Some students have problems with setuping the environment. Maybe having a step by step instructions could help. But some students don’t want to “start” the course before hand.

    • +
    • Preparing the environemnt before hand ensures everyone is onboard from day 1. The same thing happend in CSC training sessions and another session Peng attended.

    • +
    • Had experience in attending as teacher and student in previous workshops

    • +
    +
  • +
  • Room 4

    +
      +
    • knowing the background of the audience is helpful

      +
        +
      • Try and ask in advance of the background of the audience. Do a poll at the start of the workshop. In person one can do it interactive.

      • +
      +
    • +
    • among co-instructors: discuss topics and flow

    • +
    • if more people are involved, it can help changing roles from time to time to see different perspectives

    • +
    • preparation is key

    • +
    • Circulate instructions beforehand

      +
        +
      • Do a poll before session: Have you installed (QGIS) successfully?

      • +
      • Push hard to do this in the welcome email

      • +
      +
    • +
    • communicate clearly to the participants

    • +
    • +
    +
  • +
  • Room 5

    +
      +
    • We’ve all taken most roles

    • +
    • How to prepare in advance?

      +
        +
      • Meet and discuss once or twice

      • +
      • Make a pre-survey to check for interest and background

      • +
      • Going through the materials

      • +
      • Checking the toolkit (zoom)

      • +
      • Agree on the reponsibilities and back-up plans (bit of scenarios planning)

      • +
      +
    • +
    • How to prepare trainings in advance?

      +
        +
      • Collect resources and prepare the workshop plan

      • +
      • Having the material readily available online ans sharing it

      • +
      • Making a pre-survey

      • +
      +
    • +
    • What was the best workshop experience for you as learner, helper or instructor? What made it great?

      +
        +
      • learner

        +
          +
        • Engaging and practical workshop with more exercices and follow-up theoretical part explanations

        • +
        +
      • +
      • helper

        +
          +
        • When the instructor is well prepared and as helper ther’s only typos to fix and interesting questions to answer

        • +
        • Assist the instructor, coordinate the collaborative notes, and make sure that the time is respected

        • +
        +
      • +
      • instructor

        +
          +
        • I have a colleague whom I’ve ran the same workshop a few times already, goes quite smoothly now and we’ve made a few changes. Hard to reach that point with new colleagues but getting there

        • +
        • Students/participants were engaging with the material and many good feedback collected even some of them asked for the next workshop

        • +
        +
      • +
      +
    • +
    +
  • +
  • Room 6

    +
      +
    • What has made a great experience for you as a learner/helper/instructor?

    • +
    • Common ground between learners & teachers

      +
    • +
    • Motivation

      +
        +
      • Teaching is much more enjoyable when the learners want to be there

      • +
      • I spend a lot of time at the start of a workshop making sure learners feel that the content is possible for them to understand and master

      • +
      +
    • +
    +
  • +
+

Poll: I have joined a CodeRefinery workshop before: (add an o for your answer)

+
    +
  • yes (within last 2 years): ooooooo

  • +
  • yes (longer time ago): oo

  • +
  • no: oooooooo

  • +
  • +
+

(questions would continue below:)

+
    +
  • What is the motivation / advantages of streaming workshop versus using zoom?

    +
      +
    • We’ll cover this more in week 4, but roughly: zoom became unmanageable and essentially quiet once things got big. Streaming allowed “one to many” communication with no limit, and collab notes allowed better interaction anyway. By separating the rooms, it was more pleasant to teach. Videos could be released immediately since there was no risk of privacy of participants. There could still be in-person/online small groups who have “watching parties.”

    • +
    +
  • +
  • What are the blue red and green font colors here, does it symbolify anything or just a convention HedgeDoc uses?

    +
      +
    • Visual separation of formatting, mostly. (It helps to quickly realize you’ve missed/ mistyped a control Markdown symbol etc.)

    • +
    • Yeah, it’s bascically “code highlighting” for markdown. No special meaning but quite convenient for us.

    • +
    +
  • +
  • Is this next workshop only for team leads or also open for helpers and coordinators?

    +
      +
    • You mean the next session of this workshop or the upcoming “CodeRefinery workshop”(this one: https://coderefinery.github.io/2024-09-10-workshop/)?

      +
        +
      • The upcoming workshop coordinators are alredy working, but can be joined if you are interested

      • +
      • As helper roles we currently only have “collaborative notes helper”, which is all about helping to answer questions in the collaborative notes

      • +
      • We do have some co-teaching slots open :)

      • +
      • If interested: join the discussion in our chat: https://coderefinery.zulipchat.com/#narrow/stream/316508-coderefinery-tools-workshop/topic/Fall.202024.20CodeRefinery.20workshop

      • +
      +
    • +
    +
  • +
  • Can a person have multiple roles in a workshop as a helper and a teacher?

    +
      +
    • Yes, many teachers also contribute to the rest of the workshop by answering questions in collaborative notes. :+1:

    • +
    • Some teachers also host a local classroom in week one and do their teaching in week two of the workshop

    • +
    • Roles that do not go well together are broadcaster/director/host and instructor (goes well until there is a problem; co-teaching solves that partly)

    • +
    +
  • +
+
+
+

Episode 4: Sound

+

https://coderefinery.github.io/train-the-trainer/sound/

+
    +
  • To me, Richard is a bit quieter than the other two :+1: :+1: :+1:

    +
      +
    • to elaborate: I think that the audio coming from him is missing some mids

    • +
    • Do you have any links about this kind of evaluation and adjustment?

    • +
    +
  • +
  • Do you suggest / recommend a specific headset(s) with mounted microphone?

    +
      +
    • in our experience headsets with a microphone will almost always be better than a separate microphone sitting on the desk or in the monitor

    • +
    • +
    +
  • +
  • Speakers have different tones of voice and speaking styles, is there a recommendation or experience from CR workshops for how this is adjusted and catered to environemnts for listeners?

    +
      +
    • Yeah, people’s voices are different and we haven’t gone as far as voice training or improving.

    • +
    +
  • +
  • How to change the volume for speakers? Tried Zoom settings and system settings and didn’t help.

    +
      +
    • From linux I can use different pulsemixers pavucontrol, pulsemixer to set the gain to above 100%. I’m not sure the equivalent on other OSs but

    • +
    +
  • +
+
+
+

Exercise until xx:10 +https://coderefinery.github.io/train-the-trainer/sound/#exercises

+
+
    +
  • room 1

    +
      +
    • Practically, no typical headset is designed or can capture the technical purity of human voice within its natural environment. But one needs to understand the polar pattern of the (specific) microphone or how much of the signal will be picked up by the microphone from different directions, a sine qua non when it comes to mitigating unwanted sound sources to bleed into the signal.

    • +
    +
  • +
+

For best results, keep the right direction & distance to your (directional) mic. Usually, that’s between 15-30 cm to get get a natural sound. A microphone records everything it can, also silence, so check the headphone output BEFORE adjusting the gain, in some specific cases aim for a dry sound, ie the influence of the room or how audible the room is on the recording ! Finally, adjust the mix between dry and room sound, or change the frequency response in tandem using a compressor to reduce the dynamic range of a signal for a more consistent listening experience = the quietest parts of your signal will appear louder by reducing the loudest parts.

+

It is all about one thing and one thing only - love your voice, let people fall in love with the acoustic quality of your charm. So remember: GIGO, it matters!

+
    +
  • Room 3

    +
      +
    • Had different headsets and we could see the difference (bluetooth low quality)

    • +
    • How to change the volume?

      +
        +
      • It’s surprisingly hard to get more control than the basic slider you see in the apps! You need to look.

      • +
      +
    • +
    +
  • +
  • room 4

    +
      +
    • headset is probably better listening experience but they can be uncomfortable to wear during long meeting days :+1:

      +
        +
      • Yeah. Luckily only instructors

      • +
      • Therefore breaks are non-negotiable

      • +
      +
    • +
    • loud keyboard can be an issue

    • +
    • if one has a silent room that does not echo, it can be ok to teach without headset

    • +
    • on Linux I am using pulsemixer to adjust levels and pavucontrol to change outputs/sources

    • +
    • mic modes on mac

    • +
    • check default microphone for zoom.

    • +
    +
  • +
  • room 5

    +
      +
    • Most tricks help tuning yourself but hard to do it as a group. Perhaps doing a short recording.

      +
        +
      • Yeah. Some independent recording/playing aronud, but also asking for advice. I would do small group/one-on-one things.

      • +
      +
    • +
    • Background noises cancellation tools or wise choice of quiet environments

    • +
    • Audio check with colleagues or through the app with the audience saying numbers for example

    • +
    • Zoom or Teams have sound checks but work different in the app than the browser. They also work different across Operating systems

    • +
    • Some sound issues might be related to network speed or stability, also to RAM available. Worthwhile to try and control those as well

    • +
    • Make it welcoming for the audience to give you feedback on the audio and other settings, give reminders

    • +
    +
  • +
+
+
+

Episode 5: How to prepare a quality screen-share

+

Materials: https://coderefinery.github.io/train-the-trainer/screenshare/

+
    +
  • If your Zoom does not support “share portion of screen”, sharing a tab and resizing it to portrait for yourself is a possible workaround (this at least works when joining the call from Chromium browser)

    +
      +
    • Another workaround is to use an editor/IDE that displays multiple panels in one window and can show a web page, code files and terminal session +10

    • +
    +
  • +
  • Is ‘share a portion of your screen’ where you draw a box in Zoom to share a section?

    +
      +
    • yes :+1:

    • +
    +
  • +
  • When using zsh, one can run something like this in a terminal

    +
    tail -n $NLASTCOMMANDS -f ~/.zsh_history | sed 's/^.............../LAST COMMAND:/g'
    +
    +
    +

    (I place this in a window under the main terminal, I use i3)

    +
  • +
  • I am a bit confused on what platform you are putting this code?

    +
      +
    • Radovan is using Linux with (I think) the “i3 window manager”. It can be quite involved and there is lots of personal customization here.

    • +
    +
  • +
  • When teaching with a custom prompt, is it worth starting with the default (that your learners will see) and explicitly mentioning “I change these things to make it clearer when teaching”

    +
      +
    • One should always comment on what may be different. Thing is “default” may look different for many people :+1:

    • +
    • “I am not going to teach you how to customise your prompt, but here’s an online tutorial, be prepared to lose several days of your life…” :laughing:

    • +
    +
  • +
  • Now I can’t see the last line in the terminal

    +
      +
    • Yep, that’s a problem. It can be good to keep a buffer on the bottom of the screen.

    • +
    • If you move your mouse outside the Zoom window, the controls should go away. But still a good note.

      +
        +
      • My mouse was on another screen.

      • +
      • Ok, thanks.

      • +
      +
    • +
    • I think one can also make the zoom bars not auto-hide (then it won’t display under), but that is annoying also since it wastes space.

    • +
    +
  • +
  • Does anybody still use shellshare? Does it work?

    +
      +
    • We in CR haven’t used it much but we have seen it.

    • +
    +
  • +
  • Does the stacking of the screens work on windows?

    +
      +
    • Don’t know unfortunately

    • +
    +
  • +
+
+

Exercises (done together) +https://coderefinery.github.io/train-the-trainer/screenshare/#exercises

+

Write your cool tips and ideas below. +Stay after xx:00, to

+
+
    +
  • To be safe, I have created on my computer an account that I use only for teaching, so I do not need to do any manual set up

  • +
  • share history or jupyter notebooks live (5-10 secs refresh rate) into a git repo. Share the link with the learners so they can catch up https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush

  • +
+
+
+
+
+

Wrapup

+
    +
  • Next session Tuesday August 27 9 CEST: About teaching & cool things we all would like to share

  • +
  • All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • Cool gems session: If you want to share something, please edit your registration and fill it in there (link to modify in registration confirmation); or e-mail to support@coderefinery.org

  • +
  • If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14:00 (Europe/Stockholm time)

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • Sound and screen share optimization as well as relevant tools and good practices for online instruction. “While you may be unable to control your users’ mindset, you can anticipate it, and make sure that your user experience caters to it.” - Jonathan Cherki

  • +
  • Nice opportunity to (re)think about my online teaching setup :+1: :+1: :+1:

  • +
  • Other ways to display command history :+1:

  • +
  • Did not know that bluetooth gear had so much latency! :+1:

  • +
  • A good reminder about headsets with microphones

  • +
  • Nice and friendly teaching. Thank you!

  • +
  • Screen share with command history and terminal customisation

  • +
  • Really useful tips on sound and screen sharing :+1:

  • +
  • Nice experience share

  • +
  • very useful and practical tips!

  • +
  • Easy to follow along and filled with useful tips on sound, video etc.

  • +
  • +
+

What one thing would you improve about this session?

+
    +
  • Just digging to find something: I have read some of the things you have talked about here already in some blog posts, so perhaps these sessions are not as shokingly full of new content as I imagined (but actually sharing experiences is something I can’t do by reading a blog post)

    +
      +
    • Perhaps: could you link some blog posts or other sources for what you have discussed so far? If it makes sense. Not sure.

    • +
    +
  • +
  • Talking about interface optimization approaches, which applies to sound as much as to visuals or any other aspect either for that matter, it might offer a perspective to bear in mind the concept of introducing asymptotic complexity increment. The latter would mean the goal is measuring how fast the effort of engaging, on one or more of the three parallel levels of interaction, must change to reach higher levels of partial certainty on the correctness of the implementation of the method in question, in this case the pedagogical paradigm. For the former, lower is better I guess, or in this case, in the intended sense, slower is faster. Let us consider an abstract example: People liked using the search engine Google (a Google session to put it in a fancy way) in the early days because it was as simple as it could get, a literally featureless entry point with no bells and whistles. That was the level of its visible complexity, or rather Google set a bar as low as it one could have, and then any higher point of VISIBLE complexity that was to be introduced, such a move would only be on the path of an asymptotic curve curving towards the set bar, never reaching it, as far as the entry point is concerned. We still see the same level of complexity when we fire up google and we never feel distracted to start with, except for the rather forgivable nuisance of the GDPR conformity pop-up notice which appears only AFTER the first move has been made, and thankfully it works plain and simple from there on (unless one starts feeling lucky, pun intended). Now, think about Youtube … the user experience complexity is a totally different matter, the same company today (unfortunately) yet one now has a steadily worsening engagement experience. Good learning sessions tend to be more of the Google search engine experience and a far cry from the current Youtube trend I would opine. Or, to sum it up and keep it sweet and simple, it helps to identify the limits of human-human and human-technology interaction, within the framework of any applicable technology-technology interaction and joy is the result of respecting those limits. Wishful thinking ?

  • +
  • Bring the cat back!

    +
      +
    • I wish it came, but it’s been resting all morning! I don’t bother it or stage apperances…

    • +
    +
  • +
  • Maybe having a digest/ summary of previous iterations of this session might be interesting. I feel a lot of experiences have been exchanged and a lot of techniques/ tools have been mentioned. Spending some time in compiling this into a selected list and adding it as content to the course itself might be worthwhile.

    +
      +
    • Good idea! We will write a blog post about this workshop and will include a summary of all discussions there :)

    • +
    +
  • +
  • Possibly have some command line examples from Windows rather than (just) *nix? I will look at the screenshots after the session. :+1: :+1:

    +
      +
    • Also, a thought if you do do breakout sessions with this work, do one for Unix, one for Windows, one for Mac as an option.

    • +
    +
  • +
  • I could not follow the part Radovan showed codes (Radovan is using Linux with (I think) the “i3 window manager”.)

  • +
  • ..

  • +
+

Any other comments?

+
    +
  • Looking forward to the topics of following sessions.

  • +
  • Looking forward to the next sessions!

  • +
  • Thank you!

  • +
  • Relax, nothing else matters, live a life and have fun ! If you obey all the rules you may end up missing all the fun. ‘The best way to predict your future is to create it.’ - Abraham Lincoln :+1:

  • +
+
+
+

Day 3 : sessiion 3 (27.08.24) - “About teaching and cool things we all would like to share”

+
+

:calendar: Schedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 9.45

Computational thinking

10.15 - 10.45

8.15 - 8.45

9.45 - 10.00

Break

10.25 - 11.00

8.25 - 9.00

10.00 - 10.30

Teaching philosophies

11.00 - 11.30

9.00 - 9.30

10.30 - 11.00

Co-teaching

11.30 - 12.00

9.30 - 10.00

11.00 - 11.15

Break

12.00 - 12.15

10.00 - 10.15

11.15 - 11.50

Sharing teaching gems (voluntary)

12.15 - 12.50

10.15 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+

:icecream: Icebreaker

+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • +
  • :sleeping:

  • +
  • :coffee:+2

  • +
  • :robot:

  • +
  • Still little sleeppy :)

  • +
  • 🥴 (:woozy_face: still not converted 🤷‍♂️)

  • +
  • Our planet could be a cube. It has six sides to it. It must be a cube. A cube it is, this Blue Planet … just wondering …

  • +
  • 🦾

  • +
  • :sweat_smile:

  • +
  • computer says no :-) some network trouble

  • +
  • running late, and participating from a :train2:

  • +
+
+
+
Introduction in breakoutrooms
+

Name / Affiliation / Location

+
+
+
Best classroom experiences
+

As a learner or teacher; what was the best workshop/lesson/seminar you have attended? What made the experience great?

+
    +
  • Room 1

    +
      +
    • First summer HPC streamed workshop (as a teacher). Somehow the first felt the best

    • +
    • CSC HPC summer workshop

    • +
    • story telling teaching approach

    • +
    +
  • +
  • Room 2

    +
      +
    • NVIDIA DLI Course on Deep Learning

      +
        +
      • very enthusiastic instructor

      • +
      • intuitive and very accessible way of showing technical details and fostering deeper understanding

      • +
      • a lot of hands-on material and smaller coding exercises

      • +
      +
    • +
    • Anything as long as its interactive and somehow enjoyable from both teacher and learner sides

    • +
    +
  • +
  • Room 4:

    +
      +
    • EPCC MPI Distributed training workshop.

      +
        +
      • Lots of hand on coding / experience gained.

      • +
      • Very interactive instructor who also discussed ideas for more personalised cases of distributed computing.

      • +
      +
    • +
    • Coderefinery RSE course

      +
        +
      • relevance of topic to my current work.

      • +
      • Dynamic / friendly / positive teaching style.

      • +
      • Modular Code Development; very instructive

      • +
      +
    • +
    • Some CSC courses / LinkedIn learning courses

      +
        +
      • up to date materials and topics.

      • +
      • Good way to merge theory with practicalities without making learner feel bored (Example: Jonathan Reichental)

      • +
      • Challenging information to learn more and research about the topic

      • +
      • Trainers are the experts in the field

      • +
      +
    • +
    +
  • +
+
+

Episode on teaching gems

+

If you want to share or demo something about tools and techniques you have found helpful in your teaching, please add your name/initials and rough topic below for smooth transition.

+
+

Note: It does not have to be your tool or your idea, this episode is meant to share experiences and discover new things. You also do not need any slides or materials, a story will do fine :) +Length of the stories will be depending on interest, but be prepared to fit it into 3 min (shortest possible).

+
+ +
+
+
+
+
+
+

:question: Questions

+
+

General / Practicalities

+
    +
  • What is this document for?

    +
      +
    • Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts)

    • +
    +
  • +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms?

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    +
  • +
+
+
+
+

Episode 1 : Computational thinking

+

Materials: https://coderefinery.github.io/train-the-trainer/computational-thinking/ (Link to slides in the middle of material)

+
+
Questions to audience
+

How might breaking down a complex problem into smaller parts change your approach to problem-solving in your current projects?

+
    +
  • Avoids cognitive overload

  • +
  • I used to give an example about this in workshops of cutting long tree into pieces from top to avoid that it falls and destroy a house bloc.

  • +
  • Easier to start on something small

  • +
  • Each individual part is familiar and can take existing solutions.

  • +
  • Only focus on the new things

  • +
  • One can lose oversight of where is supposed to be getting to due to problems with summation of biases introduced during the solving of the parts.

  • +
  • .

  • +
+

Can you think of a research project where identifying patterns in your data led to new insights or breakthroughs?

+
    +
  • Multi-targeted drug design where you need to identify both chemical and biological pathways/patterns

  • +
  • Distilling complex physics problems into simpler 1D statistics is very often done.

  • +
  • I used to do bioinformatics, pretty much everything in biology is about patterns in strings of charachters (DNA, proteins). Finding those patterns and using them is the way to go

  • +
  • Pattern recognition DOES NOT lead to new insight, it is new insight which allows for the recognition of a ‘pattern’, the latter being an allocation of possible bias.

  • +
  • +
  • ..

  • +
+

What challenges do you face when trying to simplify complex concepts in your field, and how do you decide which details to focus on?

+
    +
  • Absence of a terminology / jargon to describe a new idea. :+1:

  • +
  • Similar to above, when teaching often students know what they want to achive, but don’t have the termonology to express it, so working through what they want is helpful, after teaching them some termonology.

  • +
  • Whatever is most useful to the learner first?

  • +
  • I work with researchers in different fields. I don’t always fully understand their domain knowledge but I can take the basiscs or generalities and get code that works for them

  • +
  • A very practical problem is trying to resist going for a coffee in the midst of taking a shot at a complex concept, in the hope that the true details are to be found in the coffee.

  • +
  • not all information is easy to find or a lot of conflicting information or even sometimes imformation explosion

  • +
+

How do you determine the priority of tasks when designing algorithms for your academic projects, and what criteria do you use to ensure that the most critical tasks are addressed first?

+
    +
  • Working chronologically when going through a problem - start at the beginning.

  • +
  • What gives the more insight with the least effort can be a nice start

  • +
  • Talk to colleagues and Subject matter experts to understand various perspective to decide and prioritize.

  • +
  • Logic will get you from A to B. Imagination will take you everywhere. - Albert Einstein.

  • +
  • ..

  • +
+
+
+
Questions from the audience
+
    +
  • About the 4 core concepts, is this based on the model of how human brain works and perceives vision / abstract ideas?

  • +
  • I don’t know if it’s based on how the brain works, but it’s related to creating a framework for solving programming programs that has been extrapolated to solve any other problem as well.

  • +
  • Devil’s advocate question: cooking (by recipe) actually employs all four principles outlined here and has done so since before the advent of computers. Why then is this concept presented as “computational”?

    +
      +
    • Random aside, this is an interesting connection to our “cooking metaphor to HPC”

    • +
    +
  • +
  • Devil’s answer to the Devil’s advocate: Great question, cooking, as far as the act happens in the Devil’s kitchen, does not employ numerical algorithms. The Devil introduced the computer precisely to make man lose apetite for that what is cooked in the Devil’s kitchen to be served to all. Only then can the Devil eat the cake and keep it too …

    +
      +
    • Well, an algorithm without numbers is still an algorithm, i.e. a set of rules :)

    • +
    +
  • +
  • Are there other names for this technique? I may have missed something crucial, but it strikes me as ‘logical thinking’ in a way.

    +
      +
    • Yes, you could also just see it as problem solving. Most people know how to do it and if you’ve worked with programming, you’ve probably applied it. It can be the case that it’s very obvious to some, but not to others.

    • +
    +
  • +
  • Any chance we can ge a link to the slides?

    +
      +
    • They are in the course material: https://coderefinery.github.io/train-the-trainer/computational-thinking/ :thumbs_up:

    • +
    +
  • +
+
+
+
Exercise questions to discuss
+
    +
  1. Conceptually would the strategies provided by computational thinking help you in completing tasks more efficiently?

  2. +
+
    +
  • Room 1:

    +
      +
    • divide and conquer technique

    • +
    • We discussed what happens if you don’t use these, since they are so natural

    • +
    +
  • +
  • Room 2:

    +
      +
    • in some cases yes, if the task is not too small

    • +
    • not sure if more efficiently but it does help at least getting strted

    • +
    • Computational thinking is an extension of what others have called solutionism: the belief that any given problem can be solved by the application of computation. Whatever the practical or social problem we face, there is an app for it. - James Bridle

    • +
    +
  • +
  • Room 3:

    +
      +
    • Helps in starting the task.

    • +
    • For many it is the normal way to do problem solving. Also in Agile & Scrum methodlogies.

    • +
    +
  • +
  • Room 4:

    +
      +
    • Yes, it helped me during my scientific research to manage multiple projects and research publications simultaneously.

    • +
    • +
    +
  • +
+
    +
  1. Do you think that the effectiveness of computational thinking depends on the person’s personality type?

  2. +
+
    +
  • Room 1:

    +
      +
    • yes, we agree it’s quite different. But good vision and motivation this can be effective

    • +
    +
  • +
  • Room 2:

    +
      +
    • yes, laying out all the steps necessary to achieve an overall goal can be very daunting; some people are not good at/ comfortable with following fine-grained instructions

    • +
    • once the problem is broken down, different personalities might choose different ways to tackle the parts

    • +
    • The degree to which something, that is a result of what one means by ‘Computational Thinking,’ is successful in producing a desired result, that is success, cannot be a function of personality.

    • +
    +
  • +
  • Room 3:

    +
      +
    • Yes. Different people have different ways to communicate.

    • +
    • Online tools vs pen and paper

    • +
    +
  • +
  • Room 4:

    +
      +
    • We are all agree that it depends on the personality type but it could be learned and trained

    • +
    +
  • +
+
    +
  1. Would this type of thinking be an option for you to integrate into your current workflow?

  2. +
+
    +
  • Room 1:

    +
      +
    • Yes; we didn’t know the name explicitly; but we use it

    • +
    • It’s quite important for

    • +
    +
  • +
  • Room 2:

    +
      +
    • I’m already doing it implicitly :smile: :+1: :+1:

    • +
    • Writing a program is like writing a song, its all about the tune, lyrics are merely the necessary nuisance a coder needs to put up with. The latter can, if so written, result in a lot of noise.

    • +
    +
  • +
  • Room 3:

    +
      +
    • Easy if you are working alone. But different team may have their own ways of working (inertia). One way would be then to gradually show the rest of the team its effectiveness.

    • +
    • https://teamtopologies.com/key-concepts

    • +
    +
  • +
  • Room 4:

    +
      +
    • We are using it in our daily life so it’s already an option for us, only the terminologies are a bit new.

    • +
    +
  • +
+
+
+
+

Episode 2 : Teaching philosophies

+

Materials: https://coderefinery.github.io/train-the-trainer/teaching-philosophies/

+

Questions to discuss:

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+

Breakout Room exercise

+
    +
  • Room1

    +
      +
    • Motivation

      +
        +
      • For best practices in teaching, learning from each other, collaboration

      • +
      +
    • +
    • Learning applied tech is like an apprecentiship: there is theory, but real learning happens by co-working with others.

    • +
    • Worse is better: teach what can be used more quickly and it can be improved later

    • +
    • +
    • I think there are two bits of teaching - teach the basics and terminology so people know what they want to know, and then teaching how to find out how to do things like Richard said - how to find answers yourself.

    • +
    • Using Jupyter notebooks - good for learning a technique, but not for learning the basics.

    • +
    • Possibly command line usage has a branding problem - “programming other programs”?

    • +
    • the skills we learn in CR training are expected to stay , it is not exam oriented

    • +
    +
  • +
  • Room 2

    +
      +
    • State objectives clearly and repeat them a few times

    • +
    • Try to keep it informal, interactive, flexible

    • +
    • Helps when having practical tasks in mind for the materials taught

    • +
    • Leave some reasoning to the learner, not always giving full answers

      +
        +
      • How to deal with frustration though: try some personal approaches, more clues…

      • +
      +
    • +
    • The mediocre teacher tells. The good teacher explains. The superior teacher demonstrates. The great teacher inspires. — William Arthur Ward

    • +
    • Teaching kids to count is fine, but teaching them what counts is best. –Bob Talbert

    • +
    +
  • +
  • Room 4

    +
      +
    • Question 1: What is your motivation for taking this training?

      +
        +
      • Currently do instruction, wanting to improve as an instructor and helper when conducting software carpentries.

      • +
      • Planning to start some side hustles providing online courses and why not joining the CR in the near future

      • +
      +
    • +
    • Question 2: How structured or informal are your own teaching needs?

      +
        +
      • More recently, follow software carpentries, but look into what aspects can be tailored to keep to different time slots.

      • +
      • I used to be more informal in the past, repetetive practice sessions. Would like to be more structured given the teaching tools.

      • +
      • I’ve done life-coaching and some teaching but I feel i’m both of them

      • +
      +
    • +
    • Question 3: What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

      +
        +
      • Smaller size, and more targetted.

      • +
      • Collaborative tools and targeted audience working with small groups

      • +
      • Academic probably focuses on an audience with a more focused/narrow background, while this style encompasses a wider audience.

      • +
      • Academic teaching keeps theory and practical lab sessions very separate, whereas carpentries combine both.

      • +
      +
    • +
    • Question 4: What other skills need to be taught, but academic teaching isn’t the right setting?

      +
        +
      • Public speaking, collaborative meeting skills

      • +
      • Industrial cases and related work skills

      • +
      +
    • +
    +
  • +
+
+
+

Episode 3: Co-teaching

+

Materials: https://coderefinery.github.io/train-the-trainer/co-teaching/

+
    +
  • In general: Co-teaching is a beast with at least two personalities each of which

    +
      +
    • demand higher preparation requirements

    • +
    • face remarkable complexity in terms of coteacher coordination

    • +
    • in the virtual component face shortcomings related to the technical equipment and the failure of the human factor

    • +
    +
  • +
+
    +
  • Co-teaching requires the framework of co-operative learning. Team teaching does not by default translate into parallel learning, and vice versa.

  • +
+
    +
  • Re: CodeRefinery in-person beginnings – I agree with the “didn’t work so well in-person”, I’m not sure if it’s that we weren’t as ready for it, or that the different characteristics made it not work so much

  • +
  • How do the downsides compare to a single instructor monologuing?

    +
      +
    • That’s a great question! The main difference is that a single instructor can teach himself to be good (i.e. not just boring monologuing) alone, while for teams of 2+ to work well, everyone needs to be baseline-competent. So the effort to avoid downsides gets reduced if (and only if) all team members share it.

    • +
    +
  • +
+
+

Exercise/Discussion: https://coderefinery.github.io/train-the-trainer/co-teaching/#exercise

+

Questions:

+
    +
  • Have you already tried this or similar model in your teaching?

  • +
  • Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best?

  • +
  • Have you tried or seen a different model for two instructors to present? Please share with us how it works.

  • +
+
+
    +
  • room 1

    +
      +
    • We have tendend to do presenter/interviewer more

    • +
    • challenges are co-teaching with different personalities

    • +
    +
  • +
  • room 2

    +
      +
    • Main challenge: finding enough personell :smile:

    • +
    • It’s not always possible/feasible to have colleagues co-teaching

    • +
    • A combination of both, but presenter and interviewer could be difficult to plan an to follow

    • +
    • Guide and demo-giver with technical / non-technical roles could be nice

      +
        +
      • How to plan the guide and demo-giver

        +
          +
        • First guide, then demo

        • +
        • Demo, then guide describes

        • +
        +
      • +
      +
    • +
    • Alternative model: main presenter + ‘technical expert’

      +
        +
      • main presenter introduces concepts from a birdseye view and passes on to the technical expert for additional details, experiences and answers to questions from the audience

      • +
      +
    • +
    • We frequently do a classical division: on person in presenting, one or more are answering questions in the chat; there is rarely any interaction between them however

    • +
    +
  • +
+
    +
  • As has been pointed out by Paolo Freire, in general, ‘education is suffering from narration sickness’ … ‘The outstanding characteristic of this narrative education, then, is the sonority of words, not their transforming power’. Perhaps one approach could be to rephrase the question after having the answer: It is not apriori about the model implemented, it is about whether that what was implemented was judged aposteriori to have succeeded in becoming, or at least could pretend to have done so, the intended context matched model implementation it probably was computed to be.

  • +
+
    +
  • room 4

    +
      +
    • the co-teaching approach does not seem to be widely practiced

    • +
    • it can be interesting to see “mistakes” which are less likely to happen in solo-teaching?

    • +
    • co-teaching can be nicer for audience but maybe more stress/anxiety for instructors to prepare? more stress in terms of not knowing all the questions in advance. less stress worrying about forgetting something.

    • +
    +
  • +
+
+
+

Teaching gems

+

(scroll up to find the green box “Episode on teaching gems”)

+

What’s your favorite way of teaching? Any nice tools you use?

+

Has anyone found a nice online tool to draw?

+
    +
  • I love this tool suite https://excalideck.com/

    +
      +
    • For drawing https://excalidraw.com/

    • +
    +
  • +
  • I have seen Miro …

  • +
  • I think the Code Refineries use something for their graphics that looks a bit ‘cartoony’ - but I cannot remember what it is called!

    +
      +
    • Drawn on remarkable and then coloured and tidied up in Inkscape. :+1:

    • +
    +
  • +
  • I am a big fan of remarkable. I think sharing option is fairly good. Unfortunately bit expensive tool.

    +
      +
    • true, for me it was worth it already for the pdf annotation for research papers, cannot read on computer screen

    • +
    +
  • +
  • https://webwhiteboard.com/

  • +
  • https://www.youtube.com/watch?v=4-l8MY5kYGc

  • +
  • Figma and Kahoot are useful as well

  • +
+

Screenkey: Screenkey for showing keyboard shortcuts

+
    +
  • Is there a Windows version people can recommend?

    +
      +
    • I found this list of alternative for windows users like me: https://alternativeto.net/software/screenkey/ :+1:

    • +
    +
  • +
  • I sometimes use the on-screen keyboard already provided by the OS :+1:

  • +
+
+
+
+

Wrapup

+
    +
  • Next session Tuesday September 3rd 9 CEST: About teaching & cool things we all would like to share

  • +
  • All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14 CEST

  • +
  • Preparations for next week will be sent out by e-mail

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • The co-teaching lesson and experiences from others

  • +
  • Discussions were quite good, had a nice group

  • +
  • Breakout rooms and collaborative tools

  • +
  • Computational thinking and co-teaching are interesting ideas! I have seen it before, but never knew or even recognized it was a method.

  • +
  • Thanks for group discussions working with my chat only interaction! :smile:

  • +
  • ..

  • +
+

What one thing would you improve about this session?

+
    +
  • Minor point - it would be useful to have the teaching gmes box at the bottom of the document rather than the top - tricky to scroll between! In the end I opened two windows which was easier.

    +
      +
    • Thanks, yes agree. Also had that problem, but did not want to move it in between.

    • +
    +
  • +
  • The meaning of teaching “philosophy” wasn’t very clear, felt more like teaching “styles”

    +
      +
    • Thank you, we will take that into consideration

    • +
    +
  • +
  • Some prepared slides to present for an intro about the topics

    +
      +
    • You mean in addition to the materials? To use in the beginning of each session?

    • +
    +
  • +
  • The instructor views segment could be named as additional material, if it was not meant to be discussed within the course.

    +
      +
    • Thank you, we will take that into consideration

    • +
    +
  • +
+

Any other comments?

+
    +
  • Keeping it short and sweet: If at first you don’t succeed in teaching, try to explain it like you’re talking to a room full of cats. Caveat: In a room full of computational thinkers maybe if you tell students that the brain is a computational device that is forbidden, they might get excited and start using it.

  • +
+
+
+

Day4: Session 4 (3.09.24) - Streaming and video editing

+
+

:calendar: Schedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 10.00

Why we stream & Behind the scenes

10.15 - 11.00

8.15 - 9.00

10.00 - 10.15

Break

11.00 - 11.15

9.00 - 9.15

10.15 - 10.35

Video Editing

11.15 - 11.35

9.15 - 9.35

10.35 - 10.55

Exercise: Video Editing

11.35 - 11.55

9.35 - 9.55

10.55 - 11.10

Break

11.55 - 12.10

9.55 - 10.10

11.10 - 11.30

Open Broadcaster Software(OBS) introduction

12.10 - 12.30

10.10 - 10.30

11:30 - 11:50

OBS setup & what next

12.30 - 12.50

10.30 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+

:icecream: Icebreaker

+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :coffee: +

  • +
  • :runner:

  • +
  • :tired_face: Tired!

  • +
  • :nerd_face:

  • +
  • +
  • :cloud: :tea:

  • +
+
+
+
Introduction in breakoutrooms
+
    +
  • Name / Affiliation / Location

  • +
+

What’s the most number of people you have taught to?

+
    +
  • 20 at a time, with 1 asleep, 2 fidgiting with some silly device and the rest were… well… staring at their good luck… straight ahead it was of course, right before them.

  • +
  • ~35

  • +
  • ~80 in a lecture in a previous (lecturer) role, 26 in a training course setting

  • +
  • ~30

  • +
  • ~50 in training spaces and more than 100 for public audience talk

  • +
  • 35 (software carpentry)

  • +
  • CodeRefinery answer: The biggest ones are maybe 200-300 people. “small” for a stream is ~100 people.

  • +
+

What’s the most number of people you have taught with?

+
    +
  • 5 or so

  • +
  • 2 or 3 in total

  • +
  • 3, as in three, none of them smiling. I wish I could figure out why… it was such fun really…

  • +
  • 7

  • +
  • 2 or 3

  • +
  • 3 (helpers, not really co-teaching)

  • +
  • CodeRefinery answer: our biggest workshops are something like 10-20 people helping out in many different roles.

  • +
+

How can you divide teaching into separate independent tasks?

+
    +
  • By content blocks, having roles like main and assistant…

  • +
  • Having responsibility for different sections of the course.

  • +
  • Wow, now thats what we call a question… bravo… indeed, how does one separate sleeping and snoring into separate independent tasks…

  • +
  • Course, exercices, resources, tools and forms.

  • +
  • Different people teach different topics

  • +
  • CodeRefinery answer: the big logical blocks are instructors, in-person and breakout room helpers, and Notes-questions answers.

  • +
+

What’s the most interesting or useful thing you’ve learned from an online workshop, and how have you applied it/planning to apply in your life or work

+
    +
  • Having breaks every hour or so

  • +
  • New approach to screensharing, using the ‘portrait’ approach

  • +
  • Manage breathing: reduce stress and use silence to let the audience grasp what you’re saying

  • +
  • Well, the most interesting or useful thing I’ve learned from online workshops is how not to conduct a workshop, or at least some elements of the same, and I have applied this understanding by engaging in the global effort to discover more about how not to conduct a workshop, or at least some elements of the same, with the motto: That’s one small step for a man, one giant leap for mankind..

  • +
+
+
+
+

:question: Questions

+
+
+

Why we stream

+
    +
  • If during streaming there is no interaction between the teacher and the audience, why don’t we just record the lectures and stream them? So one can do a better job, perhaps?

    +
      +
    • Streaming it making it a “thing” that’s a group experience. It feels good to be a part of it, so we hope that encourages people to actually attend. All the mass Q&A is fun, and the audience helps to make it easier to present. Still, this is a good question.

    • +
    • I really appriciate it being “a thing”. If it was just recorded, I would say I would watch it tomorrow, and then I never would.

      +
        +
      • But then you can just fake it, and still have all the breakout rooms and collaborative document and so on. I appreciate the value of having a proper “event”.

        +
          +
        • I think I follow you, but if you pre-recorded the talking bits, then the presentors couldn’t change what they do based on the feedback in the shared document.

          +
            +
          • true, but I assumed that the teachers were too busy to actually do that. The more (less )division of labor between the teachers and the helpers (or collaborative document editors), the more (less) sense it makes to pre-record - IMHO

          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • What interaction options do ‘streamers’ use, e.g. on Twitch/YouTube (not Code Refinary)?

    +
      +
    • I’m besides chat and things that happen in chat, I’m not sure. The Notes-doc is definitely unique to us.

    • +
    +
  • +
  • Streaming is a kind of exercise for the movie star type. If you cannot be one, act like one, pretend, fool the listener into thinking you are one, take their brains and emotions under control. And if they don’t leave the session with tears of love for learning running down their chubby cheeks you know who to kick for doing a job just that bit worse than it should have been necessary.

  • +
  • Have you kept track of streming stats? like how many people logged in and stayed troughout, how many interacted?

    +
      +
    • Yes please, it would be good to see the stats

    • +
    • Here is stats repo

    • +
    • Thanks, I get a 404 error, is it private?

    • +
    • No, I don’t think so. https://github.com/coderefinery/workshop-stats

    • +
    • Still get 404. Does it work for anyone else?

      +
        +
      • Yeah I think it’s private. We need to fix this…

      • +
      +
    • +
    +
  • +
  • How big is small (10-15), medium (~30-40)?

    +
      +
    • I would say below 50 is small.

    • +
    +
  • +
  • Have you considered scaling to more events instead of to a larger audience? I mean, this seems the opposite of scaling, but this kind of content would be more useful the more often is it taught (“I need to learn GIT/Python/* in December!”)

    +
      +
    • We would, but right now we simply don’t have enough time and people to do more small events. But yes, “scheduling conflict” is a big problem - the best we can do right now is written material+videos to follow up on (and hope it’s interesting enough)

    • +
    • Python for Scientific Computing 5-7/November/2024

      +
        +
      • This was just an example. I mean, if I am a PHD student that needs to start working on a topic on Month X which happens to be inconveniently placed in the year, I will not benefit as much from having a workshop at Month X+3

        +
          +
        • The materials are open and the videos are publically available on YouTube channel

          +
            +
          • What’s the ratio of people watching videos afterwards vs people attending the event? That ratio can give an idea of the popularity of the two possible approaches.

          • +
          +
        • +
        +
      • +
      +
    • +
    • The more you scale up the less interactive the course / workshop will need to be. It then becomes a question of priorities, and if teaching is a lower priority then learning than I guess there really should be no prizes for guessing which approach should reign the airwaves.

    • +
    +
  • +
  • I guess outside Europe / Africa, time zones could be a problem?

    +
      +
    • yes, that is true

    • +
    • +
    +
  • +
  • Sorry, I might have missed this: have you been rehearsing and/or doing dry runs?

    +
      +
    • With instructors I like to try to do a dry run. I often don’t do a live broadcast dry run these days since I’m confidente enough, but when you are just starting, it’s a good idea.

    • +
    +
  • +
  • Do you always use Zoom for the ‘presenter end’ or have you tried other things? Teams? Jitsi? etc.?

    +
      +
    • we use mostly zoom

    • +
    • It was first pioneered using Jitsi. You can probably use others, too.

    • +
    +
  • +
  • A comment: for deRSE24 we have been using the GWDG streaming service and OBS, it worked quite well (with a 20s delay or so)

    +
      +
    • Cool! Yes, there is plenty of livestreaming options. Twitch+our OBS config gives us 2-3s of latency (which is low enough for live Notes interaction). You might be able to tune this if needed.

    • +
    +
  • +
+
+
+

Behind the stream

+
    +
  • Does OBS take a lot of RAM or CPU? what are the specs on your machine?

    +
      +
    • Richard have a relatively powerful computer with 8 AMD CPUs.

    • +
    • 4 CPUs are relatively enough for a good OBS setup, most important is a stable internet connection (ideally wired).

    • +
    • An extra monitor is recommended for the setup

    • +
    • See the hardware notesrecommendation here

    • +
    +
  • +
  • Do you do a screenshare from Zoom -> OBS or OBS -> Zoom?

    +
      +
    • Instructors share to Zoom, OBS captures Zoom, OBS sends to the world.

    • +
    • When I am using OBS sfor a single-person presentation recording, I go the other way: OBS captures my desktop/camera, OBS generates the preview window, and then Zoom captures and broadcasts the preview window.

    • +
    +
  • +
+
+
+

Video editing

+
+
Poll
+
    +
  • Have you tried video editing? Add ano as answer below

    +
      +
    • yes: ooooo

    • +
    • no :

    • +
    • Video editing makes all the difference. I have never known a way to avoid this sacred of steps, so to speak. In short, no recording can ever be production ready by default in the books of the wiser among the streamers. In fact, during the editing one can considerably refine and improve the learning experience in great ways. But then one would need to invest both time and effort.

    • +
    +
  • +
  • If yes Which are the tools you use?

    +
      +
    • Windows Movie Maker / ClipChamp

    • +
    • (raw stream from Zoom)

    • +
    • I think it was shotcut - I did only basic trimming

    • +
    • Kdenlive

    • +
    • Clipchamp, OpenShot, Sony Vegas

    • +
    • also ffmpeg from command line to cut beginning and end

    • +
    +
  • +
+
+
+
Questions
+
    +
  • What is Whisper?

    +
      +
    • Open-source model from OpenAI that converts speech to text transcripts.

    • +
    • this one? https://openai.com/index/whisper/

    • +
    • curious if anyone has tried it with languages other than english

    • +
    • I heard that one of my spanish colleague try it with another software. I don’t remember the tool. But with AI bloom there are many licensed tools that can do it with fifferent language

    • +
    +
  • +
  • What do you use to crop the videos?

    +
      +
    • I see now, ffmpeg

    • +
    +
  • +
  • how to merge multiple parts in one? I asked because you edited only the icebreaker part?

    +
      +
    • you can manage it in input part, see ffmpeg-editlist readme.

    • +
    +
  • +
  • Do you generate custom thumbnails for the video?

    +
      +
    • no, because of the time, but its good to have. If we had a volunteer to manage that, then we should!

    • +
    +
  • +
  • Does anyone recommend any other (GUI) tools that work well? ffmpeg is very new to me!

    +
      +
    • if you want a basic trimming and editing , you can use Quicktime player/imovies on mac

    • +
    • Clipchamp as the Microsoft video editor

    • +
    • Thanks :smile:

    • +
    +
  • +
  • How do subtitles get uploaded to YouTube?

    +
      +
    • You upload the video and subtitles as part of upload.

    • +
    • :+1:

    • +
    +
  • +
  • How does codewhisperer compare against youtube’s automatically generated subtitles?

    +
      +
    • by experience, whisper was better couple of years ago. We haven’t compared it recently

    • +
    • I guess and advantage is that you can edit whisper subtitles in case something is odd or whatever, probs cannot do that in YouTube

    • +
    +
  • +
+
+
+
+

Open Broadcaster Software (OBS) introduction & setup

+
    +
  • Are the profiles public?

    +
      +
    • Yes, you can see it here

    • +
    +
  • +
  • Does it work in Linux+Wayland?

    +
      +
    • I think everything we do with OBS would.

    • +
    +
  • +
+
+
+
+

Wrapup

+ +
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • ffmpeg seems great, will give a try for fun!

  • +
  • great to see everything in practice!

  • +
  • Very insightful to see what happens behind the scenes.

  • +
+

What one thing would you improve about this session?

+
    +
  • Some more interactivity would’ve been nice but since most the group preferred demo instead of exercise perhaps it’s only a personal opinion

  • +
  • It would have been good to share the OBS profiles repo beforehand in the setup email - so I could have had it to hand. (https://github.com/coderefinery/obs-config)

    +
      +
    • +1 good idea, we should do this next time

    • +
    +
  • +
  • Perhaps a simpler starter OBS setup?

    +
      +
    • Good idea… I should have, but basically ran out of time to prepare.

    • +
    +
  • +
+

Any other comments?

+
    +
  • Cool to see the switch from RSE to trainer to AV guy, impressive!

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/objects.inv b/objects.inv new file mode 100644 index 0000000..cba69ae Binary files /dev/null and b/objects.inv differ diff --git a/obs-config/index.html b/obs-config/index.html new file mode 100644 index 0000000..f8717f9 --- /dev/null +++ b/obs-config/index.html @@ -0,0 +1,276 @@ + + + + + + + Open Broadcaster Software (OBS) setup — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Open Broadcaster Software (OBS) setup

+
+

Objectives

+
    +
  • See how to configure OBS using the pre-made CodeRefinery scene +collections

  • +
  • Modify the collections to suit your needs.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: ?? min

  • +
  • Hands-on: ?? min

  • +
  • Q&A: ?? min

  • +
+
+ +

In this lesson, we’ll see how to configure OBS from scratch for your +purposes. We’ll do this by deleting the instructor’s configuration +and trying to recreate it

+

This section is short, since it has never been done before: we’ll just +give it a short and update the lesson later.

+
+

CodeRefinery OBS configs

+
    +
  • CodeRefinery configs are shared in a repository: +https://github.com/coderefinery/obs-config

  • +
  • These can be imported to pre-configure some things

  • +
  • There are two types of configs:

    +
      +
    • Profiles

      +
        +
      • Servers, resolutions, audio, video, etc.

      • +
      +
    • +
    • Scene collections

      +
        +
      • The graphical layouts.

      • +
      +
    • +
    +
  • +
+
+
+

Installing the OBS config

+
    +
  • Clone the git repository.

  • +
  • Import the profile and scene collections under their respective +menus.

  • +
+
+
+

Initial setup

+
    +
  • Click through each menu and change anything that is needed

  • +
  • Set the streaming server

  • +
+
+

The instructor will go through the setup.

+
    +
  • Reset configuration: mv .config/obs-studio/ .config/obs-studio-old/

  • +
  • Import profiles/TeachingStreamingv3/

  • +
  • Import scenes/TeachingStreamingZoomv3.json

  • +
+
+
+
+

Set up the remote control

+
    +
  • Create a Python environment and install it: pip install https://github.com/coderefinery/obs-cr/archive/refs/heads/master.zip

  • +
  • Run it: python obs_cr/control.py localhost:4445 TOKEN --broadcaster

  • +
  • There are more options but let’s not cover them yet… and leave +this for a hands-on session.

  • +
+
+
+

Setup before each course

+
    +
  • Re-confirm audio

  • +
  • Re-confirm each scene

  • +
  • Test everything

  • +
  • rkdarst has a rather long +checklist, +but each individual step is short.

  • +
+
+
+

Q&A

+

We’ll answer audience questions.

+
+

Keypoints

+
    +
  • Most of our configuration has been OBS may seem complicated, but it’s a graphical application and most +pieces make sense once you know how it works.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/obs/index.html b/obs/index.html new file mode 100644 index 0000000..205a80a --- /dev/null +++ b/obs/index.html @@ -0,0 +1,259 @@ + + + + + + + Open Broadcaster Software (OBS) introduction — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Open Broadcaster Software (OBS) introduction

+
+

Objectives

+
    +
  • Understand that OBS is a video mixer.

  • +
  • Understand the basic controls and features of OBS.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 15 min

  • +
  • Q&A 5 min

  • +
+
+ +

In this episode, you’ll get more familiar with the OBS portion of the +streaming setup. You’ll see how it’s used, but not yet how to +configure it from scratch. You’ll learn how to be a “director”.

+
+

What is OBS?

+
    +
  • Formally “OBS Studio”

  • +
  • Most commonly known as a livestreaming application.

  • +
  • Open source, free.

  • +
  • Cross-platform, easy to use screencasting and streaming application.

  • +
  • Real-time video mixer.

  • +
+
+
+

OBS user interface

+
    +
  • We’ll click through each view.

  • +
  • What does each view do?

  • +
  • Let’s click through the buttons.

  • +
  • Let’s see the important config options.

  • +
+
+
+

OBS during a course

+
    +
  • What management is needed.

  • +
  • The control panel.

  • +
  • Audio.

  • +
  • Adjusting windows and so on.

  • +
+
+
+

Hardware requirements

+
    +
  • Reasonably powerful broadcast computer

    +
      +
    • CodeRefinerys streaming computer is 8 CPU AMD, 64GB memory

    • +
    • That is way overkill: a powerful laptop can probably do this.

    • +
    +
  • +
  • Large second monitor for laying out the windows you capture

  • +
  • Stable internet connection (wired preferable)

    +
      +
    • CodeRefinery’s broadcast is the slowest purchasable: 100 Mbit down / +25Mbit up

    • +
    +
  • +
+
+
+

Q&A

+

We’ll answer audience questions.

+
+
+

See also

+ +
+

Keypoints

+
    +
  • OBS may seem complicated, but it’s a graphical application and most +pieces make sense once you know how it works.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/overview/index.html b/overview/index.html new file mode 100644 index 0000000..c63b95c --- /dev/null +++ b/overview/index.html @@ -0,0 +1,418 @@ + + + + + + + A workshop seen from different perspectives — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

A workshop seen from different perspectives

+
+

Objectives

+
    +
  • Understand the general structure of CodeRefinery workshops and why it is the way it is

  • +
  • Get to know the different roles of a workshop and which ones are the most essential ones

  • +
  • Understand the importance of installation instructions and how they contribute to learners success

  • +
  • Understand the importance of onboarding and a welcoming community for volunteers in a workshop

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 15 min

  • +
  • Roles journeys can be shortened to looking only at instructor role.

  • +
+
+
+

Note

+

This episode focuses on the large scale streamed workshop setup. Some of the features can also be applied to smaller scale workshops though.

+
+
+

Discussion

+
+

Discussion

+

In breakoutrooms: choose one or two questions to talk about your own experiences; summary in collaborative notes:

+
    +
  • What kind of roles have you been in yourself regarding workshops?

  • +
  • How were you prepared for your role?

  • +
  • What are the things you would like to know before a workshop?

  • +
  • How are you preparing your participants for your trainings?

  • +
  • What was the best workshop experience for you as learner, helper or instructor? What made it great?

  • +
+
+
+
+

One workshop - many parts

+
+../_images/CR_workshop_setup.png +
+

Image showing the different phases of a CodeRefinery workshop described below. Also showing that while there is only two people teaching, many people work behind the scenes.

+
+
+
+

Before the workshop

+
    +
  • During winter/summer: “Someone” takes the coordinator role for the next workshop

  • +
  • Coordinator fills other roles:

    +
      +
    • Coordinator: collects necessary lesson updates, supports other coordinators

    • +
    • Registration coordinator: Sets up web page, starts and manages registration

    • +
    • Instructor coordinator: Finds instructors and onboards them

    • +
    • Advertising coordinator: Prepares advertizement texts and finds people to distribute them

    • +
    • Team coordinator: Gathers local organizers/teams

    • +
    • Bring your own code session coordinator: If available, offer BYOC session after main workshop

    • +
    +
  • +
  • Instructor: Onboarding with (instructor-) coordinator and previous instructor of lesson; update of lesson materials (urgent issues and personal touches)

  • +
  • Local organizer/Team lead: Group onboarding ~ week/or two before workshop

  • +
  • Learner: Gets installation instructions, invited to installation help session, workshop info from event page and summary via e-mail

  • +
  • Collaborative notes manager sets up the notes document

  • +
+
+

Note

+

Onboarding manuals

+
    +
  • Outline of what will happen during the workshop

  • +
  • Discussion of different strategies to handle the exercise sessions

  • +
  • Lowering the barrier to ask for support by meeting some organizers

  • +
  • Q&A

  • +
+
+
+

Note

+

Installation instructions

+
    +
  • Instructions for all operating systems

  • +
  • Goal: Learners leave the workshop and are ready to apply the learned tools and techniques to their own work

  • +
  • Support session for installation challenges

  • +
+
+
+
+

During the workshop

+
+../_images/BYOC.png +
+

Image showing the different ways learners can do the exercises. No matter which way they choose, they always watch the stream and interact with instructors and organizers via collaborative notes. Individual learners do the exercises alone, people in online or local classrooms in addition get to discuss with their peers.

+
+
+
    +
  • Everyone watches stream

  • +
  • Co-instructors +- Present content +- Answer questions in collaborative notes

  • +
  • Collaborative notes manager

    +
      +
    • Keeps the collaborative notes clean

    • +
    • Helps answering questions

    • +
    • Adds sections

    • +
    • Archives the document after each day

    • +
    +
  • +
  • Learners do exercises individually or in team

  • +
  • Local organizer / Team lead

    +
      +
    • Guides learners through exercises

    • +
    • Facilitates discussion

    • +
    +
  • +
  • (Registration-) coordinator sends out e-mails to participants after each day (summary + preparation)

  • +
  • Director/Broadcaster manages the streaming (see session 4)

  • +
+
+
+

After the workshop

+
    +
  • Coordinator collects lessons learned based on experience and feedback and turns them into issues

  • +
  • Coordinator organizes debriefing week after the workshop, where anyone can join to give feedback

  • +
  • “Someone” sends out post-workshop survey half a year after workshop

  • +
  • Coordinator organizes “Bring your own code” sessions

  • +
  • Broadcaster prepares and shares recording (see session 4)

  • +
+
+

Note

+

Bring your own code sessions

+

We want to support learners to apply what they have learned in the workshop to their own work by offering one/two sessions where they can drop in, and discuss challenges with CodeRefinery instructors and helpers.

+
+../_images/welcome.png +
+

Image showing a classroom learning about git leading to a discussion between student and teacher to start a welcoming environment for asking for help.

+
+
+
+
+
+
+

This sounds like a lot of people and time investment!

+
    +
  • Many roles can be combined or adjusted as needed

  • +
  • Some roles can be taken on by multiple people

  • +
+

So how many people are needed for this kind of workshop?

+
    +
  • Recommended minimum: 2-3 people

  • +
  • Optimum: ~ 4-5 people +The more people you involve, the more time goes into coordination work.

  • +
+
+
+

How did we get to this setup?

+
    +
  • Collaborative in-person workshops since 2016 around the Nordics

  • +
  • Moved online in 2020

  • +
  • Started with “traditional zoom” workshops, breakoutrooms, volunteer helpers

  • +
  • Thought about scaling and ease of joining -> current setup (More about this in session 4)

  • +
  • Continuous development

  • +
+

We also still do smaller scale local workshops, if instructors are available. +You can offer your own CodeRefinery workshop by inviting other CodeRefinery instructors. +You can also reuse single lessons and integrate them into your own teaching.

+
+
+

Workshop roles and their journeys

+
+

Individual learner journey

+
    +
  • Registration

  • +
  • Installation

  • +
  • (if appicable: Invited to local meetup)

  • +
  • Workshop

    +
      +
    • Watch stream

    • +
    • Q&A in notes

    • +
    • Exercises alone or in team

    • +
    • Daily feedback

    • +
    +
  • +
  • Debrief/ Feedback session

  • +
  • Post workshop survey

  • +
+
+
+

Instructor journey

+
    +
  • Indicate interest in CodeRefinery chat

  • +
  • Onboarding

  • +
  • Lesson material updates

  • +
  • Teaching

  • +
  • (if wished: supports answering questions in notes)

  • +
  • Debrief

  • +
+
+
+

Team lead / Local host journey

+
    +
  • Registration

  • +
  • (if applicable: run own registration)

  • +
  • Onboarding

  • +
  • Workshop

    +
      +
    • Watch stream

    • +
    • Facilitate exercises/discussions

    • +
    • Daily feedback

    • +
    +
  • +
  • Debrief / feedback / survey

  • +
+
+
+

Other roles

+

Director and broadcaster roles will be discussed in Session 4. +For more in-depth descriptions and other roles (host, instructor, registration coordinator, etc), see also our CodeRefinery manuals.

+
+
+
+

Different roles as stepping stones for community involvement

+
+../_images/steps.png +
+

Image showing a person jumping from step to step following learner, helper, expert helper, co-instructor, co-organizer.

+
+
+

There is no “one way” to get involved. Do what feels right. +Interested in teaching with us? Let us know and we can discuss what is a suitable path for you!

+
+

Keypoints

+
    +
  • CodeRefinery workshops are a collaborative effort with many different roles

  • +
  • Onboarding the different roles is one key aspect of our workshops

  • +
  • Everyone has their own path

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/screenshare/index.html b/screenshare/index.html new file mode 100644 index 0000000..a16afec --- /dev/null +++ b/screenshare/index.html @@ -0,0 +1,565 @@ + + + + + + + How to prepare a quality screen-share — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

How to prepare a quality screen-share

+
+

Objectives

+
    +
  • Discuss the importance of a well planned screen-share.

  • +
  • Learn how to prepare and how to test your screen-share setup.

  • +
  • Know about typical pitfalls and habits to avoid.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 15 min

  • +
  • Exercises: 15 min

  • +
+
+
+

Share portrait layout instead of sharing entire screen when teaching online

+
    +
  • Many learners will have a smaller screen than you.

  • +
  • You should plan for learners with only one small screen.

  • +
  • A learner will need to focus on both your screen share and their +work.

  • +
  • Share a portrait/vertical half of your screen (840 × 1080 is our standard and your +maximum).

  • +
  • Zoom provides a “Share a part of screen” that is good for this.

    +
      +
    • Our latest streaming setup (day 4) can take the portrait part for +you so you can share landscape.

    • +
    • Zoom + Linux + Wayland display manager doesn’t have “Share a +portion of the screen”

      +
        +
      • You can share a single window portrait.

      • +
      • Or you can start your desktop session in “X11” or “Xorg” legacy +mode.

      • +
      • Or possibly other workarounds (does anyone know other solutions?)

      • +
      +
    • +
    +
  • +
+
+../_images/landscape.png +
+

A FullHD 1920x1080 screen shared. Learners have to make this really small if +they want to have something else open.

+
+
+
+../_images/portrait.png +
+

Portrait layout. Allows learners to have something else open in the other half.

+
+
+

Motivation for portrait layout:

+
    +
  • This makes it easier for you to look at some other notes or to coordinate +with other instructors at the same time +without distracting with too much information.

  • +
  • This makes it possible for participants to have something else open in the +other screen half: terminal or browser or notebook.

  • +
+
+

Instructor perspective

+
+../_images/instructor.png +
+

I1: +This is how it can look for the instructor. Zoom is sharing a portion of the left +side, the right side is free for following notes, chat, etc.

+
+
+
+
+

Learner perspective

+

Here are three examples of how it can look for the learner.

+
+../_images/learner-large.png +
+

L1: +Learner with a large screen, Zoom in dual-monitor mode so that the instructor +pictures are not shown. Screen-share is on the left side, collaborative notes +at bottom left, terminal and web browser on the right.

+
+
+
+../_images/learner-normal.png +
+

L2: +A learner with a single large screen (Zoom in “single monitor mode”). +Instructor screen share at right, learner stuff at left.

+
+
+
+../_images/learner-small.png +
+

L3: +A learner with a particularly small screen. Instructor screen-share at left, +your windows at right.

+
+
+
+
+
+

Share the history of your commands

+

Even if you type slowly it is almost impossible to follow every command. We +all get distracted or want to read up on something or while following a command +fails on the learner laptop while instructor gets no error.

+

Add pauses and share the commands that you have typed so that one can catch up.

+

Below are some examples (some more successful than others) of sharing history +of commands.

+
+../_images/history-portrait.png +
+

H1: +A vertical screen layout shared. Note the extra shell history at the top. The +web browser is at the bottom, because the Zoom toolbar can cover the bottom +bit.

+
+
+
+../_images/history-rsh.png +
+

H2: +This isn’t a screen-share from CodeRefinery, but may be instructive. Note the +horizontal layout and shell history at the bottom right.

+
+
+
+../_images/history-landscape-dark.png +
+

H3: +Similar to above, but dark. Includes contents on the right.

+
+
+
+../_images/history-portrait-light.png +
+

H4: +Jupyter + terminal, including the fish shell and the terminal history.

+
+
+
+../_images/history-portrait-dark.png +
+

H5: +Lesson + terminal, tmux plus terminal history and dark background.

+
+
+
+../_images/portrait.png +
+

H6: +HPC Kickstart course. Note the colors contrast of the windows and colors of +the prompt and text. The history is smaller and doesn’t take up primary +working space. The working directory is in the window title bar.

+
+
+
+https://raw.githubusercontent.com/bast/history-window/main/demo.gif +
+

H7: +Show command history “picture-in-picture”, in the same terminal window.

+
+
+
+
+

How to configure history sharing

+

You need to find a way to show the recent commands you have entered, so that +learners can see the recent commands. Below are many solutions. Try them out +and see what works for you.

+
    +
  • prompt-log: +It adds a interesting idea that the command you enter is in color and also +provides terminal history before the command returns.

  • +
  • Simple: The simple way is PROMPT_COMMAND="history -a" and then +tail -f -n0 ~/.bash_history, but this doesn’t capture ssh, +sub-shells, and only shows the command after it is completed.

  • +
  • Better yet still simple: Many Software Carpentry instructors use +this script, +which sets the prompt, splits the terminal window using tmux and displays command history +in the upper panel. Requirement: tmux

  • +
  • Better (bash): This prints the output before the command is run, +instead of after. Tail with tail -f ~/demos.out.

    +
    BASH_LOG=~/demos.out
    +bash_log_commands () {
    +    # https://superuser.com/questions/175799
    +    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    +    [[ "$PROMPT_COMMAND" =~ "$BASH_COMMAND" ]] && return # don't cause a preexec for $PROMPT_COMMAND
    +    local this_command=`HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"`;
    +    echo "$this_command" >> "$BASH_LOG"
    +}
    +trap 'bash_log_commands' DEBUG
    +
    +
    +
  • +
  • Better (zsh): This works like above, with zsh. Tail with tail -f ~/demos.out.

    +
    preexec() { echo $1 >> ~/demos.out }
    +
    +
    +
  • +
  • Better (fish): This works like above, but for fish. Tail with +tail -f ~/demos.out.

    +
    function cmd_log --on-event fish_preexec ; echo "$argv" >> ~/demos.out  ; end
    +
    +
    +
  • +
  • Better (tmuxp): This will save some typing. +TmuxP is a Python program (pip install tmuxp) that gives you programmable tmux sessions. One configuration that +works (in this case for fish shell):

    +
    session_name: demo
    +windows:
    +  - window_name: demo
    +    layout: main-horizontal
    +    options:
    +      main-pane-height: 7
    +    panes:
    +      - shell_command:
    +          - touch /tmp/demo.history
    +          - tail -f /tmp/demo.history
    +      - shell_command:
    +          - function cmd_log --on-event fish_preexec ; echo "$argv" >> /tmp/demo.history  ; end
    +
    +
    +
  • +
  • Windows PowerShell: In Windows Terminal, +a split can be made by pressing CTRL+SHIFT+=. Then, in one of the splits, the following +PowerShell command will start tracking the shell history:

    +
    Get-Content (Get-PSReadlineOption).HistorySavePath -Wait
    +
    +
    +

    Unfortunately, this only shows commands after they have been executed.

    +
  • +
  • Tavatar: shell history mirroring teaching tool can copy recent history to a remote server.

  • +
  • history-window: Show command +history “picture-in-picture” when teaching command line. Requires Bash.

  • +
+
+
+

Font, colors, and prompt

+
+

Terminal color schemes

+
    +
  • Dark text on light background, not dark theme. Research and our +experience says that dark-text-on-light is better in some cases and +similar in others.

  • +
  • You might want to make the background light grey, to avoid +over-saturating people’s eyes and provide some contrast to the pure +white web browser. (this was an accessibility recommendation when +looking for ideal color schemes)

  • +
  • Do you have any yellows or reds in your prompt or program outputs? +Adjust colors if possible.

  • +
+
+
+

Font size

+
    +
  • Font should be large (a separate history terminal can have a smaller +font).

  • +
  • Be prepared to resize the terminal and font as needed. Find out +the keyboard shortcuts to do this since you will need it.

  • +
+
+
+

Prompt

+

At the beginning of the workshop your goal is to have a shell +as easy to follow as possible and as close to what learners will +see on their screens:

+
    +
  • Your prompt should be minimal: few distractions, and not take up many +columns of text.

  • +
  • prompt-log does +this for you.

  • +
  • The minimum to do is is export PS1='\$ '.

  • +
  • Blank line between entries: export PS1='\n\$ '.

  • +
  • Have a space after the $ or % or whatever prompt character you +use.

  • +
  • Strongly consider the Bash shell. This is what most new people will +use, and Bash will be less confusing to them.

  • +
  • Eliminate menu bars and any other decoration that uses valuable +screen space.

  • +
  • Add colors only if it simplifies the reading of the prompt.

  • +
+

Later in the workshop or in more advanced lessons:

+
    +
  • Using other shells and being more adventurous is OK - learners will +know what is essential to the terminal and what is extra for your +environment.

  • +
+

Try to find a good balance between:

+
    +
  • Showing a simple setup and showing a more realistic setup.

  • +
  • Showing a consistent setup among all instructors and showing a +variety of setups.

  • +
+
+
+
+

Habits we need to un-learn

+
    +
  • Do not clear the terminal. Un-learn CTRL-L or clear if possible. +More people will wonder what +just got lost than are helped by seeing a blank screen. Push +ENTER a few times instead to add some white space.

  • +
  • Do not rapidly switch between windows or navigate quickly between multiple +terminals, browser tabs, etc. This is useful during your own work when nobody +is watching, but it is very hard to follow for learners.

  • +
  • Avoid using aliases or shortcuts that are not part of the +standard setup. Learners probably don’t have them, and they will fail +if they try to follow your typing. Consider even to rename corresponding +files (.bashrc, .gitconfig, .ssh/config, .ssh/authorized_keys, .conda/*).

  • +
  • Be careful about using tab completion or reverse history search if these +haven’t been introduced yet.

  • +
+
+
+

Desktop environment and browser

+
    +
  • Try to remove window title bars if they take up lots of space +without adding value to the learner.

  • +
  • Can you easily resize your windows for adjusting during teaching?

  • +
  • Does your web browser have a way to reduce its menu bars and other +decoration size?

    +
      +
    • Firefox-based browsers: go to about:config and set +layout.css.devPixelsPerPx to a value slightly smaller than one, +like 0.75. Be careful you don’t set it too small or large since +it might be hard to recover! When you set it to something smaller +than 1, all window decorations become smaller, and you compensate +by zooming in on the website more (you can set the default zoom to +be greater than 100% to compensate). Overall, you get more +information and less distraction.

    • +
    +
  • +
+
+
+

How to switch between teaching setup and work setup?

+
    +
  • Make a dedicated “demos” profile in your terminal emulator, if +relevant. Or use a different terminal emulator just for demos.

  • +
  • Same idea for the browser: Consider using a different browser profile for +teaching/demos.

  • +
  • Another idea is to containerize the setup for teaching. +We might demonstrate this during the Sharing teaching gems session later.

  • +
+
+
+

Keypoints

+
    +
  • Share portrait layout instead of sharing entire screen

  • +
  • Adjust your prompt to make commands easy to read

  • +
  • Readability and beauty is important: adjust your setup for your audience

  • +
  • Share the history of your commands

  • +
  • Get set up a few days in advance and get feedback from someone else. +Feedback and time to improve is very important to make things clear and accessible. +10 minutes before the session starts is typically too late.

  • +
+
+
+
+

Exercises

+
+

Evaluate screen captures (20 min)

+

Evaluate screenshots on this page. Discuss the trade-offs of each one. Which +one do you prefer? Which are useful in each situation?

+

Please take notes in the collaborative document.

+
+
+

Set up your own environment (20 min)

+

Set up your screen to teach something. Get some feedback from another learner +or your exercise group.

+
+
+
+

Other resources

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/search/index.html b/search/index.html new file mode 100644 index 0000000..a394590 --- /dev/null +++ b/search/index.html @@ -0,0 +1,184 @@ + + + + + + Search — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/searchindex.js b/searchindex.js new file mode 100644 index 0000000..2d07286 --- /dev/null +++ b/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {":calendar: Schedule": [[10, "calendar-schedule"], [10, "id1"], [10, "id9"], [10, "id17"]], ":icecream: Icebreaker": [[10, "icecream-icebreaker"], [10, "id2"], [10, "id10"], [10, "id18"]], ":question: Questions": [[10, "question-questions"], [10, "id5"], [10, "id13"], [10, "id21"]], "A workshop seen from different perspectives": [[13, null]], "About teaching": [[10, "about-teaching"]], "About the CodeRefinery project and CodeRefinery workshops in general": [[1, null]], "Accepting the smallest contribution": [[9, "discussion-0"]], "After the workshop": [[13, "after-the-workshop"]], "All CodeRefinery lessons are on GitHub": [[8, "discussion-0"]], "Alternatives": [[17, "alternatives"]], "Are there any downsides?": [[0, "are-there-any-downsides"]], "Asking questions": [[2, "asking-questions"]], "Asking questions before the workshop": [[5, "asking-questions-before-the-workshop"]], "August/September 2024": [[10, "august-september-2024"]], "August/September 2024 CodeRefinery train the trainer workshop": [[7, null]], "Balancing and dynamic adjustment": [[16, "balancing-and-dynamic-adjustment"]], "Basic controls": [[2, "basic-controls"]], "Before the workshop": [[2, "before-the-workshop"], [13, "before-the-workshop"]], "Behind the stream": [[10, "behind-the-stream"], [17, null]], "Benefits and disadvantages": [[21, "benefits-and-disadvantages"]], "Best classroom experiences": [[10, "best-classroom-experiences"]], "Better approach": [[8, "better-approach"]], "Bj\u00f8rn Lindi": [[19, "exercise-1"]], "Breakout Room exercise": [[10, "breakout-room-exercise"]], "Carpentries audience": [[1, "carpentries-audience"]], "Challenges related to defining our target audience": [[1, "discussion-1"]], "Check-in": [[10, "check-in"], [10, "id3"], [10, "id11"], [10, "id19"]], "Co-teaching": [[0, null], [0, null]], "Co-teaching and team teaching benefits": [[0, "co-teaching-and-team-teaching-benefits"]], "CodeRefinery OBS configs": [[12, "coderefinery-obs-configs"]], "CodeRefinery audience": [[1, "coderefinery-audience"]], "CodeRefinery control panel": [[17, "coderefinery-control-panel"]], "CodeRefinery lesson template": [[9, "coderefinery-lesson-template"]], "CodeRefinery teaching philosophies": [[19, null]], "Collaborative Document Manager": [[2, "collaborative-document-manager"]], "Collaborative document format example": [[2, "collaborative-document-format-example"]], "Collaborative document mechanics and controls": [[2, "collaborative-document-mechanics-and-controls"]], "Collaborative notes": [[2, null]], "Collaborative notes archives from workshops": [[10, null]], "Collecting feedback as we teach": [[5, "collecting-feedback-as-we-teach"]], "Community": [[1, "community"]], "Competent practitioners": [[1, null]], "Computational thinking": [[3, null]], "Creating new teaching material": [[8, "creating-new-teaching-material"]], "Day 2 : Session 2 (20.08.24)- Tools and techniques adopted in CodeRefinery workshops": [[10, "day-2-session-2-20-08-24-tools-and-techniques-adopted-in-coderefinery-workshops"]], "Day 3 : sessiion 3 (27.08.24) - \u201cAbout teaching and cool things we all would like to share\u201d": [[10, "day-3-sessiion-3-27-08-24-about-teaching-and-cool-things-we-all-would-like-to-share"]], "Day1: Session 1 (13.08.24) - About lesson design, deployment and iterative improvement": [[10, "day1-session-1-13-08-24-about-lesson-design-deployment-and-iterative-improvement"]], "Day4: Session 4 (3.09.24) - Streaming and video editing": [[10, "day4-session-4-3-09-24-streaming-and-video-editing"]], "Desktop environment and browser": [[14, "desktop-environment-and-browser"]], "Different roles as stepping stones for community involvement": [[13, "different-roles-as-stepping-stones-for-community-involvement"]], "Discuss how to collaborate and handle questions (15 min)": [[2, "exercise-0"]], "Discuss the models of team teaching (10 min)": [[0, "exercise-0"]], "Discussion": [[13, "discussion"], [13, "discussion-0"]], "Discussion: how to distribute this?": [[20, null]], "Discussion: what makes a video easy to edit?": [[20, null]], "Don\u2019t get overwhelmed": [[2, "don-t-get-overwhelmed"]], "During the workshop": [[13, "during-the-workshop"]], "Editing-1: Get your sample video": [[20, "exercise-1"]], "Editing-2: Run Whisper to generate raw subtitles and test video.": [[20, "exercise-0"]], "Editing-3: Create the basic editlist.yaml file": [[20, "exercise-2"]], "Editing-4: Run ffmpeg-editlist": [[20, "exercise-3"]], "Editing-5: Add more features": [[20, "exercise-4"]], "Editing-6: Subtitles": [[20, "exercise-5"], [20, "exercise-6"]], "Editing-7: Generate the final output file.": [[20, "exercise-7"]], "Episode 1 : Computational thinking": [[10, "episode-1-computational-thinking"]], "Episode 1: CodeRefinery": [[10, "episode-1-coderefinery"]], "Episode 1: Lesson design and development": [[10, "episode-1-lesson-design-and-development"]], "Episode 2 : Teaching philosophies": [[10, "episode-2-teaching-philosophies"]], "Episode 2: Collaborative Notes": [[10, "episode-2-collaborative-notes"]], "Episode 2: Lessons with version control": [[10, "episode-2-lessons-with-version-control"]], "Episode 3: Co-teaching": [[10, "episode-3-co-teaching"]], "Episode 3: How we collect feedback and measure impact": [[10, "episode-3-how-we-collect-feedback-and-measure-impact"]], "Episode 3: One workshop, many perspectives": [[10, "episode-3-one-workshop-many-perspectives"]], "Episode 4: Sound": [[10, "episode-4-sound"]], "Episode 5: How to prepare a quality screen-share": [[10, "episode-5-how-to-prepare-a-quality-screen-share"]], "Evaluate screen captures (20 min)": [[14, "exercise-0"]], "Example 1": [[5, "example-1"]], "Example 2": [[5, "example-2"]], "Example 3": [[5, "example-3"]], "Example 4": [[5, "example-4"]], "Exercise": [[0, "exercise"], [2, "exercise"]], "Exercise A": [[20, "exercise-a"]], "Exercise B": [[20, "exercise-b"]], "Exercise questions to discuss": [[10, "exercise-questions-to-discuss"]], "Exercise: Discussion about learning objectives and exercise design": [[8, "exercise-discussion-about-learning-objectives-and-exercise-design"]], "Exercise: Group discussion (10 min)": [[5, "exercise-group-discussion-10-min"]], "Exercise: How do you design your teaching material?": [[8, "exercise-how-do-you-design-your-teaching-material"]], "Exercises": [[9, "exercises"], [14, "exercises"], [16, "exercises"], [20, "exercises"]], "Feedback about todays session": [[10, "feedback-about-todays-session"], [10, "id8"], [10, "id16"], [10, "id23"]], "Feedback template": [[2, "feedback-template"]], "Font size": [[14, "font-size"]], "Font, colors, and prompt": [[14, "font-colors-and-prompt"]], "Future prospects (briefly)": [[21, "future-prospects-briefly"]], "General / Practicalities": [[10, "general-practicalities"], [10, "id6"], [10, "id14"]], "General Collaborative Document practices": [[2, "general-collaborative-document-practices"]], "Getting it set up": [[17, "getting-it-set-up"]], "Goals": [[1, "goals"]], "Great resources": [[8, "great-resources"]], "Group discussion using the collaborative notes": [[5, "exercise-0"]], "Guide and demo-giver": [[0, "guide-and-demo-giver"]], "Habits we need to un-learn": [[14, "habits-we-need-to-un-learn"]], "Hardware requirements": [[11, "hardware-requirements"]], "History": [[1, "discussion-0"], [21, "history"]], "How did we get to this setup?": [[13, "how-did-we-get-to-this-setup"]], "How scenes are controlled": [[17, "how-scenes-are-controlled"]], "How this relates to streaming": [[20, "how-this-relates-to-streaming"]], "How to configure history sharing": [[14, "how-to-configure-history-sharing"]], "How to prepare a quality screen-share": [[14, null]], "How to switch between teaching setup and work setup?": [[14, "how-to-switch-between-teaching-setup-and-work-setup"]], "How we collect feedback and measure impact": [[5, null]], "How we do it": [[20, "how-we-do-it"]], "Ice-breaker in groups (20 minutes)": [[19, "exercise-0"]], "Icebreaker questions": [[21, "icebreaker-questions"]], "Improving existing lessons": [[8, "improving-existing-lessons"]], "Individual learner journey": [[13, "individual-learner-journey"]], "Initial setup": [[12, "initial-setup"]], "Installing the OBS config": [[12, "installing-the-obs-config"]], "Instructor guide": [[6, null]], "Instructor journey": [[13, "instructor-journey"]], "Instructor note": [[0, "instructor-note-0"], [2, "instructor-note-0"], [3, "instructor-note-0"], [4, "instructor-note-0"], [5, "instructor-note-0"], [8, "instructor-note-0"], [9, "instructor-note-0"], [11, "instructor-note-0"], [12, "instructor-note-0"], [13, "instructor-note-0"], [14, "instructor-note-0"], [16, "instructor-note-0"], [17, "instructor-note-0"], [18, "instructor-note-0"], [19, "instructor-note-0"], [20, "instructor-note-0"], [21, "instructor-note-0"]], "Instructor perspective": [[14, "instructor-perspective"]], "Instructor views": [[19, "instructor-views"]], "Instructors go through the building and contributing process": [[9, "demo-0"]], "Introduction": [[2, "introduction"], [19, "introduction"]], "Introduction in breakoutrooms": [[10, "id4"], [10, "id12"], [10, "id20"]], "Introduction in breakoutrooms.": [[10, "introduction-in-breakoutrooms"]], "Keypoints": [[0, "keypoints-0"], [2, "keypoints-0"], [3, "keypoints-0"], [9, "keypoints-0"], [11, "keypoints-0"], [12, "keypoints-0"], [13, "keypoints-0"], [14, "keypoints-0"], [16, "keypoints-0"], [17, "keypoints-0"], [18, "keypoints-0"], [19, "keypoints-0"], [20, "keypoints-0"], [21, "keypoints-0"]], "Keypoints: CodeRefinery": [[1, "keypoints-0"]], "Learner perspective": [[14, "learner-perspective"]], "Lesson design and development": [[8, null]], "Lesson-VCS-1: Present and discuss your own lesson formats": [[9, "exercise-0"]], "Lesson-VCS-2: Tour a CodeRefinery or Carpentries lesson on Github": [[9, "exercise-1"]], "Lesson-VCS-3: Modify a CodeRefinery example lesson on Github": [[9, "exercise-2"]], "Lesson-VCS-4: Clone and build a CodeRefinery lesson locally": [[9, "exercise-3"]], "Lesson-VCS-5: (advanced) Create your own lesson using the CodeRefinery format": [[9, "exercise-4"]], "Lessons learned": [[5, "lessons-learned"]], "Lessons with version control": [[9, null]], "Most things to edit (everyone)": [[2, "most-things-to-edit-everyone"]], "Novices": [[1, null]], "OBS during a course": [[11, "obs-during-a-course"]], "OBS user interface": [[11, "obs-user-interface"]], "Objectives": [[0, "objectives-0"], [1, "objectives-0"], [2, "objectives-0"], [3, "objectives-0"], [4, "objectives-0"], [5, "objectives-0"], [8, "objectives-0"], [9, "objectives-0"], [11, "objectives-0"], [12, "objectives-0"], [13, "objectives-0"], [14, "objectives-0"], [16, "objectives-0"], [17, "objectives-0"], [18, "objectives-0"], [19, "objectives-0"], [20, "objectives-0"], [21, "objectives-0"]], "One workshop - many parts": [[13, "one-workshop-many-parts"]], "Open Broadcaster Software (OBS) introduction": [[11, null]], "Open Broadcaster Software (OBS) introduction & setup": [[10, "open-broadcaster-software-obs-introduction-setup"]], "Open Broadcaster Software (OBS) setup": [[12, null]], "Other resources": [[14, "other-resources"]], "Other roles": [[13, "other-roles"]], "Overview": [[0, "overview"]], "Participant preparations for each session": [[6, "participant-preparations-for-each-session"]], "Poll": [[10, "poll"]], "Posting the collaborative document to the website": [[2, "posting-the-collaborative-document-to-the-website"]], "Presenter and interviewer": [[0, "presenter-and-interviewer"]], "Primary articles": [[20, "primary-articles"]], "Privacy": [[2, "privacy"]], "Prompt": [[14, "prompt"]], "Q&A": [[11, "q-a"], [12, "q-a"], [17, "q-a"], [21, "q-a"]], "Questions": [[10, "questions"]], "Questions from the audience": [[10, "questions-from-the-audience"]], "Questions to audience": [[10, "questions-to-audience"]], "Radovan Bast": [[19, "exercise-2"]], "Recommendations": [[16, "recommendations"]], "Resources": [[7, null]], "Richard Darst": [[19, "exercise-4"]], "Sabry Razick": [[19, "exercise-3"]], "See also": [[11, "see-also"], [18, "see-also"], [20, "see-also"]], "Session 1": [[7, null]], "Session 2": [[7, null]], "Session 3": [[7, null]], "Session 4": [[7, null]], "Session 4 intro": [[15, null]], "Set up the remote control": [[12, "set-up-the-remote-control"]], "Set up your own environment (20 min)": [[14, "exercise-1"]], "Setup before each course": [[12, "setup-before-each-course"]], "Share portrait layout instead of sharing entire screen when teaching online": [[14, "share-portrait-layout-instead-of-sharing-entire-screen-when-teaching-online"]], "Share the history of your commands": [[14, "share-the-history-of-your-commands"]], "Sharing teaching gems": [[4, null]], "Solution": [[20, "solution-0"], [20, "solution-1"], [20, "solution-2"], [20, "solution-3"], [20, "solution-4"], [20, "solution-5"]], "Sound": [[16, null]], "Sound-1: Evaluate sound quality": [[16, "exercise-0"]], "Sound-2: Adjust volume up and down": [[16, "exercise-1"]], "Sound-3: Do a balance check": [[16, "exercise-2"]], "Speak up when there are problems": [[16, "speak-up-when-there-are-problems"]], "Sphinx": [[9, "sphinx"]], "Stepas Toliautas": [[19, "exercise-5"]], "Summary": [[0, "summary"], [9, "summary"], [16, "summary"], [19, "summary"], [20, "summary"]], "Take time designing your survey": [[5, "take-time-designing-your-survey"]], "Talking points for each sessions intro": [[6, "talking-points-for-each-sessions-intro"]], "Target audience": [[1, "target-audience"], [6, "target-audience"]], "Teaching": [[10, "teaching"]], "Teaching gems": [[10, "teaching-gems"]], "Team lead / Local host journey": [[13, "team-lead-local-host-journey"]], "Team teaching models": [[0, "team-teaching-models"]], "Team teaching specifics": [[0, "team-teaching-specifics"]], "Terminal color schemes": [[14, "terminal-color-schemes"]], "The importance of audio": [[16, "the-importance-of-audio"]], "The instructor will go through the setup.": [[12, "demo-0"]], "The process of designing a lesson \u201cbackwards\u201d": [[8, "the-process-of-designing-a-lesson-backwards"]], "This sounds like a lot of people and time investment!": [[13, "this-sounds-like-a-lot-of-people-and-time-investment"]], "Timing": [[6, "timing"]], "Tips for good sound quality": [[16, "tips-for-good-sound-quality"]], "Tour of lesson templates options": [[9, "tour-of-lesson-templates-options"]], "Train the trainer workshop": [[7, null]], "Trying to measure impact with longer-term surveys": [[5, "trying-to-measure-impact-with-longer-term-surveys"]], "Typical problems": [[8, "typical-problems"]], "Use case: our lessons": [[8, "use-case-our-lessons"]], "Use ffmpeg-editlist to edit this sample video": [[20, "exercise-8"]], "Video editing": [[10, "video-editing"], [20, null]], "Video recordings": [[19, "prerequisites-0"]], "We collect notes using a shared document (5 min)": [[8, "exercise-0"]], "We work in groups but use the shared document as result (20 min)": [[8, "exercise-1"]], "What can go wrong": [[17, "what-can-go-wrong"]], "What is OBS?": [[11, "what-is-obs"]], "What is streaming and recording?": [[21, "what-is-streaming-and-recording"]], "What\u2019s next?": [[18, null]], "Who does what": [[17, "who-does-what"]], "Why version control?": [[9, "why-version-control"]], "Why we stream": [[10, "why-we-stream"], [21, null]], "Window layouts": [[17, "window-layouts"]], "Workshop roles and their journeys": [[13, "workshop-roles-and-their-journeys"]], "Wrapup": [[10, "wrapup"], [10, "id7"], [10, "id15"], [10, "id22"]]}, "docnames": ["co-teaching", "coderefinery-intro", "collaborative-notes", "computational-thinking", "cool-gems", "feedback-and-impact", "guide", "index", "lesson-development", "lessons-with-git", "notes-archive", "obs", "obs-config", "overview", "screenshare", "session-4-intro", "sound", "streaming", "streaming-whats-next", "teaching-philosophies", "video-editing", "why-we-stream"], "envversion": {"sphinx": 62, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["co-teaching.md", "coderefinery-intro.md", "collaborative-notes.md", "computational-thinking.md", "cool-gems.md", "feedback-and-impact.md", "guide.md", "index.md", "lesson-development.md", "lessons-with-git.md", "notes-archive.md", "obs.md", "obs-config.md", "overview.md", "screenshare.md", "session-4-intro.md", "sound.md", "streaming.md", "streaming-whats-next.md", "teaching-philosophies.md", "video-editing.md", "why-we-stream.md"], "indexentries": {}, "objects": {}, "objnames": {}, "objtypes": {}, "terms": {"": [0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 19, 20], "0": [10, 14, 21], "00": [10, 20], "01": 2, "02": 10, "02_at_09": 10, "03": [5, 20], "03308595436e636b3bb37ed9d1f0dee39eeccd0f": 10, "04": 20, "05": [10, 20], "07": 20, "08": 5, "1": [2, 6, 14, 21], "10": [2, 3, 6, 10, 14, 16, 17, 19, 20, 21], "100": [10, 11, 14, 16, 21], "1080": 14, "11": [10, 20], "12": [5, 10, 20], "128": 10, "13": 7, "13292363": 5, "13th": 7, "14": 10, "148421550": 10, "15": [0, 6, 10, 11, 13, 14, 20], "16": 20, "17": 10, "175799": 14, "180": 19, "18640868": 10, "19": 10, "1920x1080": 14, "1d": 10, "2": [2, 6, 8, 13], "20": [2, 3, 5, 6, 7, 9, 13, 17, 20], "200": 10, "2014": [1, 8], "2015": [1, 8], "2016": [1, 8, 13], "2017": 8, "2019": 8, "2020": 13, "202024": 10, "2021": 5, "2022": [1, 8], "2023": 20, "2024": [5, 8, 15], "2025": 1, "20coderefineri": 10, "20workshop": 10, "21": 10, "23": 10, "24": 20, "25": [6, 9, 10, 20], "25mbit": 11, "26": 10, "2671576": 5, "2671578": 5, "27": 7, "2k45bftw4sbmlbfjr1oz90": 10, "3": [1, 2, 4, 6, 8, 13, 21], "30": [6, 10], "300": [10, 16], "31": 20, "316508": 10, "35": [4, 6, 8, 10, 20], "37": 20, "39": 10, "3rd": [7, 10], "4": [2, 3, 6, 13, 14], "40": 10, "404": 10, "43": 20, "4445": 12, "45": [2, 6, 10, 19, 20], "5": [0, 2, 5, 6, 11, 13, 16, 18, 21], "50": [10, 20], "500m": 16, "5281": 5, "55": 10, "5c6ecd3628a43b0cdc79815f665e224a": 10, "6": 10, "612x612": 10, "64gb": 11, "7": [10, 14], "75": 14, "7b": 10, "7b7ec4b91d2cf9d8e1b064678d205467": 10, "7e": 10, "7nhx": 19, "8": [10, 11], "80": 10, "840": 14, "9": [10, 14], "90": [6, 8], "9781119861690": 10, "A": [1, 2, 7, 8, 10, 14, 18, 19], "And": [2, 10, 16, 19, 20], "As": [2, 8, 10, 15, 16, 20], "At": [2, 14], "BY": 8, "Be": [2, 10, 14, 16, 20], "Being": 10, "But": [2, 6, 8, 10, 16, 19], "By": [1, 10, 20], "For": [0, 1, 2, 6, 8, 9, 10, 13, 19, 20, 21], "If": [2, 6, 7, 8, 9, 10, 13, 15, 16, 19, 20], "In": [0, 1, 6, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21], "It": [0, 1, 2, 6, 8, 9, 10, 14, 15, 16, 17, 19, 20], "NO": 10, "NOT": 10, "No": [5, 10, 13, 20, 21], "Not": [0, 5, 8, 10, 17], "One": [0, 1, 2, 5, 14, 16, 17], "Or": [2, 9, 10, 14], "That": [10, 11, 19], "The": [0, 1, 2, 5, 7, 9, 10, 11, 13, 14, 15, 17, 19, 20, 21], "Then": [6, 10, 14], "There": [1, 2, 6, 9, 10, 12, 13, 15, 17, 20, 21], "These": [6, 10, 12, 15, 16, 18, 20, 21], "To": [6, 10, 20], "Will": 10, "With": [10, 16, 19], "_build": 9, "_cobn": 20, "aaa": 16, "aalto": [10, 20], "aaltoscicomp": 20, "aau": 10, "abl": [2, 6, 8, 10, 16, 19, 20], "about": [0, 2, 5, 6, 7, 9, 11, 13, 14, 15, 17, 18, 19, 20, 21], "abov": [2, 5, 10, 14, 20], "abraham": 10, "absenc": 10, "absolut": 10, "abstract": [3, 10], "academ": [1, 10, 19], "academi": 10, "accept": [1, 10], "access": [8, 10, 14, 20], "accid": 20, "accident": 0, "accomd": 10, "accompani": 8, "accomplish": [2, 10], "account": [2, 6, 9, 10], "accur": 20, "achiev": [5, 10, 16, 19], "achiv": 10, "acoust": [10, 16], "acquiesc": [5, 10], "across": 10, "act": 10, "action": [5, 10], "activ": [0, 1, 8, 10, 15], "actual": [0, 1, 5, 8, 10, 19, 20, 21], "ad": [2, 10, 14], "adapt": [0, 10], "add": [0, 2, 5, 6, 9, 10, 13, 14], "addit": [0, 10, 13, 16, 19], "address": [1, 10], "adjust": [0, 2, 6, 10, 11, 13, 14, 17, 20], "adopt": 7, "advanc": [0, 2, 6, 10, 14], "advantag": [6, 8, 10], "advent": 10, "adventur": 14, "advertis": 13, "advertiz": 13, "advic": 10, "advoc": [8, 10, 20], "affili": 10, "africa": 10, "after": [2, 5, 6, 9, 10, 14, 16, 19, 20], "afternoon": 8, "afterward": [2, 10, 19], "aftwerward": 10, "against": 10, "agil": [10, 19], "ago": [10, 19], "agre": [0, 2, 10], "ah": 10, "aha": 19, "ahead": 10, "ai": 10, "aim": [1, 7, 10, 19], "airwav": 10, "al": 10, "albert": 10, "algorithm": [3, 10], "alias": 14, "align": 20, "all": [0, 1, 2, 5, 6, 7, 9, 13, 14, 16, 17, 19, 20, 21], "alloc": 10, "allow": [0, 2, 8, 9, 10, 14, 19, 20, 21], "almost": [10, 14, 19], "alon": [2, 10, 13], "along": [2, 10, 19, 20], "alreadi": [0, 1, 5, 8, 10, 19], "alredi": 10, "also": [0, 1, 2, 6, 7, 8, 9, 10, 13, 14, 15, 16, 17, 19], "altern": [0, 2, 9, 10], "alternativeto": 10, "although": 10, "alwai": [1, 2, 8, 10, 13, 19], "am": [8, 10, 16, 19], "amazingli": 8, "ambassador": 1, "ambros": 10, "amd": [10, 11], "among": [10, 14, 16], "amount": [2, 10], "amus": 10, "an": [0, 1, 2, 5, 6, 7, 8, 10, 14, 15, 16, 17, 19, 20], "analogi": 10, "analysi": 10, "analyz": 8, "ani": [1, 2, 5, 7, 10, 14, 16, 19, 20], "annoi": 10, "annot": 10, "anomali": 15, "anonym": [5, 10], "anonymis": 10, "anoth": [0, 8, 10, 14], "answer": [2, 5, 8, 10, 11, 12, 13, 19], "anticip": [0, 10], "anwser": 2, "anxieti": 10, "anybodi": [5, 10], "anymor": 19, "anyon": [2, 10, 13, 14, 20], "anyth": [2, 5, 9, 10, 12, 17, 20, 21], "anywai": 10, "anywher": 9, "apart": 10, "apetit": 10, "api": 9, "aposteriori": 10, "app": 10, "appear": [10, 19, 20], "apper": 10, "appic": 13, "appli": [0, 1, 8, 10, 13, 20], "applic": [0, 10, 11, 12, 13, 17, 19], "apprecentiship": 10, "appreci": [10, 19], "apprici": 10, "approach": [0, 1, 10, 19], "appropri": 10, "approxim": 10, "apriori": 10, "ar": [1, 2, 5, 6, 7, 9, 10, 12, 13, 14, 15, 19, 20, 21], "archiv": [2, 7, 12, 13], "area": [0, 1, 10, 20], "aren": [2, 10, 16, 20], "argument": 10, "argv": 14, "aronud": 10, "around": [10, 13], "arrang": 2, "art": 10, "arthur": 10, "articl": 10, "artifact": 16, "asc": 20, "asid": 10, "ask": [0, 8, 9, 10, 13, 15, 16, 19], "asleep": 10, "aspect": [6, 10, 13], "assess": [0, 8], "assign": [6, 10], "assist": 10, "assum": [1, 2, 5, 9, 10], "assur": 10, "asymptot": 10, "async": 21, "attempt": 9, "attend": [5, 8, 10, 20], "attent": [0, 10], "audibl": 10, "audienc": [0, 5, 7, 8, 11, 12, 14, 16, 17, 19, 20, 21], "audio": [6, 7, 10, 11, 12, 15, 20], "aug": 7, "authorized_kei": 14, "auto": 10, "autom": 8, "automat": [2, 10], "av": 10, "avail": [0, 3, 5, 9, 10, 13, 16, 19, 20], "avm": 10, "avoid": [1, 2, 5, 10, 14, 19], "awai": [2, 10, 16, 17], "awar": [1, 10, 19], "awkward": 0, "b": 10, "bachelor": 10, "back": [2, 8, 10, 19, 20], "background": [8, 10, 14, 16, 19], "backup": [2, 18], "backward": 10, "bad": [10, 16], "bake": 10, "balanc": [2, 5, 14], "band": 10, "bandwidth": 16, "bar": [10, 14], "barrier": [6, 10, 13], "bascic": 10, "base": [1, 8, 9, 10, 13, 14, 17, 20], "baselin": 10, "bash": 14, "bash_command": 14, "bash_histori": 14, "bash_log": 14, "bash_log_command": 14, "bashrc": 14, "basic": [0, 6, 8, 9, 10, 11, 15, 16, 19], "basisc": 10, "bast": 7, "bbb": 16, "beamer": 10, "bear": 10, "beast": 10, "beat": 16, "beauti": 14, "becam": 10, "becaus": [1, 5, 10, 14, 16, 19, 20], "becom": [0, 5, 7, 8, 10, 14, 19, 20], "been": [5, 6, 8, 9, 10, 12, 13, 14, 16, 18, 19, 20], "befor": [1, 6, 8, 10, 14, 19, 20], "beforehand": 10, "beggin": 10, "begin": [5, 10, 14, 19, 20], "beginn": 7, "behind": [2, 5, 6, 7, 13], "being": [0, 10, 14, 19], "belief": 10, "believ": 10, "bell": 10, "below": [0, 2, 5, 7, 9, 10, 13, 14, 16, 19, 20], "benefici": [1, 10, 19], "benefit": [9, 10, 20], "benjamin": 10, "besid": 10, "best": [0, 1, 6, 13, 19], "better": [5, 10, 14, 19], "between": [0, 2, 6, 7, 9, 10, 13, 19], "beyond": [1, 2, 6, 16], "bia": [5, 10], "bias": 10, "biasi": 10, "big": [0, 8, 10, 21], "bigger": 5, "biggest": 10, "bill": 10, "bin": 10, "binari": 19, "binder": 10, "bioinformat": 10, "biolog": 10, "biologi": 10, "birdsey": 10, "bit": [10, 14, 16, 17, 19], "bj\u00f8rn": 7, "bl": 10, "black": [10, 20], "blackbox": 10, "blank": [2, 8, 14], "bleed": 10, "blob": [6, 10, 19], "bloc": 10, "block": [8, 10, 19], "blog": [5, 8, 10], "bloom": [8, 10], "blow": 10, "blue": 10, "bluetooth": [10, 16], "blurb": 10, "board": 10, "bob": 10, "bomb": 10, "bombard": 10, "book": [8, 9, 10], "bookshop": 10, "bore": [10, 15], "bot": 10, "both": [10, 14, 19], "bother": 10, "bottom": [2, 5, 10, 14], "bound": 10, "box": [9, 10], "br": 10, "brain": [6, 10], "brainstorm": [8, 10], "branch": [8, 10], "brand": 10, "bravo": 10, "bread": 10, "break": [2, 6, 10, 16, 17, 19, 20], "breaker": 10, "breakfast": 10, "breakout": [0, 2, 20], "breakoutroom": [6, 7, 13, 19], "breakthrough": 10, "breath": 10, "bridl": 10, "brief": 6, "bring": [2, 8, 10, 13, 16], "broad": [6, 10], "broadcast": [7, 13, 17], "broaden": 19, "broken": 10, "browser": [10, 19], "bst": 10, "budget": 20, "buffer": 10, "build": [1, 6, 10], "built": [9, 10], "bullet": [2, 10, 19], "busi": [10, 19], "button": [10, 11], "byoc": 13, "c": 10, "c4": 10, "cake": 10, "calcul": 10, "call": [10, 16, 17], "came": [10, 16], "camera": [7, 10, 19], "can": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 19, 20, 21], "cancel": [10, 16], "cannot": [6, 10], "canon": 10, "capac": 10, "capic": 10, "captur": [5, 10, 11, 15], "care": [1, 14], "carpentri": [8, 10, 14, 19], "cartooni": 10, "case": [0, 1, 2, 10, 14, 19], "cat": 10, "catch": [0, 10, 14, 20], "cater": 10, "caus": 14, "caveat": 10, "cc": 8, "cell": 10, "center": 10, "centric": 19, "certain": [10, 17, 19, 21], "certainti": 10, "certif": 10, "cest": 10, "challeng": [10, 13], "chanc": [7, 10], "chang": [0, 2, 5, 6, 8, 9, 10, 12, 17, 19], "channel": [1, 10], "chao": 0, "chaotic": [0, 10], "chapter": 20, "characht": 10, "charact": 14, "characterist": 10, "charg": 7, "charm": 10, "chat": [1, 2, 6, 10, 13, 14, 16], "chatgpt": 10, "cheat": 10, "check": [2, 5, 6, 19, 20], "checklist": [10, 12], "cheek": 10, "chemic": 10, "cherish": 10, "cherki": 10, "choic": [8, 10, 20], "choos": [8, 10, 13], "chose": 10, "chromium": 10, "chronolog": 10, "chubbi": 10, "chunk": 20, "cicero": [9, 10], "circl": 10, "circul": 10, "citabl": [5, 8], "clarifi": 10, "clariti": 16, "class": 19, "classic": [0, 10], "classroom": [0, 8, 13], "clean": [10, 13], "cleanli": 20, "clear": [0, 10, 14, 19, 20], "clearer": 10, "clearli": [10, 20], "cli": 10, "click": [9, 11, 12], "client": 10, "clipchamp": 10, "clock": 10, "clone": 12, "close": [2, 5, 7, 8, 14, 16], "closer": [0, 8], "cloud": 10, "clue": 10, "clutter": 10, "cm": 10, "cmd_log": 14, "co": [1, 6, 7, 13, 19], "coach": 10, "coc": 10, "cocktail": 10, "code": [1, 5, 6, 8, 9, 10, 13, 20], "codeberg": 10, "coder": 10, "coderefineri": [0, 2, 5, 6, 11, 13, 14, 20, 21], "codewhisper": 10, "coffe": 10, "cognit": 10, "cohort": 10, "colab": 10, "collab": 10, "collabor": [0, 1, 6, 7, 8, 13, 14, 19], "collat": 10, "colleagu": [5, 8, 10], "collect": [6, 7, 12, 13, 19, 20], "color": [9, 10], "colour": 10, "column": 14, "com": [5, 6, 8, 9, 10, 12, 14, 19, 20], "combin": [10, 13, 19, 20], "come": [2, 6, 8, 10, 18, 19, 20], "comfort": 10, "command": [6, 8, 9, 10, 20], "comment": [0, 1, 2, 5, 6, 10], "commit": [9, 10], "common": [0, 1, 10, 19], "commonli": [10, 11], "commun": [2, 6, 10, 21], "comp_lin": 14, "compani": 10, "compar": 10, "compel": 10, "compens": [14, 21], "compet": 10, "competit": 10, "compil": 10, "complement": [0, 19], "complet": [2, 8, 10, 14], "complex": 10, "complic": [10, 11, 12, 19], "compon": 10, "comprehens": 15, "compressor": 10, "compromis": 19, "comput": [1, 6, 7, 8, 9, 11, 19, 20], "con": 10, "concept": [0, 10, 19], "conceptu": [1, 10], "concern": 10, "conclus": [2, 10], "concucurr": 10, "conda": [8, 14], "condens": 10, "condition_on_previous_text": 20, "conduct": [6, 10], "conf": 10, "confer": 21, "confid": [1, 19], "confident": 10, "config": [10, 11, 14], "configur": [11, 12], "confirm": [6, 10, 12], "conflict": 10, "conform": 10, "confus": [10, 14, 19], "connect": [10, 11, 17], "conquer": 10, "consciou": 19, "consid": [2, 5, 10, 14, 16, 19], "consider": 10, "consist": [2, 3, 7, 9, 10, 14], "constant": [0, 10], "constantli": 10, "constel": 10, "construct": [8, 10, 16], "consum": 21, "contact": [10, 15], "contain": [7, 8, 9, 20], "container": [10, 14], "content": [0, 7, 9, 10, 13, 14, 19, 20], "context": [0, 2, 10, 19], "continu": [1, 10, 13], "continuum": 0, "contrast": 14, "contribut": [10, 13], "contributor": 1, "control": [0, 1, 7, 8, 11, 16], "convei": 19, "conveni": 10, "convent": 10, "convers": [0, 2], "convert": [5, 8, 10], "cook": 10, "cool": [6, 7, 8], "coordin": [0, 10, 13, 14, 17, 21], "copi": [6, 9, 14, 20], "core": 10, "correct": [10, 19], "correspond": [10, 14], "coteach": 10, "could": [0, 2, 8, 10, 17, 19, 20], "couldn": 10, "count": [10, 16], "countri": 1, "coupl": 10, "courag": 10, "cours": [0, 1, 2, 4, 5, 6, 8, 9, 10, 14, 16, 17, 18, 20, 21], "cover": [6, 8, 10, 12, 14, 15], "covid": [10, 21], "cph": 10, "cpu": [8, 10, 11], "cr": [2, 9, 10, 12], "creat": [0, 2, 7, 10, 12, 19], "creator": 1, "criteria": 10, "critic": 10, "crop": 10, "cross": [9, 11], "crowd": 10, "crowdsourc": 20, "crown": 10, "crucial": 10, "cry": 10, "csc": 10, "css": [10, 14], "ctfasset": 10, "ctrl": 14, "cube": 10, "cuda": 20, "cultur": [10, 16], "curios": 19, "curiou": [7, 10], "current": [1, 8, 10, 13, 20], "curriculum": 8, "curriculumn": 10, "cursor": 20, "curv": 10, "custom": [9, 10, 17, 19], "customis": 10, "cut": [10, 20], "cycl": 10, "d": [10, 19], "dai": [2, 5, 6, 8, 13, 14, 20, 21], "daili": [6, 8, 10, 13], "danger": 2, "dark": 14, "darst": 7, "darstr1": 20, "data": [2, 5, 8, 10, 20], "dataset": 10, "date": 10, "daunt": 10, "day1": 20, "deactiv": 10, "dead": 20, "deal": [2, 10], "debrief": 13, "debug": [8, 14], "decaf": 10, "decemb": 10, "decid": [9, 10, 16], "decis": 10, "declar": 2, "decomposit": 3, "decor": 14, "dedic": [0, 2, 9, 14], "deep": [2, 10], "deeper": [6, 10], "deepli": 2, "default": [10, 14], "defin": [0, 8, 10, 20], "definit": [10, 17, 20], "degre": [10, 19], "delai": [2, 10], "delet": 12, "deliev": 10, "deliv": 10, "deliveri": 0, "demand": [2, 10], "demo": [2, 9, 10, 14, 15, 19, 20], "demonstr": [4, 8, 10, 14, 16, 18, 20], "demystifi": 19, "denni": 10, "depend": [2, 6, 8, 9, 10, 20], "deploy": 7, "depth": [10, 13], "deriv": 9, "derse24": 10, "describ": [1, 8, 10, 13, 17], "descript": [10, 13, 20], "design": [1, 3, 6, 7, 9], "desir": [10, 20], "desk": 10, "desktop": 10, "destroi": 10, "detail": [0, 2, 6, 7, 10, 17], "detect": 19, "determin": 10, "dev": 10, "devast": 10, "develop": [1, 5, 6, 7, 13, 19], "deviat": [0, 19], "devic": [2, 10, 16, 20], "devil": 10, "devpixelsperpx": 14, "dhanya": 7, "diagram": 19, "dictionari": 10, "did": [5, 10, 16, 19], "didn": [10, 20], "diff": 10, "differ": [0, 1, 2, 6, 7, 9, 10, 14, 15, 16, 18, 19, 21], "difficult": [1, 5, 10, 19], "difficulti": [1, 21], "dig": 10, "digest": 10, "digit": 10, "dipietro": 10, "dir": 10, "direct": [1, 2, 8, 9, 10, 16, 17], "directli": [9, 17, 20], "director": [0, 10, 11, 13, 17], "directori": [9, 10, 14, 20], "disadvantag": [6, 9], "disagre": 10, "disciplin": [1, 10], "disclaim": 20, "discov": 10, "discret": 1, "discuss": [1, 4, 6, 14, 16, 19, 21], "disorganis": 10, "disori": 0, "displai": [2, 6, 9, 10, 14], "dissoci": 5, "distanc": 10, "distil": [10, 19], "distinct": [10, 21], "distract": [2, 10, 14], "distribut": [10, 13], "divers": [8, 10], "divid": 10, "divis": [0, 10], "dli": 10, "dmp": 10, "dna": 10, "do": [0, 1, 2, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 21], "doc": [2, 9, 10], "document": [0, 1, 5, 9, 10, 13, 14, 19], "doe": [0, 1, 5, 6, 10, 11, 14, 16, 20], "doesn": [2, 9, 10, 14, 16], "doi": 5, "domain": 10, "don": [0, 5, 6, 8, 9, 10, 14, 16, 17, 19, 20, 21], "done": [2, 7, 10, 12, 17, 19, 20, 21], "doubli": 19, "dough": 10, "down": [2, 8, 10, 11], "download": [2, 10, 20], "downsid": [10, 21], "dra": 10, "draft": [8, 10], "drag": 10, "draw": 10, "drawn": 10, "driven": 1, "drop": [0, 10, 13], "drown": 10, "drug": 10, "dry": 10, "dual": 14, "duck": 16, "due": [0, 10, 16], "durat": 2, "dure": [0, 2, 5, 6, 8, 10, 14, 16, 17, 19], "dynam": 10, "e": [0, 1, 6, 10, 13, 14, 17, 20], "each": [0, 2, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20], "ean": 10, "earli": [5, 8, 10], "earlier": [1, 5, 8, 10], "eas": 13, "easi": [2, 8, 9, 10, 11, 14, 19], "easier": [2, 5, 8, 9, 10, 14], "easiest": 10, "easili": [1, 2, 9, 10, 14, 19], "eat": 10, "echo": [10, 14], "edit": [6, 7, 9, 21], "editlist": 10, "editor": [2, 10, 20], "educ": [0, 8, 10], "edward": 10, "eest": 10, "effect": [5, 8, 10], "effici": 10, "effort": [10, 13, 19], "eg": [1, 10], "egg": 10, "eight": 10, "einstein": 10, "either": [0, 4, 9, 10, 16], "elabor": 10, "element": 10, "elimin": 14, "els": [2, 5, 8, 9, 10, 14, 16, 17, 20], "email": 10, "embrac": 19, "emoji": 10, "emot": 10, "emoticon": 10, "emphas": [9, 19], "emphasi": [8, 21], "emploi": 10, "empow": 10, "empti": [8, 10], "emul": 14, "en": [10, 20], "enabl": [2, 10], "encod": 20, "encompass": 10, "encourag": [4, 8, 10, 19], "end": [0, 2, 8, 10, 14, 16, 17, 19, 20], "energi": 2, "engag": [0, 7, 8, 10, 19, 21], "engin": 10, "english": 10, "enhanc": [7, 10], "enjoi": 10, "enjoy": [10, 16], "enough": [1, 8, 10, 20], "ensur": [0, 2, 10, 16], "enter": 14, "enthusiast": 10, "entiti": 10, "entri": [10, 14], "enviro": 10, "environ": [2, 6, 8, 9, 10, 12, 13, 19, 20], "environemnt": 10, "epcc": 10, "episod": [2, 6, 8, 11, 12, 13, 17, 19, 20], "epsisod": 10, "epub": 9, "equal": [2, 10, 20], "equip": [10, 16], "equival": 10, "erambl": 10, "error": [5, 10, 14, 19], "especi": [0, 10, 19, 20], "essenc": 19, "essenti": [8, 10, 13, 14], "est": 10, "estim": 10, "et": 10, "etc": [1, 2, 6, 7, 9, 10, 12, 13, 14, 16, 17, 20, 21], "etern": 5, "etherpad": 10, "europ": 10, "evalu": [8, 10], "even": [0, 2, 6, 9, 10, 14, 16, 19, 20, 21], "event": [6, 10, 13, 14, 16, 21], "eventu": 10, "ever": [10, 16], "everett": 10, "everi": [0, 2, 7, 9, 10, 14], "everybodi": 10, "everyon": [6, 7, 9, 10, 13, 16, 20], "everyth": [0, 9, 10, 12, 19, 20], "everytim": 10, "everywher": 10, "evolv": 1, "ex": 10, "exam": 10, "exampl": [0, 1, 8, 10, 14, 16, 19, 20], "exc": 10, "excalideck": 10, "excalidraw": 10, "excel": 10, "except": 10, "excercis": 10, "excerpt": 20, "exchang": [7, 10], "excit": [10, 16], "execut": [9, 10, 14], "exemplifi": 10, "exercic": 10, "exercis": [1, 3, 6, 13, 19, 21], "exhaust": 10, "exist": [1, 9, 10], "expand": 10, "expect": [5, 8, 10, 20], "expens": [10, 16], "experi": [1, 2, 5, 7, 13, 14, 19], "experienc": [0, 8, 19], "expert": [1, 5, 10, 13, 19], "explain": [0, 1, 3, 10, 19], "explan": [10, 17, 20], "explicit": 19, "explicitli": 10, "explor": [6, 10], "explos": 10, "export": 14, "expos": 8, "express": [8, 10], "extant": 10, "extend": [9, 10], "extens": [8, 9, 10], "extern": [16, 20], "extra": [9, 10, 14], "extrapol": 10, "extrem": 16, "ey": [2, 14], "f": [10, 14], "face": 10, "facilit": [7, 13], "fact": [10, 19], "factor": [10, 20], "fail": [10, 14], "failur": 10, "fair": 10, "fairli": 10, "faith": 10, "fake": 10, "fall": 10, "fals": 20, "familar": 6, "familiar": [10, 11], "fan": 10, "fanci": 10, "far": [5, 6, 10], "fashion": 19, "fast": [2, 5, 10, 19, 20, 21], "faster": 10, "favor": 1, "favorit": [8, 10], "feasibl": 10, "featur": [9, 10, 11, 13], "featureless": 10, "februari": 1, "feedback": [0, 1, 6, 7, 8, 13, 14, 15, 19], "feel": [0, 1, 10, 13, 19, 21], "fell": 10, "fellow": [7, 10], "felt": [10, 19], "few": [2, 5, 10, 14, 19, 20], "ffmpeg": [6, 10], "fi": [10, 20], "fidgit": 10, "field": [5, 10], "fiffer": 10, "figma": 10, "figur": [2, 5, 8, 10, 15, 16, 17], "fil": 10, "file": [9, 10, 14], "filesystem": 10, "fill": [0, 8, 10, 13], "final": [6, 10], "find": [1, 2, 9, 10, 13, 14, 19, 20], "findabl": [8, 10], "fine": [9, 10], "fire": 10, "firefox": 14, "first": [0, 1, 2, 5, 6, 8, 10, 15, 16, 17, 20], "fish": 14, "fish_preexec": 14, "fit": [0, 9, 10], "fix": [2, 5, 9, 10, 16, 20], "fl": 10, "flat": 10, "flexibl": 10, "flinga": 10, "flood": 2, "flow": [0, 2, 9, 10], "flowchat": 20, "fly": 10, "focu": [0, 2, 10, 14, 17, 21], "focus": [0, 10, 13, 21], "folder": 10, "folk": 10, "follow": [1, 2, 5, 8, 9, 10, 13, 14, 20], "font": [9, 10], "fool": 10, "forbidden": 10, "forc": 0, "forev": 10, "forget": [10, 20], "forgiv": 10, "fork": [9, 10], "form": [0, 1, 2, 5, 8, 10, 20, 21], "formal": [10, 11], "format": [1, 8, 10], "former": 10, "formul": 5, "fortun": 10, "forward": [0, 10], "foster": 10, "found": [4, 6, 10], "four": [7, 10, 19, 20], "fragment": 9, "frame": [10, 20], "framework": [3, 10], "franklin": 10, "free": [1, 5, 7, 9, 10, 11, 14, 21], "freelanc": 10, "freir": 10, "frequenc": 10, "frequent": 10, "friend": 19, "friendli": [7, 10], "from": [0, 1, 2, 4, 5, 6, 7, 8, 9, 11, 12, 14, 17, 19, 20, 21], "fruit": [7, 10], "frustrat": 10, "full": [10, 16, 20, 21], "fullhd": 14, "fulli": [1, 10, 19], "fun": [10, 19], "function": [9, 10, 14], "fund": 1, "funder": 5, "further": 6, "fuse": 0, "futur": [1, 5, 6, 7, 10, 19, 20], "g": [0, 10, 17, 20], "gain": 10, "game": 16, "gap": 0, "garbag": 10, "garbl": 20, "gatekeep": 10, "gather": 13, "gave": 18, "gcjexwc8cf": 19, "gdpr": 10, "ge": 10, "gear": 10, "gem": [6, 7, 14], "gener": [0, 6, 7, 8, 9, 13, 21], "geniu": 10, "gentl": 10, "get": [0, 1, 3, 5, 6, 7, 8, 9, 10, 11, 14, 16, 19], "getzola": 10, "ghost": 10, "gi": 10, "giant": 10, "gig": 10, "gigo": 10, "git": [1, 8, 9, 10, 12, 13], "gitautopush": 10, "gitconfig": 14, "github": [2, 5, 6, 10, 12, 14, 20], "gitlab": 8, "give": [1, 2, 5, 9, 10, 12, 13, 14, 19, 20, 21], "given": [1, 8, 10], "giver": 10, "global": 10, "gme": 10, "go": [0, 2, 6, 8, 10, 14, 16, 19, 20], "goal": [2, 4, 5, 8, 10, 13, 14, 19], "goe": [2, 10, 13], "gone": 10, "good": [0, 1, 2, 5, 7, 8, 9, 10, 14, 19, 20, 21], "googl": [2, 10], "got": [1, 6, 10, 14, 19, 21], "gotten": 10, "gpu": 10, "grade": 21, "gradual": 10, "grain": 10, "graphic": [10, 11, 12], "grasp": 10, "great": [7, 10, 13, 19], "greater": 14, "greatest": 19, "green": 10, "grei": 14, "grew": 1, "gritti": 19, "ground": [10, 19], "group": [0, 6, 7, 10, 13, 14], "grow": 10, "guarante": 20, "guess": 10, "guest": 10, "gui": 10, "guid": [7, 8, 10, 13, 17, 19], "gwdg": 10, "h1": 14, "h2": 14, "h3": 14, "h4": 14, "h5": 14, "h6": 14, "h7": 14, "ha": [1, 5, 8, 9, 10, 12, 13, 16, 17, 19], "habit": 0, "hackathon": 10, "hackmd": [0, 2, 10, 20], "had": [5, 10, 19], "hale": 10, "half": [13, 14], "hand": [0, 1, 6, 10, 12, 18], "handbook": 8, "handl": [10, 13], "happen": [2, 10, 13, 17, 20], "happend": 10, "happi": 10, "hard": [9, 10, 14, 16, 17, 19, 20, 21], "harder": [10, 21], "hardest": 10, "hardwar": [10, 19], "hashnod": 10, "hasn": 10, "have": [0, 1, 2, 5, 6, 7, 8, 9, 10, 13, 14, 15, 16, 17, 18, 19, 20, 21], "haven": [8, 10, 14], "hc": 10, "he": 10, "head": [2, 10, 12, 17, 19], "headphon": [10, 16], "headset": [10, 16], "hear": [10, 16], "heard": [10, 16], "hedgedoc": [0, 2, 10], "heidi": 10, "height": 14, "heinlein": 10, "held": 0, "help": [0, 1, 2, 5, 6, 8, 9, 10, 13, 14, 15, 16, 19, 20, 21], "helper": [2, 6, 7, 10, 13], "here": [0, 1, 2, 4, 6, 8, 9, 10, 14, 19, 20, 21], "herford": 10, "heterogen": 10, "hide": 10, "high": [1, 8, 16, 20], "higher": 10, "highli": [2, 10], "highlight": [2, 8, 9, 10], "him": 10, "himself": 10, "hint": [2, 20], "histori": [9, 10], "historysavepath": 14, "histtimeformat": 14, "hole": 19, "home": [10, 19], "homepag": 10, "hope": 10, "hopefulli": [2, 8], "horizont": 14, "horribl": 2, "host": [1, 9, 10], "hostabl": 9, "hour": [2, 5, 10, 20, 21], "hous": 10, "hover": 20, "how": [0, 1, 3, 6, 7, 9, 11, 12, 16, 19, 21], "howev": [0, 1, 10], "hpc": [10, 14, 20, 21], "html": [9, 10], "http": [2, 5, 6, 8, 9, 10, 12, 14, 19, 20], "huge": [10, 21], "human": 10, "humour": 19, "hustl": 10, "hybrid": 10, "hypothesi": 20, "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20], "i1": 14, "i3": 10, "ic": 10, "icebreak": [2, 6], "icon": 9, "icp": 10, "id": 10, "idcc": 10, "idcc24": 10, "idea": [1, 5, 8, 10, 14], "ideal": [10, 14], "identifi": [8, 10], "ie": 10, "imag": [1, 10, 13], "imagin": 10, "imbalanc": 16, "imform": 10, "imho": 10, "immedi": [2, 10, 19, 20], "imovi": 10, "impact": [6, 7], "imperfect": 8, "implement": 10, "implicitli": 10, "import": [0, 1, 2, 8, 9, 10, 11, 12, 13, 14, 19, 20], "imposs": [10, 14], "impress": 10, "impro": 10, "improv": [1, 2, 5, 7, 9, 14, 16, 20], "improvis": 10, "incent": 20, "inclin": 19, "includ": [0, 2, 10, 14, 19, 20], "inclus": 10, "inconveni": 10, "incorpor": 5, "increas": 10, "increment": 10, "inde": 10, "independ": [1, 10, 19], "index": 10, "indic": [2, 10, 13, 20], "individu": [0, 10, 12, 16, 17, 19], "industri": 10, "inertia": 10, "influenc": 10, "info": [2, 10, 13, 20], "inform": [1, 2, 6, 7, 10, 14, 19, 20], "infrastructur": [1, 19], "infrequ": 21, "initi": [2, 8, 10, 20], "initial_prompt": 20, "inkscap": 10, "inlcud": 1, "inlin": 9, "inner": 10, "input": [9, 10, 16, 20], "insid": 10, "insight": 10, "inspir": [5, 9, 10], "instal": [0, 6, 9, 10, 13, 14, 20], "instanc": [0, 9, 10], "instant": [2, 21], "instead": [2, 5, 8, 9, 10, 19, 20], "institut": [1, 5], "instruct": [0, 2, 10, 13, 14, 20], "instructor": [1, 7, 10], "int": 10, "intak": 10, "integr": [10, 13], "intend": [10, 19], "intens": 2, "intent": 19, "interact": [0, 2, 6, 7, 9, 10, 13, 16, 19, 20, 21], "interest": [1, 6, 7, 8, 10, 13, 14, 19], "interfac": [9, 10], "intergr": 10, "intermedi": [1, 10], "intern": 15, "internet": [10, 11], "interoper": 10, "interpret": 2, "interrupt": [0, 2], "interview": 10, "intro": [7, 9, 10, 20], "introduc": [10, 14], "introduct": [6, 7, 8, 12, 15, 20], "introductori": [2, 15], "intuit": 10, "invent": 20, "invert": 8, "invest": 10, "invit": 13, "involv": [1, 10], "io": [2, 5, 6, 8, 9, 10, 14, 20], "iron": 10, "isn": [2, 6, 10, 14, 16, 17, 19, 21], "isol": [8, 10], "issu": [1, 5, 6, 8, 9, 10, 13, 16, 19], "istockphoto": 10, "item": [2, 5, 10], "iter": [1, 7], "its": [0, 1, 10, 14, 20], "itself": [0, 1, 5, 9, 10], "j": 10, "jame": 10, "jargon": [10, 19], "jarno": 7, "jekyl": 8, "jitsi": 10, "job": [10, 19], "joi": 10, "join": [0, 1, 2, 6, 7, 10, 13], "jointli": 0, "joke": 10, "jonathan": 10, "journal": 10, "joyc": 10, "jpg": 10, "json": 12, "judg": [5, 10], "jump": [10, 13, 20], "jupyt": [1, 8, 9, 10, 14], "jupyterbook": 9, "jupyterhub": 10, "jupyterlab": 10, "just": [1, 2, 5, 7, 8, 9, 10, 12, 14, 15, 19, 20], "justifi": 10, "k": 10, "kahoot": 10, "kao": 10, "kb0068677": 10, "kdenliv": 10, "keep": [0, 1, 2, 10, 13, 17, 19], "kei": [1, 10, 13, 20], "keller": 10, "kept": 10, "keyboard": [10, 14], "kick": 10, "kickstart": [14, 20, 21], "kid": 10, "kind": [2, 10, 13, 15, 16], "kitchen": 10, "knead": 10, "knew": [8, 10], "know": [0, 1, 3, 5, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20], "knowledg": [9, 10, 19], "known": [1, 10, 11, 19], "kth": 1, "l": 14, "l1": 14, "l2": 14, "l3": 14, "l8my5kygc": 10, "la": 10, "lab": 10, "label": 10, "labor": [0, 10], "lai": [10, 11], "landscap": 14, "lang": [10, 20], "languag": [1, 8, 10, 19], "laptop": [11, 14], "larg": [2, 7, 10, 11, 13, 14, 19, 20], "larger": [0, 8, 10, 21], "largest": 21, "last": [6, 10], "late": [10, 14, 20], "latenc": [10, 16], "later": [2, 5, 7, 8, 9, 10, 12, 14, 17, 20], "latest": [2, 10, 14, 19], "latex": [8, 9, 10], "latter": [7, 10], "laugh": 10, "layout": 12, "lead": [0, 5, 10, 20], "leader": 16, "lean": 10, "leap": 10, "learn": [0, 1, 6, 7, 10, 11, 13, 17, 19, 20, 21], "learner": [0, 1, 2, 5, 8, 10, 19, 20], "least": 10, "leav": [2, 10, 12, 13, 20], "lectur": [0, 2, 10, 19], "led": 10, "left": [2, 14, 20], "legaci": 14, "length": [6, 10], "less": [0, 10, 14, 16, 19, 21], "lesson": [0, 1, 2, 6, 7, 12, 13, 14, 15, 17, 18, 19, 20], "let": [1, 2, 10, 11, 12, 13, 16, 20], "level": [1, 2, 6, 8, 9, 10], "licens": [8, 10], "life": [10, 15, 19], "lifecycl": 10, "light": [10, 14], "lightn": 6, "like": [0, 1, 2, 4, 6, 7, 8, 9, 14, 16, 19, 20], "likert": 10, "limit": [9, 10, 16, 20, 21], "lincoln": 10, "lindi": 7, "line": [2, 6, 8, 9, 10, 14, 20], "link": [2, 5, 6, 7, 9, 10, 19], "linkedin": 10, "linux": [2, 8, 9, 10, 14, 20], "list": [8, 10, 19, 20], "listen": [10, 16, 19], "liter": [0, 10], "littl": 10, "live": [2, 8, 10, 19], "livestream": [6, 10, 11, 20, 21], "ll": [9, 10, 11, 12, 17], "local": [0, 1, 6, 8, 10, 14], "localhost": 12, "locat": [10, 16], "log": [10, 14], "logic": [2, 10], "login": 2, "logo": 9, "long": [2, 5, 9, 10, 12, 16, 19, 20, 21], "longer": [9, 10], "look": [0, 2, 6, 8, 9, 10, 13, 14, 16, 17, 19, 20], "loop": 10, "loos": 10, "lose": [2, 10], "lost": [8, 10, 14, 20], "lot": [5, 7, 8, 10, 14, 15, 16, 17, 18, 19], "loud": [10, 16], "louder": [10, 16], "loudest": 10, "love": 10, "low": [6, 10, 16], "lower": [10, 13, 16], "luck": 10, "lucki": 10, "luckili": 10, "lyric": 10, "m": [10, 19], "mac": 10, "machin": 10, "made": [9, 10, 12, 13, 14], "magic": 19, "mai": [0, 1, 2, 6, 8, 10, 11, 12, 14, 15, 16, 19, 20], "mail": [6, 10, 13], "main": [0, 1, 2, 3, 6, 8, 10, 13, 14, 17, 19, 20], "mainli": 10, "maintain": [0, 1, 21], "major": [1, 5, 10], "make": [0, 1, 2, 5, 6, 8, 9, 10, 11, 12, 14, 16, 19, 21], "maker": 10, "man": 10, "manag": [8, 9, 10, 11, 13, 14, 17], "mani": [0, 1, 6, 9, 14, 15, 19, 21], "mankind": 10, "manual": [0, 8, 10, 11, 12, 13, 14, 20], "map": [10, 19], "markdown": [2, 8, 9, 10], "mass": [10, 21], "master": [10, 12], "match": [5, 10, 16], "materi": [0, 1, 2, 3, 5, 7, 9, 10, 13, 19], "materti": 10, "matter": [10, 13, 16], "max": 10, "maximum": 14, "mayb": [2, 8, 10], "mbit": 11, "md": 10, "mdbook": 10, "me": [10, 19], "mean": [10, 19, 20], "meant": 10, "measur": [6, 7], "mechan": 5, "media": 10, "mediocr": 10, "medium": [10, 16, 21], "meet": [1, 8, 10, 13, 16], "meetup": 13, "mega": 21, "member": 10, "memor": 19, "memori": [8, 10, 11], "mental": [2, 7], "mention": 10, "mentor": 15, "mentorship": 19, "menu": [10, 12, 14], "mere": 10, "merg": [8, 10], "messag": [8, 9, 10], "messi": 10, "met": 10, "meta": 2, "metaphor": 10, "method": [9, 10], "methodlogi": 10, "mic": 10, "michel": 10, "microphon": [6, 10, 16], "microsoft": 10, "mid": 10, "middl": [5, 10], "midst": 10, "might": [0, 6, 9, 10, 14, 16, 19, 20], "min": [3, 4, 6, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21], "mind": [0, 2, 10, 19], "mindset": 10, "mini": 10, "minim": [2, 9, 10, 14, 19, 20], "minimum": [13, 14], "minor": 10, "minut": [0, 2, 4, 8, 10, 14], "miro": 10, "mirror": 14, "misconcept": 8, "miss": [6, 10, 16, 19, 20], "mistak": [8, 10, 19, 20], "mistyp": 10, "mitig": 10, "mix": [0, 7, 10], "mixer": 11, "mkv": 20, "mobil": 2, "mode": [2, 10, 14, 20], "model": 10, "modesti": 10, "modif": [8, 9], "modifi": [10, 12, 20], "modular": [1, 5, 7, 8, 10], "moment": [10, 19], "mondai": 10, "monei": 10, "monitor": [10, 11, 14], "monologu": 10, "month": 10, "more": [0, 1, 2, 5, 7, 8, 9, 10, 11, 12, 13, 14, 16, 19, 21], "morn": 10, "most": [0, 6, 9, 10, 11, 12, 13, 14, 16, 19, 20, 21], "mostli": [0, 1, 10], "motiv": [1, 5, 10, 14, 19, 20], "motto": 10, "mount": [10, 16], "mous": [10, 20], "move": [0, 8, 10, 13, 20], "movement": 10, "movi": 10, "mpi": 10, "much": [0, 1, 2, 6, 8, 9, 10, 14, 16, 19, 20, 21], "multi": [2, 10], "multipl": [0, 2, 8, 10, 13, 14], "must": [6, 8, 10, 20], "mutual": 10, "mv": 12, "mwakok": 10, "my": [5, 8, 10, 19, 21], "mynam": 2, "myst": [9, 10], "myst_pars": 10, "mysteri": 19, "n": [2, 10, 14], "n0": 14, "n2ak": 20, "name": [2, 5, 10, 16, 20], "narr": 10, "narrat": 10, "narrow": 10, "natur": [0, 10, 19], "navig": [9, 14], "nbinder": 10, "nbviewer": 10, "necessari": [2, 10, 13, 19, 20], "need": [0, 1, 2, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 19, 20], "negoti": 10, "neic": [1, 6], "nerd_fac": 10, "nerded_fac": 10, "nest": 2, "net": 10, "network": [1, 10], "neutral": 5, "never": [2, 6, 10, 12, 19, 20], "new": [0, 2, 7, 9, 10, 14, 15, 17, 19, 20], "next": [2, 5, 6, 7, 8, 9, 10, 11, 13, 16, 19, 20], "nice": [2, 9, 10], "nicer": [10, 21], "nickbearman": 10, "night": 10, "nitti": 19, "nix": 10, "nlastcommand": 10, "nobodi": [10, 14], "nois": [10, 16], "non": [2, 8, 10, 16], "none": [5, 10], "nordic": [1, 13], "norepli": 6, "normal": [6, 9, 10, 16, 21], "notabl": 16, "note": [6, 7, 15], "notebook": [1, 5, 8, 9, 10, 14], "notepad": 10, "notesrecommend": 10, "noth": [10, 14], "notic": [10, 16, 19, 20], "notif": 2, "notifi": 10, "notion": 19, "novemb": 10, "novic": [10, 19], "now": [0, 2, 5, 7, 8, 9, 10, 20, 21], "nuisanc": 10, "number": [0, 6, 8, 10], "numer": 10, "nvidia": 10, "o": [5, 10, 20], "ob": [6, 7, 17, 20], "obei": 10, "object": [6, 7, 10], "obs_cr": 12, "obviou": [2, 10, 20], "occasion": [0, 1, 10, 19], "octob": 1, "odd": 10, "odt": 10, "ofc": 10, "off": [0, 14, 19, 20], "offens": 19, "offer": [6, 7, 8, 10, 13, 19], "offic": 10, "offici": 10, "often": [0, 1, 2, 10, 19], "ok": [10, 14, 20], "old": [10, 12], "older": [2, 20], "oliv": 10, "onboard": [0, 6, 10, 13], "onc": [10, 11, 12, 16, 19], "one": [0, 1, 2, 5, 8, 9, 10, 13, 14, 16, 19, 20, 21], "onedr": 10, "ones": [2, 7, 10, 13, 17], "onli": [0, 2, 6, 7, 8, 9, 10, 13, 14, 15, 19, 20], "onlin": [0, 1, 2, 6, 7, 10, 13, 15, 19], "onsit": 10, "oo": 10, "ooo": [5, 10], "oooo": 10, "ooooo": 10, "oooooo": [5, 10], "ooooooo": 10, "oooooooo": 10, "ooooooooooooooooooo": 5, "op": 10, "open": [0, 1, 2, 6, 7, 8, 9, 14, 19], "openai": 10, "openshot": 10, "oper": [9, 10, 13], "opin": 10, "opinion": [10, 16], "opportun": [1, 2, 10], "oppos": 10, "opposit": [10, 19], "optim": [10, 21], "optimum": 13, "option": [2, 5, 6, 10, 11, 12, 14, 20], "order": [8, 10, 16], "org": [1, 5, 6, 7, 8, 9, 10], "organ": [0, 1, 7, 8, 9, 10, 13], "organis": 10, "orient": 10, "origin": [10, 20], "oss": 10, "other": [0, 1, 2, 5, 6, 7, 8, 9, 10, 16, 19, 20, 21], "otherwis": [10, 15, 20], "our": [0, 4, 5, 9, 10, 12, 13, 14, 15, 16, 17, 20, 21], "out": [1, 2, 5, 6, 9, 10, 11, 13, 14, 15, 16, 17, 20], "outcom": [10, 19], "outlin": [10, 13, 15], "output": [9, 10, 14], "output_format": 20, "outro": [6, 10], "outsid": [7, 10, 20], "outstand": 10, "ov": 10, "over": [0, 5, 7, 8, 10, 14, 16, 19, 20], "overal": [8, 9, 10, 14, 20], "overarch": 8, "overcom": 10, "overhead": 10, "overkil": 11, "overload": [2, 10], "oversight": 10, "overview": [1, 6, 8, 10], "overwhelm": 19, "own": [1, 2, 8, 10, 13, 19, 21], "oxford": 10, "p": 10, "pace": [5, 10], "packag": 10, "pad": 10, "page": [2, 8, 9, 10, 13, 14, 16, 20], "paid": 10, "paint": 8, "pane": 14, "panel": [10, 11, 14], "panick": 16, "paolo": 10, "paper": [8, 10], "paradigm": 10, "parallel": [0, 8, 10, 20], "parser": 9, "parson": 8, "part": [0, 1, 2, 3, 6, 8, 10, 14, 16, 17, 18, 20, 21], "part1": 20, "parti": 10, "partial": 10, "particip": [2, 4, 5, 7, 8, 10, 13, 14, 19, 20], "particu": 10, "particular": [0, 10], "particularli": [5, 10, 14], "partli": 10, "partner": [7, 10], "pass": [6, 10], "past": [8, 10, 20], "path": [10, 13, 20], "pathwai": 10, "pattern": [3, 10], "paus": [10, 14], "pavucontrol": 10, "pdf": [9, 10], "pedagog": 10, "peer": 13, "pen": 10, "pencil": 9, "peng": 10, "peopl": [1, 2, 8, 9, 10, 14, 16, 19, 20, 21], "per": [10, 20], "perceiv": 10, "perfect": [2, 8, 20], "perfectli": 19, "perform": [1, 8], "perhap": [10, 20], "period": [2, 10, 19], "periscop": 10, "perman": 10, "permiss": 2, "persist": 5, "person": [0, 2, 10, 13, 16, 17, 19, 21], "persona": [8, 10, 19], "personalis": 10, "personel": 10, "perspect": [7, 19], "phase": 13, "phd": 10, "philosohi": 6, "philosophi": [7, 9], "phrase": 19, "physic": 10, "pick": [8, 10, 16], "pickl": 10, "pickup": 16, "pictur": [0, 5, 8, 14], "pid": 10, "piec": [10, 11, 12], "pinimg": 10, "pioneer": 10, "pip": [10, 12, 14, 20], "pipe": 10, "pitfal": 14, "place": [2, 5, 9, 10, 19, 20, 21], "plai": 10, "plain": 10, "plan": [0, 1, 2, 5, 8, 10, 14, 18], "planet": 10, "platform": [10, 11, 17], "player": 10, "playlist": [19, 20], "pleas": [2, 5, 6, 7, 8, 10, 14, 15, 16, 19], "pleasant": 10, "plenti": [6, 10], "plplblyhczjaahf89p": 19, "plu": 14, "plug": 16, "plzlvms9rf3nmkr2jmglan4su3ojwtwmvw": 20, "png": 10, "poet": 10, "point": [2, 8, 9, 10, 17, 19, 20], "polar": 10, "polish": 10, "pop": 10, "popular": 10, "port": [1, 8], "portion": [10, 11, 14], "portrait": 10, "posit": 10, "possibl": [1, 2, 9, 10, 14, 16, 19, 21], "possibli": [0, 10, 14, 20], "post": [5, 7, 8, 10, 13], "potenti": [0, 16], "power": [10, 11], "powershel": 14, "pptx": 10, "pr": 2, "practic": [0, 1, 3, 7, 8, 15, 16, 18], "pre": [5, 10, 12], "precis": [10, 19], "predict": 10, "preexec": 14, "prefer": [2, 10, 11, 14], "premis": 10, "prep": 10, "prepar": [0, 7, 8, 13, 15, 16, 19], "prerequisit": [7, 9, 10, 20], "presemo": 10, "presenc": 10, "present": [1, 4, 6, 7, 8, 10, 13, 19, 20, 21], "presentor": 10, "presist": 10, "press": [8, 14], "presum": 10, "pretend": 10, "pretti": [8, 9, 10, 16], "preview": [8, 9, 10], "previou": [0, 6, 7, 9, 10, 12, 13, 19, 20], "price": 16, "primari": 14, "principl": [0, 10, 20], "print": [10, 14], "prior": 1, "priorit": 10, "prioriti": [10, 20], "privaci": [10, 20, 21], "privat": [2, 10], "prize": 10, "pro": 10, "prob": 10, "probabl": [8, 9, 10, 11, 14, 16, 20, 21], "problem": [1, 2, 3, 5, 10, 19], "procedur": [0, 16], "process": [0, 10, 20], "procur": 16, "produc": [10, 20], "product": [6, 10, 15, 19], "profan": 10, "profession": [16, 19], "profil": [8, 10, 12, 14], "program": [1, 8, 10, 14, 19], "programm": [10, 14], "progress": [2, 10], "project": [6, 7, 8, 9, 10], "prompt": [10, 20], "prompt_command": 14, "proper": [6, 8, 10], "propos": [0, 1, 6, 9, 10], "propsal": 9, "protein": 10, "prove": 10, "proven": 7, "provid": [1, 2, 5, 6, 9, 10, 14, 20], "ps1": 14, "psreadlineopt": 14, "public": [2, 5, 9, 10], "publicli": [1, 10], "publish": [2, 5, 8, 10], "pull": [8, 9, 10, 19, 20], "pulsemix": 10, "pun": 10, "punctuat": 20, "purchas": 11, "pure": 14, "puriti": 10, "purpos": [9, 12], "push": [9, 10, 14], "pushpada": 7, "put": [2, 8, 10, 18], "py": [10, 12], "python": [6, 8, 9, 10, 12, 14, 20], "pyyaml": 20, "q": [2, 10, 13, 18], "qgi": 10, "qua": 10, "qualifi": 1, "qualiti": [7, 8, 20], "quantifi": [5, 10], "quarto": 10, "question": [0, 1, 7, 8, 9, 11, 12, 13, 14, 15, 19], "quick": [2, 8, 10, 20], "quickli": [2, 6, 10, 14, 16, 20], "quicktim": 10, "quiet": [10, 16], "quieter": 10, "quietest": 10, "quit": [2, 10, 19], "quiz": 10, "quizz": 10, "r": [9, 10], "rabbit": 19, "radovan": [7, 10], "rais": [1, 2, 19], "ram": 10, "ran": 10, "random": [6, 8, 10], "rang": [10, 16], "rantaharju": 7, "rapid": 21, "rapidli": 14, "rare": [10, 19], "rate": 10, "rather": [2, 10, 12], "ratio": 10, "raw": 10, "rb": 10, "rd": 10, "re": [10, 12, 15, 16, 19, 20], "reach": [5, 10, 21], "read": [0, 2, 6, 9, 10, 14, 19], "readabl": 14, "reader": 20, "readi": [7, 10, 13, 20], "readili": 10, "readm": 10, "readthedoc": [8, 10], "real": [2, 10, 11, 15, 19, 20], "realist": [10, 14], "realiti": 0, "realiz": [10, 16, 19], "realli": [2, 8, 10, 14], "reason": [2, 5, 8, 10, 11, 16], "recent": [9, 10, 14], "recip": 10, "recogn": 10, "recognit": [3, 10], "recommend": [2, 6, 10, 13, 14, 18, 19, 21], "record": [8, 10, 13, 15, 20], "recov": [8, 14], "recreat": 12, "red": [10, 14], "redesign": 8, "reduc": [0, 2, 10, 14], "reencod": 20, "ref": 12, "refer": [2, 10], "referenc": 9, "refin": [10, 15], "refinari": 10, "refineri": 10, "reformul": 5, "refresh": 10, "regard": 13, "regist": 7, "registr": [5, 6, 7, 10, 13, 21], "regular": [8, 10], "rehears": 10, "reichent": 10, "reign": 10, "rel": 10, "relat": [10, 19], "relationship": 10, "relax": 10, "relearn": 10, "releas": [6, 8, 10, 20], "relev": [0, 8, 10, 14], "reli": 0, "remain": [2, 10], "remark": [0, 10], "remarkj": 10, "rememb": [8, 10, 20], "remind": [2, 10], "remot": [0, 10, 14, 17, 20, 21], "remov": [2, 5, 10, 14, 20], "renam": [10, 14], "render": 10, "repeat": [10, 19], "repetet": 10, "rephras": 10, "repli": 10, "repo": [9, 10], "repons": 10, "report": [5, 10], "repositori": [1, 8, 9, 10, 12], "repres": 10, "reproduc": [1, 5, 10], "request": [8, 9, 10, 19], "requir": [0, 2, 6, 9, 10, 14, 16, 21], "requisit": 10, "research": [1, 5, 10, 14, 19, 21], "reset": 12, "resist": 10, "resiz": [10, 14], "resolut": 12, "resourc": [5, 10], "respect": [9, 10, 12, 16], "respond": 5, "respons": [0, 5, 10], "rest": [9, 10, 20], "restructur": 9, "result": [5, 10, 20], "resus": 10, "return": 14, "reupload": 10, "reus": [7, 8, 9, 10, 13, 15], "reusabl": [5, 10, 21], "reveal": 10, "revealj": 10, "revers": 14, "review": [10, 20, 21], "revis": [0, 10], "revisit": 1, "rewrit": [8, 10], "richard": [7, 10], "right": [2, 5, 10, 13, 14, 16, 19, 20], "rigor": [2, 10], "rise": [5, 10], "risk": [2, 5, 10, 20, 21], "ritchi": 10, "rkdarst": 12, "rmarkdown": [9, 10], "robert": 10, "robot": 10, "role": [0, 2, 6, 10, 17, 20], "room": [0, 2, 8, 16, 19, 20], "room1": 10, "room2": 10, "root": 2, "rough": [8, 10], "roughli": [9, 10], "rse": 10, "rst": [9, 10], "rubi": 8, "rule": 10, "run": [1, 5, 9, 10, 12, 13, 14], "runner": 10, "rush": 10, "rust": 10, "rxqefefl3t5b": 10, "sacr": 10, "safe": 10, "sai": [0, 2, 10, 14, 16, 20], "said": [2, 10, 20], "saluting_fac": 10, "samantha": [7, 10], "same": [0, 6, 9, 10, 14, 16, 17, 19, 20], "sampl": [9, 10], "sandpap": 10, "satisfi": 10, "satur": 14, "save": [0, 5, 10, 14], "sc": 10, "scale": [5, 7, 10, 13, 21], "scan": 2, "scari": 17, "scenario": 10, "scene": [10, 12, 13], "schedul": [6, 20], "scicomp": 20, "scicompintro": 20, "scienc": [10, 20], "scientif": [10, 20], "scip": 20, "scisoft": 8, "scope": [2, 10], "scratch": [11, 12], "scream": 10, "screen": [4, 7, 17, 20], "screencast": 11, "screenkei": 10, "screenshar": [2, 6, 7, 10], "screenshot": [10, 14], "screenshot_2023": 10, "script": [1, 10, 14, 19], "scroll": [10, 20], "scrum": 10, "search": [2, 10, 14], "season": 10, "sec": 10, "second": [10, 11, 20], "section": [1, 2, 10, 12, 13, 20], "secur": 2, "sed": [10, 14], "see": [0, 1, 2, 6, 8, 9, 10, 12, 13, 14, 17, 19], "seed": 10, "seedl": 10, "seek": 10, "seem": [0, 1, 10, 11, 12, 16, 19], "seen": [0, 2, 5, 7, 10], "segment": [10, 20], "seibold": 10, "select": [2, 10], "self": [7, 8, 10, 19], "sell": 9, "seminar": 10, "send": [2, 9, 10, 13, 19], "sens": [1, 2, 10, 11, 12], "sensit": 19, "sent": [6, 10], "sentenc": [10, 19, 20], "sep": 7, "separ": [8, 10, 14, 19, 20, 21], "sequenc": 20, "serial": 19, "serv": [0, 10], "server": [12, 14], "servic": [1, 10], "sese": 1, "session": [0, 1, 2, 8, 12, 13, 14, 17, 19, 20], "session_nam": 14, "set": [6, 9, 10, 13, 15, 16, 19, 20], "setup": [6, 7, 8, 11, 16], "sever": [8, 10, 16, 20, 21], "sfor": 10, "share": [2, 5, 6, 7, 9, 12, 13, 15, 17, 19, 20], "shareabl": 9, "sheet": 10, "shell": [8, 9, 10, 14], "shell_command": 14, "shellshar": 10, "shift": 14, "shokingli": 10, "short": [3, 4, 10, 12, 20], "shortcom": 10, "shortcut": [10, 14], "shorten": 13, "shortest": 10, "shot": [10, 21], "shotcut": 10, "should": [2, 5, 8, 9, 10, 14, 16, 19, 20], "shouldn": [2, 10, 16, 17], "show": [0, 1, 5, 6, 8, 9, 10, 13, 14, 16, 18, 19], "shown": 14, "shy": 10, "sick": 10, "side": [6, 10, 14], "sign": [10, 19], "signal": [8, 10, 19], "silenc": 10, "silent": 10, "silli": 10, "similar": [0, 2, 10, 14, 16, 19], "simpl": [8, 10, 14, 19, 20], "simpler": [8, 10], "simpli": [10, 19], "simplic": 10, "simplifi": [10, 14], "simul": [10, 20], "simultan": 10, "sinc": [2, 5, 10, 12, 13, 14, 15, 19, 20], "sine": 10, "singl": [0, 9, 10, 13, 14, 21], "sit": 10, "site": [2, 9, 10], "situat": [0, 14], "six": 10, "size": [10, 21], "skill": [0, 7, 10, 19], "skip": 19, "sleep": 10, "sleepi": 10, "sleeppi": 10, "slice": 20, "slide": [3, 8, 9, 10, 19], "slider": 10, "slido": 10, "slightli": [2, 10, 14], "slot": 10, "slow": [2, 5, 10, 20], "slower": 10, "slowest": 11, "slowli": 14, "slur": 10, "small": [2, 6, 7, 8, 10, 14, 16, 21], "smaller": [10, 13, 14, 18], "smart": 10, "smc": 10, "smil": 10, "smile": 10, "smiley_cat": 10, "smooth": 10, "smoothli": 10, "smut": 7, "snippet": 9, "snore": 10, "so": [0, 1, 2, 5, 6, 8, 9, 10, 11, 13, 14, 16, 17, 19, 20], "social": 10, "softer": 16, "softwar": [1, 5, 7, 9, 14, 16, 19, 21], "software_carpentri": 10, "solidifi": 8, "solo": [0, 10], "solut": [8, 10, 14, 19], "solution": 10, "solv": [1, 3, 10, 19], "some": [0, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, 16, 19, 20], "somebodi": [8, 10], "somehow": 10, "someon": [0, 2, 5, 8, 9, 10, 13, 14, 16, 17, 18, 19, 20], "someth": [1, 2, 4, 5, 6, 8, 9, 10, 14, 16, 17, 19, 20], "sometim": [0, 5, 6, 10, 19], "sometimes": 10, "somewhat": 10, "somewher": 10, "song": 10, "soni": 10, "sonor": 10, "soon": [2, 10, 16], "sooner": [2, 10, 19], "sorri": 10, "sort": 10, "soucr": 10, "sound": [0, 6, 7, 19], "sourc": [0, 5, 8, 9, 10, 11, 19], "space": [10, 14], "spade": 10, "spam": 10, "spanish": 10, "spark": 19, "spars": 10, "spatial": 10, "speak": [0, 10, 20], "speaker": 10, "spec": 10, "special": 10, "specif": [1, 8, 10, 19], "specifi": 16, "spectrum": 10, "speech": 10, "speed": [1, 5, 10], "spend": 10, "spent": 19, "sphinx": [6, 8, 10], "spi": 10, "split": [2, 10, 14, 19, 20], "spontan": 10, "spool": 10, "spot": [9, 20], "spotter": 0, "spread": 1, "sprinkl": 8, "srt": 20, "ssh": 14, "stabil": 10, "stabl": [10, 11], "stack": 10, "staff": [2, 20], "stage": 10, "stai": [8, 10, 19, 21], "standard": [8, 9, 14], "star": 10, "stare": 10, "start": [1, 2, 6, 8, 10, 13, 14, 16, 17, 19, 20], "starter": 10, "stat": 10, "state": 10, "statement": [2, 10], "static": 9, "statist": 10, "statu": [2, 10], "steadili": 10, "step": [1, 2, 8, 10, 12, 18, 20], "stepa": 7, "stephan": 7, "steve": 10, "sth": 10, "stick": 20, "sticki": 10, "still": [2, 6, 8, 10, 13, 14], "stockholm": [1, 10], "stop": [10, 19, 20], "storag": 20, "stori": [10, 19], "straight": [9, 10, 17], "straightforward": [9, 10], "strategi": [8, 10, 13], "stream": [0, 6, 7, 11, 12, 13, 14, 15, 18], "streamer": 10, "streamyard": 17, "streme": 10, "strength": 0, "stress": [0, 10], "strike": 10, "string": 10, "strip": 2, "strong": [0, 9, 10], "strongli": [10, 14], "strted": 10, "structur": [0, 2, 7, 10, 13, 19], "struggl": 10, "stuck": 10, "student": [0, 10, 13], "studi": [10, 19], "studio": [6, 11, 12], "stuff": [10, 14], "style": [0, 1, 6, 10, 19], "sub": 14, "subject": [0, 10], "submit": [1, 9], "subtitl": 10, "subtleti": 0, "succe": 10, "succeed": 10, "success": [0, 5, 10, 13, 14, 19], "successfulli": 10, "suffer": [10, 16], "suffici": [1, 10, 19], "suggest": [5, 8, 10], "suit": [10, 12], "suitabl": 13, "sum": [10, 19], "summ": 8, "summari": [8, 10, 13], "summat": 10, "summer": [10, 13, 20], "sun_with_fac": 10, "sunflow": 10, "supercomput": 9, "superior": 10, "superus": 14, "support": [0, 1, 6, 7, 9, 10, 13, 19], "suppos": 10, "sure": [2, 5, 10, 16, 20], "surpris": [10, 19], "surprisingli": 10, "survei": [10, 13], "swap": 16, "swcarpentri": 10, "sweat_smil": 10, "sweden": 5, "sweet": 10, "switch": [2, 7, 10], "symbol": 10, "symbolifi": 10, "sync": 9, "synergi": 0, "syntax": 2, "synthet": 20, "sysparm_articl": 10, "system": [9, 10, 13], "systemat": 16, "t": [0, 5, 6, 8, 9, 10, 14, 16, 17, 19, 20, 21], "tab": [8, 9, 10, 14], "tabl": [10, 20], "tackl": 10, "tag": 2, "tail": [10, 14], "tailor": [0, 10], "take": [0, 2, 4, 9, 10, 13, 14, 16, 17, 19, 20], "taken": [10, 13], "talbert": 10, "talk": [0, 2, 8, 10, 13, 15, 18, 20, 21], "tandem": 10, "target": [7, 10], "task": [7, 10], "tast": 10, "taught": [0, 8, 10, 19, 21], "tavatar": 14, "taxonomi": 8, "tea": 10, "teach": [1, 2, 3, 6, 7, 9, 11, 12, 13, 15, 16, 17, 18, 20, 21], "teacher": [0, 10, 13, 19], "teachingstreamingv3": 12, "teachingstreamingzoomv3": 12, "teachtogeth": 10, "team": [9, 10, 16, 21], "teamtopologi": 10, "tear": 10, "tech": [8, 10, 14], "technic": [6, 8, 10, 15], "techniqu": [5, 6, 7, 13, 19], "technologi": [2, 8, 10, 19], "teenag": 10, "tell": [0, 10], "templat": [6, 8, 10], "ten": 8, "tend": [5, 10, 19], "tendend": 10, "term": [10, 17], "termin": 10, "terminologi": 10, "termonologi": 10, "test": [7, 8, 10, 12, 14, 16], "text": [2, 5, 9, 10, 13, 14, 20], "than": [2, 5, 8, 9, 10, 14, 16, 19, 20, 21], "thank": 10, "thankfulli": 10, "thats": 10, "thee": 15, "thei": [0, 1, 2, 4, 5, 8, 9, 10, 13, 14, 16, 17, 19, 20, 21], "them": [1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, 16, 17, 19, 21], "themat": 10, "theme": [10, 14], "themselv": [10, 16], "theoret": [1, 10, 18], "theori": [3, 10, 11, 12, 18], "ther": 10, "therefor": [0, 5, 10], "thi": [0, 1, 2, 3, 6, 8, 9, 10, 11, 12, 14, 15, 16, 17, 19, 21], "thing": [0, 5, 6, 7, 8, 12, 13, 14, 15, 16, 17, 19, 20, 21], "think": [2, 5, 6, 7, 8, 9, 16], "thinker": 10, "this_command": 14, "thoroughli": 10, "those": [0, 2, 6, 8, 10], "though": [2, 10, 13, 19], "thought": [8, 10, 13], "thread": 2, "three": [8, 10, 14, 16, 19, 20], "through": [0, 1, 2, 10, 11, 13, 19, 20], "throughout": 10, "throw": 0, "thrown": 19, "thu": [10, 20], "thumbnail": 10, "thumbs_up": 10, "thvmntbjg2y": 20, "tidi": 10, "tighter": 10, "time": [0, 2, 7, 8, 10, 11, 14, 16, 19, 20, 21], "timer": 10, "timestamp": 20, "tini": [9, 10], "tip": [5, 6, 8, 10], "tire": 10, "tired_fac": 10, "titl": [2, 10, 14, 20], "tmp": 14, "tmux": 14, "tmuxp": 14, "todai": [2, 5, 19], "togeth": [0, 8, 9, 10, 21], "token": 12, "toliauta": 7, "tomorrow": 10, "tone": 10, "tongu": 10, "too": [0, 1, 2, 5, 8, 10, 14, 16, 19, 20, 21], "took": 10, "tool": [1, 4, 6, 7, 8, 9, 13, 14, 16, 19, 20, 21], "toolbar": 14, "toolbox": 8, "toolkit": 10, "top": [2, 10, 14], "topic": [1, 6, 7, 8, 10, 19, 20, 21], "total": 10, "touch": [13, 14], "tough": 10, "tour": 17, "toward": [1, 8, 9, 10], "track": [0, 2, 5, 8, 10, 14], "traction": 10, "trade": 14, "tradit": [8, 10, 13, 19, 21], "traffic": 10, "train": [1, 8, 10, 13, 18, 19, 20, 21], "train2": 10, "trainer": 10, "transcript": [10, 20], "transfer": [8, 10], "transform": 10, "transit": [1, 10, 20], "translat": [10, 20], "transmiss": 19, "transpar": 10, "trap": 14, "travel": 21, "tree": 10, "trend": [8, 10], "tri": [0, 1, 5, 10, 16], "trick": [4, 5, 6, 8, 10, 16, 19], "tricki": 10, "trim": 10, "trivial": 10, "troubl": 10, "troughout": 10, "true": 10, "try": [0, 1, 2, 6, 8, 9, 10, 12, 14, 19, 20], "ttt": [9, 10], "tuesdai": [7, 10], "tune": [9, 10], "turn": [10, 13, 16], "tutori": [10, 17, 19], "tweak": 10, "twice": 10, "twist": 19, "twitch": [10, 17, 21], "twitter": 10, "two": [0, 1, 2, 8, 10, 12, 13, 16, 19, 20], "txt": [6, 9, 20], "type": [0, 8, 10, 12, 14, 16, 19], "typic": [1, 10, 14], "typo": [10, 19], "u": [1, 2, 5, 7, 9, 10, 13, 15, 16, 19, 20, 21], "uk": 10, "umbrella": 10, "unabl": 10, "unclear": [2, 19], "uncomfort": [10, 19], "under": [8, 10, 12], "underli": 10, "understand": [0, 1, 5, 8, 9, 10, 11, 13, 16, 19], "understood": 10, "unexpect": 0, "unexpectedli": 17, "unfortun": [10, 14], "uniqu": 10, "univers": [1, 10, 19], "unix": 10, "unknown": 10, "unless": 10, "unlik": 10, "unmanag": 10, "unnecessari": [1, 5], "unpleas": 10, "unprepar": 0, "unprepared": 0, "unproblemat": 10, "unprocess": 20, "unsaf": 10, "unspecifi": 5, "unsur": 10, "until": [1, 2, 5, 10], "unwant": 10, "uo5kbtqdjzbbqb_xldhzuovx5t08fhfgr7dw7tck90i": 10, "up": [0, 1, 2, 5, 6, 8, 9, 10, 11, 13, 15, 19, 20], "upcom": [6, 10], "updat": [2, 5, 6, 10, 12, 13], "upload": 10, "upper": 14, "upstream": 9, "urgent": [13, 16], "url": [2, 10], "us": [0, 1, 2, 3, 4, 6, 7, 10, 11, 12, 14, 15, 16, 18, 19, 21], "usabl": 10, "usag": [1, 8, 10], "usb": 16, "user": [10, 20], "usernam": 2, "usual": [1, 6, 10, 16], "utc": 10, "v": [8, 10, 17, 20], "vagu": 10, "valid": 10, "valu": [10, 14, 19], "valuabl": [2, 5, 10, 14], "variabl": 10, "varieti": [10, 14], "variou": [0, 9, 10], "vastli": 10, "vc": 10, "ve": [10, 19, 21], "vector": 10, "vega": 10, "veri": [0, 1, 2, 4, 6, 9, 10, 14, 16, 18, 19, 20], "versa": 10, "version": [1, 5, 7, 8, 19, 20], "versu": 10, "vertic": 14, "vew": 10, "via": [2, 8, 9, 10, 13], "vice": 10, "video": [6, 7, 11, 12, 15, 21], "vie": 10, "view": [2, 10, 11, 17], "viewpoint": [10, 19], "virtual": [9, 10, 20], "visibl": 10, "vision": 10, "visual": 10, "visualis": 10, "voic": [0, 2, 10, 16], "volum": [2, 10], "volunt": [10, 13], "voluntari": 10, "vote": 10, "w": 10, "wa": [1, 2, 8, 9, 10, 13, 14, 17, 19, 20], "wai": [0, 9, 10, 11, 13, 14, 18, 19, 20], "wait": [2, 14, 19], "wake": 10, "walk": 17, "wall": 2, "want": [0, 1, 6, 8, 9, 10, 13, 14, 15, 18, 19, 20, 21], "war": 19, "ward": 10, "wasn": 10, "wast": 10, "watch": [0, 9, 10, 13, 14, 19, 20], "wayland": [10, 14], "we": [0, 1, 2, 4, 6, 7, 9, 11, 12, 15, 17, 18, 19], "wear": 10, "web": [2, 8, 9, 10, 13, 14], "webcam": 10, "webpag": [2, 20], "websit": [10, 14], "websocket": 17, "webwhiteboard": 10, "wed": 10, "week": [6, 10, 13, 19], "weird": 15, "welcom": [10, 13, 20], "well": [0, 2, 10, 14, 15, 16, 19], "went": 10, "were": [2, 8, 10, 13, 16, 20], "weren": [10, 19], "what": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 13, 14, 15, 16, 19], "whatev": [9, 10, 14], "whatsapp": 10, "when": [0, 1, 2, 5, 8, 10, 17, 19, 20, 21], "whenev": [1, 7, 19], "where": [0, 1, 6, 8, 9, 10, 13, 16, 19, 20], "wherea": 10, "wherev": 16, "whether": [0, 10, 19, 20], "which": [0, 1, 2, 6, 8, 10, 11, 13, 14, 17, 19, 20], "while": [0, 2, 10, 13, 14, 19, 20], "whisper": 10, "whistl": 10, "white": 14, "whiteboard": 10, "who": [0, 1, 2, 5, 6, 10, 16, 18, 20], "whole": [6, 20], "whom": 10, "why": [2, 5, 6, 7, 13, 19], "wide": 10, "wider": 10, "wiki": 10, "william": 10, "win": 10, "window": [2, 10, 11, 14], "window_nam": 14, "winter": 13, "wire": [10, 11, 16, 19], "wireless": 16, "wise": 10, "wiser": 10, "wish": [1, 8, 10, 13], "within": [0, 2, 9, 10, 16, 20], "without": [0, 2, 8, 10, 14, 16, 21], "wittk": 7, "won": [2, 10, 16, 20, 21], "wonder": [10, 14, 19], "woozy_fac": 10, "word": [1, 5, 10, 16, 19, 20], "work": [0, 1, 7, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20], "workaround": [10, 14], "workbench": 10, "workbook": 10, "workflow": [1, 8, 9, 10, 20], "workload": 0, "workplac": 16, "workshop": [0, 6, 8, 14, 16, 17, 19, 20, 21], "world": [10, 19], "worri": [2, 6, 10], "wors": 10, "worsen": 10, "worst": [10, 17], "worth": [10, 20, 21], "worthwhil": [10, 19], "would": [1, 2, 5, 6, 7, 8, 9, 13, 19, 20, 21], "wouldn": 2, "wow": 10, "write": [0, 1, 2, 5, 7, 8, 9, 10], "writer": [8, 10], "written": 10, "wrong": [8, 10, 16], "www": [10, 19, 20], "x": [1, 8, 10, 19], "x11": 14, "xorg": 14, "xx": [2, 10], "xxx": [2, 10], "yawning_fac": 10, "ye": [0, 5, 10, 21], "yeah": 10, "year": [5, 10, 13], "yellow": 14, "yep": 10, "yet": [1, 8, 10, 11, 12, 14, 17, 20], "you": [0, 1, 2, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21], "your": [0, 1, 2, 6, 7, 10, 12, 13, 16, 17, 19], "yournam": 2, "yourself": [2, 6, 8, 9, 10, 13], "yourselv": 16, "youtub": [10, 17, 19, 20, 21], "zenodo": [5, 10], "zip": 12, "zm_kb": 10, "zola": 10, "zone": 10, "zoom": [6, 7, 10, 13, 14, 17, 21], "zsh": [10, 14], "zsh_histori": 10, "zulip": [1, 10], "zulipchat": 10}, "titles": ["Co-teaching", "About the CodeRefinery project and CodeRefinery workshops in general", "Collaborative notes", "Computational thinking", "Sharing teaching gems", "How we collect feedback and measure impact", "Instructor guide", "Train the trainer workshop", "Lesson design and development", "Lessons with version control", "Collaborative notes archives from workshops", "Open Broadcaster Software (OBS) introduction", "Open Broadcaster Software (OBS) setup", "A workshop seen from different perspectives", "How to prepare a quality screen-share", "Session 4 intro", "Sound", "Behind the stream", "What\u2019s next?", "CodeRefinery teaching philosophies", "Video editing", "Why we stream"], "titleterms": {"": 18, "08": 10, "09": 10, "1": [5, 7, 9, 10, 16, 20], "10": [0, 5], "13": 10, "15": 2, "2": [5, 7, 9, 10, 16, 20], "20": [8, 10, 14, 19], "2024": [7, 10], "24": 10, "27": 10, "3": [5, 7, 9, 10, 16, 20], "4": [5, 7, 9, 10, 15, 20], "5": [8, 9, 10, 20], "6": 20, "7": 20, "A": [11, 12, 13, 17, 20, 21], "One": [10, 13], "The": [8, 12, 16], "about": [1, 8, 10], "accept": 9, "add": 20, "adjust": 16, "adopt": 10, "advanc": 9, "after": 13, "all": [8, 10], "also": [11, 18, 20], "altern": 17, "ani": 0, "approach": 8, "ar": [0, 8, 16, 17], "archiv": 10, "articl": 20, "ask": [2, 5], "audienc": [1, 6, 10], "audio": 16, "august": [7, 10], "b": 20, "backward": 8, "balanc": 16, "basic": [2, 20], "bast": 19, "befor": [2, 5, 12, 13], "behind": [10, 17], "benefit": [0, 21], "best": 10, "better": 8, "between": 14, "bj\u00f8rn": 19, "breaker": 19, "breakout": 10, "breakoutroom": 10, "briefli": 21, "broadcast": [10, 11, 12], "browser": 14, "build": 9, "calendar": 10, "can": 17, "captur": 14, "carpentri": [1, 9], "case": 8, "challeng": 1, "check": [10, 16], "classroom": 10, "clone": 9, "co": [0, 10], "coderefineri": [1, 7, 8, 9, 10, 12, 17, 19], "collabor": [2, 5, 10], "collect": [5, 8, 10], "color": 14, "command": 14, "commun": [1, 13], "compet": 1, "comput": [3, 10], "config": 12, "configur": 14, "contribut": 9, "control": [2, 9, 10, 12, 17], "cool": 10, "cours": [11, 12], "creat": [8, 9, 20], "dai": 10, "darst": 19, "day1": 10, "day4": 10, "defin": 1, "demo": 0, "deploy": 10, "design": [5, 8, 10], "desktop": 14, "develop": [8, 10], "did": 13, "differ": 13, "disadvantag": 21, "discuss": [0, 2, 5, 8, 9, 10, 13, 20], "distribut": 20, "do": [8, 16, 20], "document": [2, 8], "doe": 17, "don": 2, "down": 16, "downsid": 0, "dure": [11, 13], "dynam": 16, "each": [6, 12], "easi": 20, "edit": [2, 10, 20], "editlist": 20, "entir": 14, "environ": 14, "episod": 10, "evalu": [14, 16], "everyon": 2, "exampl": [2, 5, 9], "exercis": [0, 2, 5, 8, 9, 10, 14, 16, 20], "exist": 8, "experi": 10, "featur": 20, "feedback": [2, 5, 10], "ffmpeg": 20, "file": 20, "final": 20, "font": 14, "format": [2, 9], "from": [10, 13], "futur": 21, "gem": [4, 10], "gener": [1, 2, 10, 20], "get": [2, 13, 17, 20], "github": [8, 9], "giver": 0, "go": [9, 12, 17], "goal": 1, "good": 16, "great": 8, "group": [5, 8, 19], "guid": [0, 6], "habit": 14, "handl": 2, "hardwar": 11, "histori": [1, 14, 21], "host": 13, "how": [2, 5, 8, 10, 13, 14, 17, 20], "i": [11, 21], "ic": 19, "icebreak": [10, 21], "icecream": 10, "impact": [5, 10], "import": 16, "improv": [8, 10], "individu": 13, "initi": 12, "instal": 12, "instead": 14, "instructor": [0, 2, 3, 4, 5, 6, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21], "interfac": 11, "interview": 0, "intro": [6, 15], "introduct": [2, 10, 11, 19], "invest": 13, "involv": 13, "iter": 10, "journei": 13, "keypoint": [0, 1, 2, 3, 9, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21], "layout": [14, 17], "lead": 13, "learn": [5, 8, 14], "learner": [13, 14], "lesson": [5, 8, 9, 10], "like": [10, 13], "lindi": 19, "local": [9, 13], "longer": 5, "lot": 13, "make": 20, "manag": 2, "mani": [10, 13], "materi": 8, "measur": [5, 10], "mechan": 2, "min": [0, 2, 5, 8, 14], "minut": 19, "model": 0, "modifi": 9, "more": 20, "most": 2, "need": 14, "new": 8, "next": 18, "note": [0, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21], "novic": 1, "ob": [10, 11, 12], "object": [0, 1, 2, 3, 4, 5, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21], "onlin": 14, "open": [10, 11, 12], "option": 9, "other": [13, 14], "our": [1, 8], "output": 20, "overview": 0, "overwhelm": 2, "own": [9, 14], "panel": 17, "part": 13, "particip": 6, "peopl": 13, "perspect": [10, 13, 14], "philosophi": [10, 19], "point": 6, "poll": 10, "portrait": 14, "post": 2, "practic": [2, 10], "practition": 1, "prepar": [6, 10, 14], "present": [0, 9], "primari": 20, "privaci": 2, "problem": [8, 16], "process": [8, 9], "project": 1, "prompt": 14, "prospect": 21, "q": [11, 12, 17, 21], "qualiti": [10, 14, 16], "question": [2, 5, 10, 21], "radovan": 19, "raw": 20, "razick": 19, "recommend": 16, "record": [19, 21], "relat": [1, 20], "remot": 12, "requir": 11, "resourc": [7, 8, 14], "result": 8, "richard": 19, "role": 13, "room": 10, "run": 20, "sabri": 19, "sampl": 20, "scene": 17, "schedul": 10, "scheme": 14, "screen": [10, 14], "see": [11, 18, 20], "seen": 13, "septemb": [7, 10], "sessiion": 10, "session": [6, 7, 10, 15], "set": [12, 14, 17], "setup": [10, 12, 13, 14], "share": [4, 8, 10, 14], "size": 14, "smallest": 9, "softwar": [10, 11, 12], "solut": 20, "sound": [10, 13, 16], "speak": 16, "specif": 0, "sphinx": 9, "step": 13, "stepa": 19, "stone": 13, "stream": [10, 17, 20, 21], "subtitl": 20, "summari": [0, 9, 16, 19, 20], "survei": 5, "switch": 14, "t": 2, "take": 5, "talk": 6, "target": [1, 6], "teach": [0, 4, 5, 8, 10, 14, 19], "team": [0, 13], "techniqu": 10, "templat": [2, 9], "term": 5, "termin": 14, "test": 20, "thi": [13, 20], "thing": [2, 10], "think": [3, 10], "through": [9, 12], "time": [5, 6, 13], "tip": 16, "todai": 10, "toliauta": 19, "tool": 10, "tour": 9, "train": 7, "trainer": 7, "try": 5, "typic": 8, "un": 14, "up": [12, 14, 16, 17], "us": [5, 8, 9, 20], "user": 11, "vc": 9, "version": [9, 10], "video": [10, 19, 20], "view": 19, "volum": 16, "we": [5, 8, 10, 13, 14, 20, 21], "websit": 2, "what": [11, 17, 18, 20, 21], "when": [14, 16], "whisper": 20, "who": 17, "why": [9, 10, 21], "window": 17, "work": [8, 14], "workshop": [1, 2, 5, 7, 10, 13], "would": 10, "wrapup": 10, "wrong": 17, "yaml": 20, "you": 8, "your": [5, 8, 9, 14, 20]}}) \ No newline at end of file diff --git a/session-4-intro/index.html b/session-4-intro/index.html new file mode 100644 index 0000000..ac8cde9 --- /dev/null +++ b/session-4-intro/index.html @@ -0,0 +1,190 @@ + + + + + + + Session 4 intro — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Session 4 intro

+

This session covers streaming and technical production. Some +introductory notes:

+
    +
  • (As of 2024) This is the first and only comprehensive introduction +to our online streaming.

  • +
  • These practices are new and well-refined internally, but a +different kind of refinement is needed to teach and reuse them.

  • +
  • The lessons have outlines of what to talk about, but it’s just an +outline. It is not refined, since thees things are new. Many +things will have to be figured out as we talk.

  • +
  • This session is a demo of lots of basics.

    +
      +
    • Ask questions - otherwise it will be boring

    • +
    • If you want to use this in real life: you will need mentoring +sessions and active help. Contact us to do that.

    • +
    +
  • +
+
+

Warning

+

Audio and video weirdness

+

We are setting up video and audio recording, but also capturing that +for re-sharing it. There may be anomalies as video or audio +feedback. Please be prepared.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/singlehtml/_images/BYOC.png b/singlehtml/_images/BYOC.png new file mode 100644 index 0000000..94702a1 Binary files /dev/null and b/singlehtml/_images/BYOC.png differ diff --git a/singlehtml/_images/CR_workshop_setup.png b/singlehtml/_images/CR_workshop_setup.png new file mode 100644 index 0000000..47b4502 Binary files /dev/null and b/singlehtml/_images/CR_workshop_setup.png differ diff --git a/singlehtml/_images/community.png b/singlehtml/_images/community.png new file mode 100644 index 0000000..ddd9a62 Binary files /dev/null and b/singlehtml/_images/community.png differ diff --git a/singlehtml/_images/hackmd--controls.png b/singlehtml/_images/hackmd--controls.png new file mode 100644 index 0000000..46a74c7 Binary files /dev/null and b/singlehtml/_images/hackmd--controls.png differ diff --git a/singlehtml/_images/hackmd--full-demo.png b/singlehtml/_images/hackmd--full-demo.png new file mode 100644 index 0000000..0988b6f Binary files /dev/null and b/singlehtml/_images/hackmd--full-demo.png differ diff --git a/singlehtml/_images/hackmd--questions2.png b/singlehtml/_images/hackmd--questions2.png new file mode 100644 index 0000000..a609199 Binary files /dev/null and b/singlehtml/_images/hackmd--questions2.png differ diff --git a/singlehtml/_images/history-landscape-dark.png b/singlehtml/_images/history-landscape-dark.png new file mode 100644 index 0000000..a1aef3c Binary files /dev/null and b/singlehtml/_images/history-landscape-dark.png differ diff --git a/singlehtml/_images/history-portrait-dark.png b/singlehtml/_images/history-portrait-dark.png new file mode 100644 index 0000000..2fc1fa6 Binary files /dev/null and b/singlehtml/_images/history-portrait-dark.png differ diff --git a/singlehtml/_images/history-portrait-light.png b/singlehtml/_images/history-portrait-light.png new file mode 100644 index 0000000..5f4361c Binary files /dev/null and b/singlehtml/_images/history-portrait-light.png differ diff --git a/singlehtml/_images/history-portrait.png b/singlehtml/_images/history-portrait.png new file mode 100644 index 0000000..28e18b0 Binary files /dev/null and b/singlehtml/_images/history-portrait.png differ diff --git a/singlehtml/_images/history-rsh.png b/singlehtml/_images/history-rsh.png new file mode 100644 index 0000000..1bbb1cc Binary files /dev/null and b/singlehtml/_images/history-rsh.png differ diff --git a/singlehtml/_images/instructor.png b/singlehtml/_images/instructor.png new file mode 100644 index 0000000..718f2a8 Binary files /dev/null and b/singlehtml/_images/instructor.png differ diff --git a/singlehtml/_images/landscape.png b/singlehtml/_images/landscape.png new file mode 100644 index 0000000..eda9d42 Binary files /dev/null and b/singlehtml/_images/landscape.png differ diff --git a/singlehtml/_images/learner-large.png b/singlehtml/_images/learner-large.png new file mode 100644 index 0000000..3b6d2cd Binary files /dev/null and b/singlehtml/_images/learner-large.png differ diff --git a/singlehtml/_images/learner-normal.png b/singlehtml/_images/learner-normal.png new file mode 100644 index 0000000..590135e Binary files /dev/null and b/singlehtml/_images/learner-normal.png differ diff --git a/singlehtml/_images/learner-small.png b/singlehtml/_images/learner-small.png new file mode 100644 index 0000000..5d5f421 Binary files /dev/null and b/singlehtml/_images/learner-small.png differ diff --git a/singlehtml/_images/portrait.png b/singlehtml/_images/portrait.png new file mode 100644 index 0000000..415799f Binary files /dev/null and b/singlehtml/_images/portrait.png differ diff --git a/singlehtml/_images/steps.png b/singlehtml/_images/steps.png new file mode 100644 index 0000000..6c978b5 Binary files /dev/null and b/singlehtml/_images/steps.png differ diff --git a/singlehtml/_images/survey-impact1.png b/singlehtml/_images/survey-impact1.png new file mode 100644 index 0000000..7dd0ddc Binary files /dev/null and b/singlehtml/_images/survey-impact1.png differ diff --git a/singlehtml/_images/survey-impact2.png b/singlehtml/_images/survey-impact2.png new file mode 100644 index 0000000..8771bff Binary files /dev/null and b/singlehtml/_images/survey-impact2.png differ diff --git a/singlehtml/_images/welcome.png b/singlehtml/_images/welcome.png new file mode 100644 index 0000000..302082c Binary files /dev/null and b/singlehtml/_images/welcome.png differ diff --git a/singlehtml/_sphinx_design_static/design-tabs.js b/singlehtml/_sphinx_design_static/design-tabs.js new file mode 100644 index 0000000..b25bd6a --- /dev/null +++ b/singlehtml/_sphinx_design_static/design-tabs.js @@ -0,0 +1,101 @@ +// @ts-check + +// Extra JS capability for selected tabs to be synced +// The selection is stored in local storage so that it persists across page loads. + +/** + * @type {Record} + */ +let sd_id_to_elements = {}; +const storageKeyPrefix = "sphinx-design-tab-id-"; + +/** + * Create a key for a tab element. + * @param {HTMLElement} el - The tab element. + * @returns {[string, string, string] | null} - The key. + * + */ +function create_key(el) { + let syncId = el.getAttribute("data-sync-id"); + let syncGroup = el.getAttribute("data-sync-group"); + if (!syncId || !syncGroup) return null; + return [syncGroup, syncId, syncGroup + "--" + syncId]; +} + +/** + * Initialize the tab selection. + * + */ +function ready() { + // Find all tabs with sync data + + /** @type {string[]} */ + let groups = []; + + document.querySelectorAll(".sd-tab-label").forEach((label) => { + if (label instanceof HTMLElement) { + let data = create_key(label); + if (data) { + let [group, id, key] = data; + + // add click event listener + // @ts-ignore + label.onclick = onSDLabelClick; + + // store map of key to elements + if (!sd_id_to_elements[key]) { + sd_id_to_elements[key] = []; + } + sd_id_to_elements[key].push(label); + + if (groups.indexOf(group) === -1) { + groups.push(group); + // Check if a specific tab has been selected via URL parameter + const tabParam = new URLSearchParams(window.location.search).get( + group + ); + if (tabParam) { + console.log( + "sphinx-design: Selecting tab id for group '" + + group + + "' from URL parameter: " + + tabParam + ); + window.sessionStorage.setItem(storageKeyPrefix + group, tabParam); + } + } + + // Check is a specific tab has been selected previously + let previousId = window.sessionStorage.getItem( + storageKeyPrefix + group + ); + if (previousId === id) { + // console.log( + // "sphinx-design: Selecting tab from session storage: " + id + // ); + // @ts-ignore + label.previousElementSibling.checked = true; + } + } + } + }); +} + +/** + * Activate other tabs with the same sync id. + * + * @this {HTMLElement} - The element that was clicked. + */ +function onSDLabelClick() { + let data = create_key(this); + if (!data) return; + let [group, id, key] = data; + for (const label of sd_id_to_elements[key]) { + if (label === this) continue; + // @ts-ignore + label.previousElementSibling.checked = true; + } + window.sessionStorage.setItem(storageKeyPrefix + group, id); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/singlehtml/_sphinx_design_static/sphinx-design.min.css b/singlehtml/_sphinx_design_static/sphinx-design.min.css new file mode 100644 index 0000000..860c36d --- /dev/null +++ b/singlehtml/_sphinx_design_static/sphinx-design.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative;font-size:var(--sd-fontsize-dropdown)}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary.sd-summary-title{padding:.5em .6em .5em 1em;font-size:var(--sd-fontsize-dropdown-title);font-weight:var(--sd-fontweight-dropdown-title);user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;list-style:none;display:inline-flex;justify-content:space-between}details.sd-dropdown summary.sd-summary-title::-webkit-details-marker{display:none}details.sd-dropdown summary.sd-summary-title:focus{outline:none}details.sd-dropdown summary.sd-summary-title .sd-summary-icon{margin-right:.6em;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary.sd-summary-title .sd-summary-text{flex-grow:1;line-height:1.5;padding-right:.5rem}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker{pointer-events:none;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker svg{opacity:.6}details.sd-dropdown summary.sd-summary-title:hover .sd-summary-state-marker svg{opacity:1;transform:scale(1.1)}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown .sd-summary-chevron-right{transition:.25s}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-right{transform:rotate(90deg)}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-down{transform:rotate(180deg)}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-bg: rgba(0, 113, 188, 0.2);--sd-color-secondary-bg: rgba(108, 117, 125, 0.2);--sd-color-success-bg: rgba(40, 167, 69, 0.2);--sd-color-info-bg: rgba(23, 162, 184, 0.2);--sd-color-warning-bg: rgba(240, 179, 126, 0.2);--sd-color-danger-bg: rgba(220, 53, 69, 0.2);--sd-color-light-bg: rgba(248, 249, 250, 0.2);--sd-color-muted-bg: rgba(108, 117, 125, 0.2);--sd-color-dark-bg: rgba(33, 37, 41, 0.2);--sd-color-black-bg: rgba(0, 0, 0, 0.2);--sd-color-white-bg: rgba(255, 255, 255, 0.2);--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem;--sd-fontsize-dropdown: inherit;--sd-fontsize-dropdown-title: 1rem;--sd-fontweight-dropdown-title: 700} diff --git a/singlehtml/_static/_sphinx_javascript_frameworks_compat.js b/singlehtml/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 0000000..8141580 --- /dev/null +++ b/singlehtml/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/singlehtml/_static/basic.css b/singlehtml/_static/basic.css new file mode 100644 index 0000000..f316efc --- /dev/null +++ b/singlehtml/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/singlehtml/_static/check-solid.svg b/singlehtml/_static/check-solid.svg new file mode 100644 index 0000000..92fad4b --- /dev/null +++ b/singlehtml/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/singlehtml/_static/clipboard.min.js b/singlehtml/_static/clipboard.min.js new file mode 100644 index 0000000..54b3c46 --- /dev/null +++ b/singlehtml/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/singlehtml/_static/copybutton.css b/singlehtml/_static/copybutton.css new file mode 100644 index 0000000..f1916ec --- /dev/null +++ b/singlehtml/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/singlehtml/_static/copybutton.js b/singlehtml/_static/copybutton.js new file mode 100644 index 0000000..2ea7ff3 --- /dev/null +++ b/singlehtml/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/singlehtml/_static/copybutton_funcs.js b/singlehtml/_static/copybutton_funcs.js new file mode 100644 index 0000000..dbe1aaa --- /dev/null +++ b/singlehtml/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/singlehtml/_static/css/badge_only.css b/singlehtml/_static/css/badge_only.css new file mode 100644 index 0000000..c718cee --- /dev/null +++ b/singlehtml/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff b/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff2 b/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/singlehtml/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff b/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff2 b/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/singlehtml/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/singlehtml/_static/css/fonts/fontawesome-webfont.eot b/singlehtml/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/singlehtml/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/singlehtml/_static/css/fonts/fontawesome-webfont.svg b/singlehtml/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/singlehtml/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/singlehtml/_static/css/fonts/fontawesome-webfont.ttf b/singlehtml/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/singlehtml/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/singlehtml/_static/css/fonts/fontawesome-webfont.woff b/singlehtml/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/singlehtml/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/singlehtml/_static/css/fonts/fontawesome-webfont.woff2 b/singlehtml/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/singlehtml/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/singlehtml/_static/css/fonts/lato-bold-italic.woff b/singlehtml/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/singlehtml/_static/css/fonts/lato-bold-italic.woff differ diff --git a/singlehtml/_static/css/fonts/lato-bold-italic.woff2 b/singlehtml/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/singlehtml/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/singlehtml/_static/css/fonts/lato-bold.woff b/singlehtml/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/singlehtml/_static/css/fonts/lato-bold.woff differ diff --git a/singlehtml/_static/css/fonts/lato-bold.woff2 b/singlehtml/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/singlehtml/_static/css/fonts/lato-bold.woff2 differ diff --git a/singlehtml/_static/css/fonts/lato-normal-italic.woff b/singlehtml/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/singlehtml/_static/css/fonts/lato-normal-italic.woff differ diff --git a/singlehtml/_static/css/fonts/lato-normal-italic.woff2 b/singlehtml/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/singlehtml/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/singlehtml/_static/css/fonts/lato-normal.woff b/singlehtml/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/singlehtml/_static/css/fonts/lato-normal.woff differ diff --git a/singlehtml/_static/css/fonts/lato-normal.woff2 b/singlehtml/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/singlehtml/_static/css/fonts/lato-normal.woff2 differ diff --git a/singlehtml/_static/css/theme.css b/singlehtml/_static/css/theme.css new file mode 100644 index 0000000..19a446a --- /dev/null +++ b/singlehtml/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/singlehtml/_static/design-tabs.js b/singlehtml/_static/design-tabs.js new file mode 100644 index 0000000..b25bd6a --- /dev/null +++ b/singlehtml/_static/design-tabs.js @@ -0,0 +1,101 @@ +// @ts-check + +// Extra JS capability for selected tabs to be synced +// The selection is stored in local storage so that it persists across page loads. + +/** + * @type {Record} + */ +let sd_id_to_elements = {}; +const storageKeyPrefix = "sphinx-design-tab-id-"; + +/** + * Create a key for a tab element. + * @param {HTMLElement} el - The tab element. + * @returns {[string, string, string] | null} - The key. + * + */ +function create_key(el) { + let syncId = el.getAttribute("data-sync-id"); + let syncGroup = el.getAttribute("data-sync-group"); + if (!syncId || !syncGroup) return null; + return [syncGroup, syncId, syncGroup + "--" + syncId]; +} + +/** + * Initialize the tab selection. + * + */ +function ready() { + // Find all tabs with sync data + + /** @type {string[]} */ + let groups = []; + + document.querySelectorAll(".sd-tab-label").forEach((label) => { + if (label instanceof HTMLElement) { + let data = create_key(label); + if (data) { + let [group, id, key] = data; + + // add click event listener + // @ts-ignore + label.onclick = onSDLabelClick; + + // store map of key to elements + if (!sd_id_to_elements[key]) { + sd_id_to_elements[key] = []; + } + sd_id_to_elements[key].push(label); + + if (groups.indexOf(group) === -1) { + groups.push(group); + // Check if a specific tab has been selected via URL parameter + const tabParam = new URLSearchParams(window.location.search).get( + group + ); + if (tabParam) { + console.log( + "sphinx-design: Selecting tab id for group '" + + group + + "' from URL parameter: " + + tabParam + ); + window.sessionStorage.setItem(storageKeyPrefix + group, tabParam); + } + } + + // Check is a specific tab has been selected previously + let previousId = window.sessionStorage.getItem( + storageKeyPrefix + group + ); + if (previousId === id) { + // console.log( + // "sphinx-design: Selecting tab from session storage: " + id + // ); + // @ts-ignore + label.previousElementSibling.checked = true; + } + } + } + }); +} + +/** + * Activate other tabs with the same sync id. + * + * @this {HTMLElement} - The element that was clicked. + */ +function onSDLabelClick() { + let data = create_key(this); + if (!data) return; + let [group, id, key] = data; + for (const label of sd_id_to_elements[key]) { + if (label === this) continue; + // @ts-ignore + label.previousElementSibling.checked = true; + } + window.sessionStorage.setItem(storageKeyPrefix + group, id); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/singlehtml/_static/doctools.js b/singlehtml/_static/doctools.js new file mode 100644 index 0000000..4d67807 --- /dev/null +++ b/singlehtml/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/singlehtml/_static/documentation_options.js b/singlehtml/_static/documentation_options.js new file mode 100644 index 0000000..89003c6 --- /dev/null +++ b/singlehtml/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'singlehtml', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/singlehtml/_static/file.png b/singlehtml/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/singlehtml/_static/file.png differ diff --git a/singlehtml/_static/jquery.js b/singlehtml/_static/jquery.js new file mode 100644 index 0000000..c4c6022 --- /dev/null +++ b/singlehtml/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!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(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=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,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).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 w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\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(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.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,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){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 H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.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--)b.attrHandle[n[r]]=t}function pe(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 de(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 d=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")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.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}},b.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[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.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},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),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(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.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},j=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)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(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==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(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?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{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 G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.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("(^|"+M+")"+e+"("+M+"|$)"))&&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:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.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 S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(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").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.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),m(t)&&(t=t.call(e,n,S.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)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.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"===S.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"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.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)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.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?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.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)}}),S.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){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/singlehtml/_static/js/html5shiv.min.js b/singlehtml/_static/js/html5shiv.min.js new file mode 100644 index 0000000..cd1c674 --- /dev/null +++ b/singlehtml/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/singlehtml/_static/js/theme.js b/singlehtml/_static/js/theme.js new file mode 100644 index 0000000..1fddb6e --- /dev/null +++ b/singlehtml/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/singlehtml/_static/minipres.js b/singlehtml/_static/minipres.js new file mode 100644 index 0000000..ad11c87 --- /dev/null +++ b/singlehtml/_static/minipres.js @@ -0,0 +1,223 @@ +// Add goTo method to elements +// http://stackoverflow.com/questions/4801655/how-to-go-to-a-specific-element-on-page +(function($) { + $.fn.goTo = function() { + $('html, body').animate({ + scrollTop: $(this).offset().top //+ 'px' + }, 'fast'); + return this; // for chaining... + } +})(jQuery); + +// NO good way to do this!. Copy a hack from here +// https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript +// https://stackoverflow.com/a/2880929 +var urlParams; +(window.onpopstate = function () { + var match, + pl = /\+/g, // Regex for replacing addition symbol with a space + search = /([^&=]+)=?([^&]*)/g, + decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, + query = window.location.search.substring(1); + urlParams = {}; + while (match = search.exec(query)) + urlParams[decode(match[1])] = decode(match[2]); +})(); + +// Select heading levels +var maxHeading = urlParams['h'] +if (maxHeading === undefined) maxHeading = 2 +var headingLevels = []; +for (h=2 ; h (sections.length-1) ) { + // if we would scroll past bottom, or above top, do nothing + return; + } + + console.log('xxxxxx'); + var targetSection = sections[targetPos]; + console.log(targetSection, typeof(targetSection)); + + // Return targetSection top and height + var secProperties = section_top_and_height(targetSection); + var top = secProperties['top']; + var height = secProperties['height'] + var win_height = window.innerHeight; + //console.info(top, height, win_height) + + var scroll_to = 0; + if (height >= win_height || height == 0) { + scroll_to = top; + } else { + scroll_to = top - (win_height-height)/3.; + } + //console.info(top, height, win_height, scroll_to) + + $('html, body').animate({ + scrollTop: scroll_to //+ 'px' + }, 'fast'); + +} + + +function minipres() { + /* Enable the minipres mode: + - call the hide() function + - set up the scrolling listener + */ + document.addEventListener('keydown', function (event) { + switch(event.which) { + case 37: // left + switch_slide(-1); + event.preventDefault(); + return false; + break; + //case 38: // up + case 39: // right + switch_slide(+1); + event.preventDefault(); + return false; + break; + //case 40: // down + default: + return; // exit this handler for other keys + } + }, true) + + hide() + + // Increase space between sections + //$("div .section").css('margin-bottom', '50%'); + $(sectionSelector).css('margin-top', '50%'); + + // Reduce size/color of other sections + if (hiddenSectionSelector.length > 0) { + var hideNodes = $(hiddenSectionSelector); + console.log(typeof hideNodes, hideNodes); + for (node in hideNodes) { + console.log("a", typeof node, node); + node = hideNodes[node]; // what's right way to iterate values? + console.log("b", typeof node, node); + if (node.parentNode && node.parentNode.className == "section") { + node = node.parentNode; + console.log("c", typeof node, node); + //node.css['transform'] = 'scale(.5)'; + //node.css['transform-origin'] = 'top center'; + $(node).css('color', 'lightgrey'); + //$(node).css('font-size', '20%'); + //$(node).css('visibility', 'collapse'); + //ntahousnatouhasno; + } + } + } +} + +function hide() { + /* Hide all non-essential elements on the page + */ + + // This is for sphinx_rst_theme and readthedocs + $(".wy-nav-side").remove(); + $(".wy-nav-content-wrap").css('margin-left', 0); + $('.rst-versions').remove(); // readthedocs version selector + + // Add other formats here. +} + + +var slideshow = minipres; + +if (window.location.search.match(/[?&](minipres|slideshow|pres)([=&]|$)/) ) { + //minipres() + window.addEventListener("load", minipres); +} else if (window.location.search.match(/[?&](plain)([=&]|$)/) ) { + window.addEventListener("load", hide); +} diff --git a/singlehtml/_static/minus.png b/singlehtml/_static/minus.png new file mode 100644 index 0000000..d96755f Binary files /dev/null and b/singlehtml/_static/minus.png differ diff --git a/singlehtml/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css b/singlehtml/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css new file mode 100644 index 0000000..3356631 --- /dev/null +++ b/singlehtml/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css @@ -0,0 +1,2342 @@ +/* Variables */ +:root { + --mystnb-source-bg-color: #f7f7f7; + --mystnb-stdout-bg-color: #fcfcfc; + --mystnb-stderr-bg-color: #fdd; + --mystnb-traceback-bg-color: #fcfcfc; + --mystnb-source-border-color: #ccc; + --mystnb-source-margin-color: green; + --mystnb-stdout-border-color: #f7f7f7; + --mystnb-stderr-border-color: #f7f7f7; + --mystnb-traceback-border-color: #ffd6d6; + --mystnb-hide-prompt-opacity: 70%; + --mystnb-source-border-radius: .4em; + --mystnb-source-border-width: 1px; +} + +/* Whole cell */ +div.container.cell { + padding-left: 0; + margin-bottom: 1em; +} + +/* Removing all background formatting so we can control at the div level */ +.cell_input div.highlight, +.cell_output pre, +.cell_input pre, +.cell_output .output { + border: none; + box-shadow: none; +} + +.cell_output .output pre, +.cell_input pre { + margin: 0px; +} + +/* Input cells */ +div.cell div.cell_input, +div.cell details.above-input>summary { + padding-left: 0em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + background-color: var(--mystnb-source-bg-color); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; + border-radius: var(--mystnb-source-border-radius); +} + +div.cell_input>div, +div.cell_output div.output>div.highlight { + margin: 0em !important; + border: none !important; +} + +/* All cell outputs */ +.cell_output { + padding-left: 1em; + padding-right: 0em; + margin-top: 1em; +} + +/* Text outputs from cells */ +.cell_output .output.text_plain, +.cell_output .output.traceback, +.cell_output .output.stream, +.cell_output .output.stderr { + margin-top: 1em; + margin-bottom: 0em; + box-shadow: none; +} + +.cell_output .output.text_plain, +.cell_output .output.stream { + background: var(--mystnb-stdout-bg-color); + border: 1px solid var(--mystnb-stdout-border-color); +} + +.cell_output .output.stderr { + background: var(--mystnb-stderr-bg-color); + border: 1px solid var(--mystnb-stderr-border-color); +} + +.cell_output .output.traceback { + background: var(--mystnb-traceback-bg-color); + border: 1px solid var(--mystnb-traceback-border-color); +} + +/* Collapsible cell content */ +div.cell details.above-input div.cell_input { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-top: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; +} + +div.cell div.cell_input.above-output-prompt { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +div.cell details.above-input>summary { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; + padding-left: 1em; + margin-bottom: 0; +} + +div.cell details.above-output>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.below-input>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-top: none; + border-bottom-left-radius: var(--mystnb-source-border-radius); + border-bottom-right-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.hide>summary>span { + opacity: var(--mystnb-hide-prompt-opacity); +} + +div.cell details.hide[open]>summary>span.collapsed { + display: none; +} + +div.cell details.hide:not([open])>summary>span.expanded { + display: none; +} + +@keyframes collapsed-fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} +div.cell details.hide[open]>summary~* { + -moz-animation: collapsed-fade-in 0.3s ease-in-out; + -webkit-animation: collapsed-fade-in 0.3s ease-in-out; + animation: collapsed-fade-in 0.3s ease-in-out; +} + +/* Math align to the left */ +.cell_output .MathJax_Display { + text-align: left !important; +} + +/* Pandas tables. Pulled from the Jupyter / nbsphinx CSS */ +div.cell_output table { + border: none; + border-collapse: collapse; + border-spacing: 0; + color: black; + font-size: 1em; + table-layout: fixed; +} + +div.cell_output thead { + border-bottom: 1px solid black; + vertical-align: bottom; +} + +div.cell_output tr, +div.cell_output th, +div.cell_output td { + text-align: right; + vertical-align: middle; + padding: 0.5em 0.5em; + line-height: normal; + white-space: normal; + max-width: none; + border: none; +} + +div.cell_output th { + font-weight: bold; +} + +div.cell_output tbody tr:nth-child(odd) { + background: #f5f5f5; +} + +div.cell_output tbody tr:hover { + background: rgba(66, 165, 245, 0.2); +} + +/** source code line numbers **/ +span.linenos { + opacity: 0.5; +} + +/* Inline text from `paste` operation */ + +span.pasted-text { + font-weight: bold; +} + +span.pasted-inline img { + max-height: 2em; +} + +tbody span.pasted-inline img { + max-height: none; +} + +/* Font colors for translated ANSI escape sequences +Color values are copied from Jupyter Notebook +https://github.com/jupyter/notebook/blob/52581f8eda9b319eb0390ac77fe5903c38f81e3e/notebook/static/notebook/less/ansicolors.less#L14-L21 +Background colors from +https://nbsphinx.readthedocs.io/en/latest/code-cells.html#ANSI-Colors +*/ +div.highlight .-Color-Bold { + font-weight: bold; +} + +div.highlight .-Color[class*=-Black] { + color: #3E424D +} + +div.highlight .-Color[class*=-Red] { + color: #E75C58 +} + +div.highlight .-Color[class*=-Green] { + color: #00A250 +} + +div.highlight .-Color[class*=-Yellow] { + color: #DDB62B +} + +div.highlight .-Color[class*=-Blue] { + color: #208FFB +} + +div.highlight .-Color[class*=-Magenta] { + color: #D160C4 +} + +div.highlight .-Color[class*=-Cyan] { + color: #60C6C8 +} + +div.highlight .-Color[class*=-White] { + color: #C5C1B4 +} + +div.highlight .-Color[class*=-BGBlack] { + background-color: #3E424D +} + +div.highlight .-Color[class*=-BGRed] { + background-color: #E75C58 +} + +div.highlight .-Color[class*=-BGGreen] { + background-color: #00A250 +} + +div.highlight .-Color[class*=-BGYellow] { + background-color: #DDB62B +} + +div.highlight .-Color[class*=-BGBlue] { + background-color: #208FFB +} + +div.highlight .-Color[class*=-BGMagenta] { + background-color: #D160C4 +} + +div.highlight .-Color[class*=-BGCyan] { + background-color: #60C6C8 +} + +div.highlight .-Color[class*=-BGWhite] { + background-color: #C5C1B4 +} + +/* Font colors for 8-bit ANSI */ + +div.highlight .-Color[class*=-C0] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC0] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C1] { + color: #800000 +} + +div.highlight .-Color[class*=-BGC1] { + background-color: #800000 +} + +div.highlight .-Color[class*=-C2] { + color: #008000 +} + +div.highlight .-Color[class*=-BGC2] { + background-color: #008000 +} + +div.highlight .-Color[class*=-C3] { + color: #808000 +} + +div.highlight .-Color[class*=-BGC3] { + background-color: #808000 +} + +div.highlight .-Color[class*=-C4] { + color: #000080 +} + +div.highlight .-Color[class*=-BGC4] { + background-color: #000080 +} + +div.highlight .-Color[class*=-C5] { + color: #800080 +} + +div.highlight .-Color[class*=-BGC5] { + background-color: #800080 +} + +div.highlight .-Color[class*=-C6] { + color: #008080 +} + +div.highlight .-Color[class*=-BGC6] { + background-color: #008080 +} + +div.highlight .-Color[class*=-C7] { + color: #C0C0C0 +} + +div.highlight .-Color[class*=-BGC7] { + background-color: #C0C0C0 +} + +div.highlight .-Color[class*=-C8] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC8] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C9] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC9] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C10] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC10] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C11] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC11] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C12] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC12] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C13] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC13] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C14] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC14] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C15] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC15] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C16] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC16] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C17] { + color: #00005F +} + +div.highlight .-Color[class*=-BGC17] { + background-color: #00005F +} + +div.highlight .-Color[class*=-C18] { + color: #000087 +} + +div.highlight .-Color[class*=-BGC18] { + background-color: #000087 +} + +div.highlight .-Color[class*=-C19] { + color: #0000AF +} + +div.highlight .-Color[class*=-BGC19] { + background-color: #0000AF +} + +div.highlight .-Color[class*=-C20] { + color: #0000D7 +} + +div.highlight .-Color[class*=-BGC20] { + background-color: #0000D7 +} + +div.highlight .-Color[class*=-C21] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC21] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C22] { + color: #005F00 +} + +div.highlight .-Color[class*=-BGC22] { + background-color: #005F00 +} + +div.highlight .-Color[class*=-C23] { + color: #005F5F +} + +div.highlight .-Color[class*=-BGC23] { + background-color: #005F5F +} + +div.highlight .-Color[class*=-C24] { + color: #005F87 +} + +div.highlight .-Color[class*=-BGC24] { + background-color: #005F87 +} + +div.highlight .-Color[class*=-C25] { + color: #005FAF +} + +div.highlight .-Color[class*=-BGC25] { + background-color: #005FAF +} + +div.highlight .-Color[class*=-C26] { + color: #005FD7 +} + +div.highlight .-Color[class*=-BGC26] { + background-color: #005FD7 +} + +div.highlight .-Color[class*=-C27] { + color: #005FFF +} + +div.highlight .-Color[class*=-BGC27] { + background-color: #005FFF +} + +div.highlight .-Color[class*=-C28] { + color: #008700 +} + +div.highlight .-Color[class*=-BGC28] { + background-color: #008700 +} + +div.highlight .-Color[class*=-C29] { + color: #00875F +} + +div.highlight .-Color[class*=-BGC29] { + background-color: #00875F +} + +div.highlight .-Color[class*=-C30] { + color: #008787 +} + +div.highlight .-Color[class*=-BGC30] { + background-color: #008787 +} + +div.highlight .-Color[class*=-C31] { + color: #0087AF +} + +div.highlight .-Color[class*=-BGC31] { + background-color: #0087AF +} + +div.highlight .-Color[class*=-C32] { + color: #0087D7 +} + +div.highlight .-Color[class*=-BGC32] { + background-color: #0087D7 +} + +div.highlight .-Color[class*=-C33] { + color: #0087FF +} + +div.highlight .-Color[class*=-BGC33] { + background-color: #0087FF +} + +div.highlight .-Color[class*=-C34] { + color: #00AF00 +} + +div.highlight .-Color[class*=-BGC34] { + background-color: #00AF00 +} + +div.highlight .-Color[class*=-C35] { + color: #00AF5F +} + +div.highlight .-Color[class*=-BGC35] { + background-color: #00AF5F +} + +div.highlight .-Color[class*=-C36] { + color: #00AF87 +} + +div.highlight .-Color[class*=-BGC36] { + background-color: #00AF87 +} + +div.highlight .-Color[class*=-C37] { + color: #00AFAF +} + +div.highlight .-Color[class*=-BGC37] { + background-color: #00AFAF +} + +div.highlight .-Color[class*=-C38] { + color: #00AFD7 +} + +div.highlight .-Color[class*=-BGC38] { + background-color: #00AFD7 +} + +div.highlight .-Color[class*=-C39] { + color: #00AFFF +} + +div.highlight .-Color[class*=-BGC39] { + background-color: #00AFFF +} + +div.highlight .-Color[class*=-C40] { + color: #00D700 +} + +div.highlight .-Color[class*=-BGC40] { + background-color: #00D700 +} + +div.highlight .-Color[class*=-C41] { + color: #00D75F +} + +div.highlight .-Color[class*=-BGC41] { + background-color: #00D75F +} + +div.highlight .-Color[class*=-C42] { + color: #00D787 +} + +div.highlight .-Color[class*=-BGC42] { + background-color: #00D787 +} + +div.highlight .-Color[class*=-C43] { + color: #00D7AF +} + +div.highlight .-Color[class*=-BGC43] { + background-color: #00D7AF +} + +div.highlight .-Color[class*=-C44] { + color: #00D7D7 +} + +div.highlight .-Color[class*=-BGC44] { + background-color: #00D7D7 +} + +div.highlight .-Color[class*=-C45] { + color: #00D7FF +} + +div.highlight .-Color[class*=-BGC45] { + background-color: #00D7FF +} + +div.highlight .-Color[class*=-C46] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC46] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C47] { + color: #00FF5F +} + +div.highlight .-Color[class*=-BGC47] { + background-color: #00FF5F +} + +div.highlight .-Color[class*=-C48] { + color: #00FF87 +} + +div.highlight .-Color[class*=-BGC48] { + background-color: #00FF87 +} + +div.highlight .-Color[class*=-C49] { + color: #00FFAF +} + +div.highlight .-Color[class*=-BGC49] { + background-color: #00FFAF +} + +div.highlight .-Color[class*=-C50] { + color: #00FFD7 +} + +div.highlight .-Color[class*=-BGC50] { + background-color: #00FFD7 +} + +div.highlight .-Color[class*=-C51] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC51] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C52] { + color: #5F0000 +} + +div.highlight .-Color[class*=-BGC52] { + background-color: #5F0000 +} + +div.highlight .-Color[class*=-C53] { + color: #5F005F +} + +div.highlight .-Color[class*=-BGC53] { + background-color: #5F005F +} + +div.highlight .-Color[class*=-C54] { + color: #5F0087 +} + +div.highlight .-Color[class*=-BGC54] { + background-color: #5F0087 +} + +div.highlight .-Color[class*=-C55] { + color: #5F00AF +} + +div.highlight .-Color[class*=-BGC55] { + background-color: #5F00AF +} + +div.highlight .-Color[class*=-C56] { + color: #5F00D7 +} + +div.highlight .-Color[class*=-BGC56] { + background-color: #5F00D7 +} + +div.highlight .-Color[class*=-C57] { + color: #5F00FF +} + +div.highlight .-Color[class*=-BGC57] { + background-color: #5F00FF +} + +div.highlight .-Color[class*=-C58] { + color: #5F5F00 +} + +div.highlight .-Color[class*=-BGC58] { + background-color: #5F5F00 +} + +div.highlight .-Color[class*=-C59] { + color: #5F5F5F +} + +div.highlight .-Color[class*=-BGC59] { + background-color: #5F5F5F +} + +div.highlight .-Color[class*=-C60] { + color: #5F5F87 +} + +div.highlight .-Color[class*=-BGC60] { + background-color: #5F5F87 +} + +div.highlight .-Color[class*=-C61] { + color: #5F5FAF +} + +div.highlight .-Color[class*=-BGC61] { + background-color: #5F5FAF +} + +div.highlight .-Color[class*=-C62] { + color: #5F5FD7 +} + +div.highlight .-Color[class*=-BGC62] { + background-color: #5F5FD7 +} + +div.highlight .-Color[class*=-C63] { + color: #5F5FFF +} + +div.highlight .-Color[class*=-BGC63] { + background-color: #5F5FFF +} + +div.highlight .-Color[class*=-C64] { + color: #5F8700 +} + +div.highlight .-Color[class*=-BGC64] { + background-color: #5F8700 +} + +div.highlight .-Color[class*=-C65] { + color: #5F875F +} + +div.highlight .-Color[class*=-BGC65] { + background-color: #5F875F +} + +div.highlight .-Color[class*=-C66] { + color: #5F8787 +} + +div.highlight .-Color[class*=-BGC66] { + background-color: #5F8787 +} + +div.highlight .-Color[class*=-C67] { + color: #5F87AF +} + +div.highlight .-Color[class*=-BGC67] { + background-color: #5F87AF +} + +div.highlight .-Color[class*=-C68] { + color: #5F87D7 +} + +div.highlight .-Color[class*=-BGC68] { + background-color: #5F87D7 +} + +div.highlight .-Color[class*=-C69] { + color: #5F87FF +} + +div.highlight .-Color[class*=-BGC69] { + background-color: #5F87FF +} + +div.highlight .-Color[class*=-C70] { + color: #5FAF00 +} + +div.highlight .-Color[class*=-BGC70] { + background-color: #5FAF00 +} + +div.highlight .-Color[class*=-C71] { + color: #5FAF5F +} + +div.highlight .-Color[class*=-BGC71] { + background-color: #5FAF5F +} + +div.highlight .-Color[class*=-C72] { + color: #5FAF87 +} + +div.highlight .-Color[class*=-BGC72] { + background-color: #5FAF87 +} + +div.highlight .-Color[class*=-C73] { + color: #5FAFAF +} + +div.highlight .-Color[class*=-BGC73] { + background-color: #5FAFAF +} + +div.highlight .-Color[class*=-C74] { + color: #5FAFD7 +} + +div.highlight .-Color[class*=-BGC74] { + background-color: #5FAFD7 +} + +div.highlight .-Color[class*=-C75] { + color: #5FAFFF +} + +div.highlight .-Color[class*=-BGC75] { + background-color: #5FAFFF +} + +div.highlight .-Color[class*=-C76] { + color: #5FD700 +} + +div.highlight .-Color[class*=-BGC76] { + background-color: #5FD700 +} + +div.highlight .-Color[class*=-C77] { + color: #5FD75F +} + +div.highlight .-Color[class*=-BGC77] { + background-color: #5FD75F +} + +div.highlight .-Color[class*=-C78] { + color: #5FD787 +} + +div.highlight .-Color[class*=-BGC78] { + background-color: #5FD787 +} + +div.highlight .-Color[class*=-C79] { + color: #5FD7AF +} + +div.highlight .-Color[class*=-BGC79] { + background-color: #5FD7AF +} + +div.highlight .-Color[class*=-C80] { + color: #5FD7D7 +} + +div.highlight .-Color[class*=-BGC80] { + background-color: #5FD7D7 +} + +div.highlight .-Color[class*=-C81] { + color: #5FD7FF +} + +div.highlight .-Color[class*=-BGC81] { + background-color: #5FD7FF +} + +div.highlight .-Color[class*=-C82] { + color: #5FFF00 +} + +div.highlight .-Color[class*=-BGC82] { + background-color: #5FFF00 +} + +div.highlight .-Color[class*=-C83] { + color: #5FFF5F +} + +div.highlight .-Color[class*=-BGC83] { + background-color: #5FFF5F +} + +div.highlight .-Color[class*=-C84] { + color: #5FFF87 +} + +div.highlight .-Color[class*=-BGC84] { + background-color: #5FFF87 +} + +div.highlight .-Color[class*=-C85] { + color: #5FFFAF +} + +div.highlight .-Color[class*=-BGC85] { + background-color: #5FFFAF +} + +div.highlight .-Color[class*=-C86] { + color: #5FFFD7 +} + +div.highlight .-Color[class*=-BGC86] { + background-color: #5FFFD7 +} + +div.highlight .-Color[class*=-C87] { + color: #5FFFFF +} + +div.highlight .-Color[class*=-BGC87] { + background-color: #5FFFFF +} + +div.highlight .-Color[class*=-C88] { + color: #870000 +} + +div.highlight .-Color[class*=-BGC88] { + background-color: #870000 +} + +div.highlight .-Color[class*=-C89] { + color: #87005F +} + +div.highlight .-Color[class*=-BGC89] { + background-color: #87005F +} + +div.highlight .-Color[class*=-C90] { + color: #870087 +} + +div.highlight .-Color[class*=-BGC90] { + background-color: #870087 +} + +div.highlight .-Color[class*=-C91] { + color: #8700AF +} + +div.highlight .-Color[class*=-BGC91] { + background-color: #8700AF +} + +div.highlight .-Color[class*=-C92] { + color: #8700D7 +} + +div.highlight .-Color[class*=-BGC92] { + background-color: #8700D7 +} + +div.highlight .-Color[class*=-C93] { + color: #8700FF +} + +div.highlight .-Color[class*=-BGC93] { + background-color: #8700FF +} + +div.highlight .-Color[class*=-C94] { + color: #875F00 +} + +div.highlight .-Color[class*=-BGC94] { + background-color: #875F00 +} + +div.highlight .-Color[class*=-C95] { + color: #875F5F +} + +div.highlight .-Color[class*=-BGC95] { + background-color: #875F5F +} + +div.highlight .-Color[class*=-C96] { + color: #875F87 +} + +div.highlight .-Color[class*=-BGC96] { + background-color: #875F87 +} + +div.highlight .-Color[class*=-C97] { + color: #875FAF +} + +div.highlight .-Color[class*=-BGC97] { + background-color: #875FAF +} + +div.highlight .-Color[class*=-C98] { + color: #875FD7 +} + +div.highlight .-Color[class*=-BGC98] { + background-color: #875FD7 +} + +div.highlight .-Color[class*=-C99] { + color: #875FFF +} + +div.highlight .-Color[class*=-BGC99] { + background-color: #875FFF +} + +div.highlight .-Color[class*=-C100] { + color: #878700 +} + +div.highlight .-Color[class*=-BGC100] { + background-color: #878700 +} + +div.highlight .-Color[class*=-C101] { + color: #87875F +} + +div.highlight .-Color[class*=-BGC101] { + background-color: #87875F +} + +div.highlight .-Color[class*=-C102] { + color: #878787 +} + +div.highlight .-Color[class*=-BGC102] { + background-color: #878787 +} + +div.highlight .-Color[class*=-C103] { + color: #8787AF +} + +div.highlight .-Color[class*=-BGC103] { + background-color: #8787AF +} + +div.highlight .-Color[class*=-C104] { + color: #8787D7 +} + +div.highlight .-Color[class*=-BGC104] { + background-color: #8787D7 +} + +div.highlight .-Color[class*=-C105] { + color: #8787FF +} + +div.highlight .-Color[class*=-BGC105] { + background-color: #8787FF +} + +div.highlight .-Color[class*=-C106] { + color: #87AF00 +} + +div.highlight .-Color[class*=-BGC106] { + background-color: #87AF00 +} + +div.highlight .-Color[class*=-C107] { + color: #87AF5F +} + +div.highlight .-Color[class*=-BGC107] { + background-color: #87AF5F +} + +div.highlight .-Color[class*=-C108] { + color: #87AF87 +} + +div.highlight .-Color[class*=-BGC108] { + background-color: #87AF87 +} + +div.highlight .-Color[class*=-C109] { + color: #87AFAF +} + +div.highlight .-Color[class*=-BGC109] { + background-color: #87AFAF +} + +div.highlight .-Color[class*=-C110] { + color: #87AFD7 +} + +div.highlight .-Color[class*=-BGC110] { + background-color: #87AFD7 +} + +div.highlight .-Color[class*=-C111] { + color: #87AFFF +} + +div.highlight .-Color[class*=-BGC111] { + background-color: #87AFFF +} + +div.highlight .-Color[class*=-C112] { + color: #87D700 +} + +div.highlight .-Color[class*=-BGC112] { + background-color: #87D700 +} + +div.highlight .-Color[class*=-C113] { + color: #87D75F +} + +div.highlight .-Color[class*=-BGC113] { + background-color: #87D75F +} + +div.highlight .-Color[class*=-C114] { + color: #87D787 +} + +div.highlight .-Color[class*=-BGC114] { + background-color: #87D787 +} + +div.highlight .-Color[class*=-C115] { + color: #87D7AF +} + +div.highlight .-Color[class*=-BGC115] { + background-color: #87D7AF +} + +div.highlight .-Color[class*=-C116] { + color: #87D7D7 +} + +div.highlight .-Color[class*=-BGC116] { + background-color: #87D7D7 +} + +div.highlight .-Color[class*=-C117] { + color: #87D7FF +} + +div.highlight .-Color[class*=-BGC117] { + background-color: #87D7FF +} + +div.highlight .-Color[class*=-C118] { + color: #87FF00 +} + +div.highlight .-Color[class*=-BGC118] { + background-color: #87FF00 +} + +div.highlight .-Color[class*=-C119] { + color: #87FF5F +} + +div.highlight .-Color[class*=-BGC119] { + background-color: #87FF5F +} + +div.highlight .-Color[class*=-C120] { + color: #87FF87 +} + +div.highlight .-Color[class*=-BGC120] { + background-color: #87FF87 +} + +div.highlight .-Color[class*=-C121] { + color: #87FFAF +} + +div.highlight .-Color[class*=-BGC121] { + background-color: #87FFAF +} + +div.highlight .-Color[class*=-C122] { + color: #87FFD7 +} + +div.highlight .-Color[class*=-BGC122] { + background-color: #87FFD7 +} + +div.highlight .-Color[class*=-C123] { + color: #87FFFF +} + +div.highlight .-Color[class*=-BGC123] { + background-color: #87FFFF +} + +div.highlight .-Color[class*=-C124] { + color: #AF0000 +} + +div.highlight .-Color[class*=-BGC124] { + background-color: #AF0000 +} + +div.highlight .-Color[class*=-C125] { + color: #AF005F +} + +div.highlight .-Color[class*=-BGC125] { + background-color: #AF005F +} + +div.highlight .-Color[class*=-C126] { + color: #AF0087 +} + +div.highlight .-Color[class*=-BGC126] { + background-color: #AF0087 +} + +div.highlight .-Color[class*=-C127] { + color: #AF00AF +} + +div.highlight .-Color[class*=-BGC127] { + background-color: #AF00AF +} + +div.highlight .-Color[class*=-C128] { + color: #AF00D7 +} + +div.highlight .-Color[class*=-BGC128] { + background-color: #AF00D7 +} + +div.highlight .-Color[class*=-C129] { + color: #AF00FF +} + +div.highlight .-Color[class*=-BGC129] { + background-color: #AF00FF +} + +div.highlight .-Color[class*=-C130] { + color: #AF5F00 +} + +div.highlight .-Color[class*=-BGC130] { + background-color: #AF5F00 +} + +div.highlight .-Color[class*=-C131] { + color: #AF5F5F +} + +div.highlight .-Color[class*=-BGC131] { + background-color: #AF5F5F +} + +div.highlight .-Color[class*=-C132] { + color: #AF5F87 +} + +div.highlight .-Color[class*=-BGC132] { + background-color: #AF5F87 +} + +div.highlight .-Color[class*=-C133] { + color: #AF5FAF +} + +div.highlight .-Color[class*=-BGC133] { + background-color: #AF5FAF +} + +div.highlight .-Color[class*=-C134] { + color: #AF5FD7 +} + +div.highlight .-Color[class*=-BGC134] { + background-color: #AF5FD7 +} + +div.highlight .-Color[class*=-C135] { + color: #AF5FFF +} + +div.highlight .-Color[class*=-BGC135] { + background-color: #AF5FFF +} + +div.highlight .-Color[class*=-C136] { + color: #AF8700 +} + +div.highlight .-Color[class*=-BGC136] { + background-color: #AF8700 +} + +div.highlight .-Color[class*=-C137] { + color: #AF875F +} + +div.highlight .-Color[class*=-BGC137] { + background-color: #AF875F +} + +div.highlight .-Color[class*=-C138] { + color: #AF8787 +} + +div.highlight .-Color[class*=-BGC138] { + background-color: #AF8787 +} + +div.highlight .-Color[class*=-C139] { + color: #AF87AF +} + +div.highlight .-Color[class*=-BGC139] { + background-color: #AF87AF +} + +div.highlight .-Color[class*=-C140] { + color: #AF87D7 +} + +div.highlight .-Color[class*=-BGC140] { + background-color: #AF87D7 +} + +div.highlight .-Color[class*=-C141] { + color: #AF87FF +} + +div.highlight .-Color[class*=-BGC141] { + background-color: #AF87FF +} + +div.highlight .-Color[class*=-C142] { + color: #AFAF00 +} + +div.highlight .-Color[class*=-BGC142] { + background-color: #AFAF00 +} + +div.highlight .-Color[class*=-C143] { + color: #AFAF5F +} + +div.highlight .-Color[class*=-BGC143] { + background-color: #AFAF5F +} + +div.highlight .-Color[class*=-C144] { + color: #AFAF87 +} + +div.highlight .-Color[class*=-BGC144] { + background-color: #AFAF87 +} + +div.highlight .-Color[class*=-C145] { + color: #AFAFAF +} + +div.highlight .-Color[class*=-BGC145] { + background-color: #AFAFAF +} + +div.highlight .-Color[class*=-C146] { + color: #AFAFD7 +} + +div.highlight .-Color[class*=-BGC146] { + background-color: #AFAFD7 +} + +div.highlight .-Color[class*=-C147] { + color: #AFAFFF +} + +div.highlight .-Color[class*=-BGC147] { + background-color: #AFAFFF +} + +div.highlight .-Color[class*=-C148] { + color: #AFD700 +} + +div.highlight .-Color[class*=-BGC148] { + background-color: #AFD700 +} + +div.highlight .-Color[class*=-C149] { + color: #AFD75F +} + +div.highlight .-Color[class*=-BGC149] { + background-color: #AFD75F +} + +div.highlight .-Color[class*=-C150] { + color: #AFD787 +} + +div.highlight .-Color[class*=-BGC150] { + background-color: #AFD787 +} + +div.highlight .-Color[class*=-C151] { + color: #AFD7AF +} + +div.highlight .-Color[class*=-BGC151] { + background-color: #AFD7AF +} + +div.highlight .-Color[class*=-C152] { + color: #AFD7D7 +} + +div.highlight .-Color[class*=-BGC152] { + background-color: #AFD7D7 +} + +div.highlight .-Color[class*=-C153] { + color: #AFD7FF +} + +div.highlight .-Color[class*=-BGC153] { + background-color: #AFD7FF +} + +div.highlight .-Color[class*=-C154] { + color: #AFFF00 +} + +div.highlight .-Color[class*=-BGC154] { + background-color: #AFFF00 +} + +div.highlight .-Color[class*=-C155] { + color: #AFFF5F +} + +div.highlight .-Color[class*=-BGC155] { + background-color: #AFFF5F +} + +div.highlight .-Color[class*=-C156] { + color: #AFFF87 +} + +div.highlight .-Color[class*=-BGC156] { + background-color: #AFFF87 +} + +div.highlight .-Color[class*=-C157] { + color: #AFFFAF +} + +div.highlight .-Color[class*=-BGC157] { + background-color: #AFFFAF +} + +div.highlight .-Color[class*=-C158] { + color: #AFFFD7 +} + +div.highlight .-Color[class*=-BGC158] { + background-color: #AFFFD7 +} + +div.highlight .-Color[class*=-C159] { + color: #AFFFFF +} + +div.highlight .-Color[class*=-BGC159] { + background-color: #AFFFFF +} + +div.highlight .-Color[class*=-C160] { + color: #D70000 +} + +div.highlight .-Color[class*=-BGC160] { + background-color: #D70000 +} + +div.highlight .-Color[class*=-C161] { + color: #D7005F +} + +div.highlight .-Color[class*=-BGC161] { + background-color: #D7005F +} + +div.highlight .-Color[class*=-C162] { + color: #D70087 +} + +div.highlight .-Color[class*=-BGC162] { + background-color: #D70087 +} + +div.highlight .-Color[class*=-C163] { + color: #D700AF +} + +div.highlight .-Color[class*=-BGC163] { + background-color: #D700AF +} + +div.highlight .-Color[class*=-C164] { + color: #D700D7 +} + +div.highlight .-Color[class*=-BGC164] { + background-color: #D700D7 +} + +div.highlight .-Color[class*=-C165] { + color: #D700FF +} + +div.highlight .-Color[class*=-BGC165] { + background-color: #D700FF +} + +div.highlight .-Color[class*=-C166] { + color: #D75F00 +} + +div.highlight .-Color[class*=-BGC166] { + background-color: #D75F00 +} + +div.highlight .-Color[class*=-C167] { + color: #D75F5F +} + +div.highlight .-Color[class*=-BGC167] { + background-color: #D75F5F +} + +div.highlight .-Color[class*=-C168] { + color: #D75F87 +} + +div.highlight .-Color[class*=-BGC168] { + background-color: #D75F87 +} + +div.highlight .-Color[class*=-C169] { + color: #D75FAF +} + +div.highlight .-Color[class*=-BGC169] { + background-color: #D75FAF +} + +div.highlight .-Color[class*=-C170] { + color: #D75FD7 +} + +div.highlight .-Color[class*=-BGC170] { + background-color: #D75FD7 +} + +div.highlight .-Color[class*=-C171] { + color: #D75FFF +} + +div.highlight .-Color[class*=-BGC171] { + background-color: #D75FFF +} + +div.highlight .-Color[class*=-C172] { + color: #D78700 +} + +div.highlight .-Color[class*=-BGC172] { + background-color: #D78700 +} + +div.highlight .-Color[class*=-C173] { + color: #D7875F +} + +div.highlight .-Color[class*=-BGC173] { + background-color: #D7875F +} + +div.highlight .-Color[class*=-C174] { + color: #D78787 +} + +div.highlight .-Color[class*=-BGC174] { + background-color: #D78787 +} + +div.highlight .-Color[class*=-C175] { + color: #D787AF +} + +div.highlight .-Color[class*=-BGC175] { + background-color: #D787AF +} + +div.highlight .-Color[class*=-C176] { + color: #D787D7 +} + +div.highlight .-Color[class*=-BGC176] { + background-color: #D787D7 +} + +div.highlight .-Color[class*=-C177] { + color: #D787FF +} + +div.highlight .-Color[class*=-BGC177] { + background-color: #D787FF +} + +div.highlight .-Color[class*=-C178] { + color: #D7AF00 +} + +div.highlight .-Color[class*=-BGC178] { + background-color: #D7AF00 +} + +div.highlight .-Color[class*=-C179] { + color: #D7AF5F +} + +div.highlight .-Color[class*=-BGC179] { + background-color: #D7AF5F +} + +div.highlight .-Color[class*=-C180] { + color: #D7AF87 +} + +div.highlight .-Color[class*=-BGC180] { + background-color: #D7AF87 +} + +div.highlight .-Color[class*=-C181] { + color: #D7AFAF +} + +div.highlight .-Color[class*=-BGC181] { + background-color: #D7AFAF +} + +div.highlight .-Color[class*=-C182] { + color: #D7AFD7 +} + +div.highlight .-Color[class*=-BGC182] { + background-color: #D7AFD7 +} + +div.highlight .-Color[class*=-C183] { + color: #D7AFFF +} + +div.highlight .-Color[class*=-BGC183] { + background-color: #D7AFFF +} + +div.highlight .-Color[class*=-C184] { + color: #D7D700 +} + +div.highlight .-Color[class*=-BGC184] { + background-color: #D7D700 +} + +div.highlight .-Color[class*=-C185] { + color: #D7D75F +} + +div.highlight .-Color[class*=-BGC185] { + background-color: #D7D75F +} + +div.highlight .-Color[class*=-C186] { + color: #D7D787 +} + +div.highlight .-Color[class*=-BGC186] { + background-color: #D7D787 +} + +div.highlight .-Color[class*=-C187] { + color: #D7D7AF +} + +div.highlight .-Color[class*=-BGC187] { + background-color: #D7D7AF +} + +div.highlight .-Color[class*=-C188] { + color: #D7D7D7 +} + +div.highlight .-Color[class*=-BGC188] { + background-color: #D7D7D7 +} + +div.highlight .-Color[class*=-C189] { + color: #D7D7FF +} + +div.highlight .-Color[class*=-BGC189] { + background-color: #D7D7FF +} + +div.highlight .-Color[class*=-C190] { + color: #D7FF00 +} + +div.highlight .-Color[class*=-BGC190] { + background-color: #D7FF00 +} + +div.highlight .-Color[class*=-C191] { + color: #D7FF5F +} + +div.highlight .-Color[class*=-BGC191] { + background-color: #D7FF5F +} + +div.highlight .-Color[class*=-C192] { + color: #D7FF87 +} + +div.highlight .-Color[class*=-BGC192] { + background-color: #D7FF87 +} + +div.highlight .-Color[class*=-C193] { + color: #D7FFAF +} + +div.highlight .-Color[class*=-BGC193] { + background-color: #D7FFAF +} + +div.highlight .-Color[class*=-C194] { + color: #D7FFD7 +} + +div.highlight .-Color[class*=-BGC194] { + background-color: #D7FFD7 +} + +div.highlight .-Color[class*=-C195] { + color: #D7FFFF +} + +div.highlight .-Color[class*=-BGC195] { + background-color: #D7FFFF +} + +div.highlight .-Color[class*=-C196] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC196] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C197] { + color: #FF005F +} + +div.highlight .-Color[class*=-BGC197] { + background-color: #FF005F +} + +div.highlight .-Color[class*=-C198] { + color: #FF0087 +} + +div.highlight .-Color[class*=-BGC198] { + background-color: #FF0087 +} + +div.highlight .-Color[class*=-C199] { + color: #FF00AF +} + +div.highlight .-Color[class*=-BGC199] { + background-color: #FF00AF +} + +div.highlight .-Color[class*=-C200] { + color: #FF00D7 +} + +div.highlight .-Color[class*=-BGC200] { + background-color: #FF00D7 +} + +div.highlight .-Color[class*=-C201] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC201] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C202] { + color: #FF5F00 +} + +div.highlight .-Color[class*=-BGC202] { + background-color: #FF5F00 +} + +div.highlight .-Color[class*=-C203] { + color: #FF5F5F +} + +div.highlight .-Color[class*=-BGC203] { + background-color: #FF5F5F +} + +div.highlight .-Color[class*=-C204] { + color: #FF5F87 +} + +div.highlight .-Color[class*=-BGC204] { + background-color: #FF5F87 +} + +div.highlight .-Color[class*=-C205] { + color: #FF5FAF +} + +div.highlight .-Color[class*=-BGC205] { + background-color: #FF5FAF +} + +div.highlight .-Color[class*=-C206] { + color: #FF5FD7 +} + +div.highlight .-Color[class*=-BGC206] { + background-color: #FF5FD7 +} + +div.highlight .-Color[class*=-C207] { + color: #FF5FFF +} + +div.highlight .-Color[class*=-BGC207] { + background-color: #FF5FFF +} + +div.highlight .-Color[class*=-C208] { + color: #FF8700 +} + +div.highlight .-Color[class*=-BGC208] { + background-color: #FF8700 +} + +div.highlight .-Color[class*=-C209] { + color: #FF875F +} + +div.highlight .-Color[class*=-BGC209] { + background-color: #FF875F +} + +div.highlight .-Color[class*=-C210] { + color: #FF8787 +} + +div.highlight .-Color[class*=-BGC210] { + background-color: #FF8787 +} + +div.highlight .-Color[class*=-C211] { + color: #FF87AF +} + +div.highlight .-Color[class*=-BGC211] { + background-color: #FF87AF +} + +div.highlight .-Color[class*=-C212] { + color: #FF87D7 +} + +div.highlight .-Color[class*=-BGC212] { + background-color: #FF87D7 +} + +div.highlight .-Color[class*=-C213] { + color: #FF87FF +} + +div.highlight .-Color[class*=-BGC213] { + background-color: #FF87FF +} + +div.highlight .-Color[class*=-C214] { + color: #FFAF00 +} + +div.highlight .-Color[class*=-BGC214] { + background-color: #FFAF00 +} + +div.highlight .-Color[class*=-C215] { + color: #FFAF5F +} + +div.highlight .-Color[class*=-BGC215] { + background-color: #FFAF5F +} + +div.highlight .-Color[class*=-C216] { + color: #FFAF87 +} + +div.highlight .-Color[class*=-BGC216] { + background-color: #FFAF87 +} + +div.highlight .-Color[class*=-C217] { + color: #FFAFAF +} + +div.highlight .-Color[class*=-BGC217] { + background-color: #FFAFAF +} + +div.highlight .-Color[class*=-C218] { + color: #FFAFD7 +} + +div.highlight .-Color[class*=-BGC218] { + background-color: #FFAFD7 +} + +div.highlight .-Color[class*=-C219] { + color: #FFAFFF +} + +div.highlight .-Color[class*=-BGC219] { + background-color: #FFAFFF +} + +div.highlight .-Color[class*=-C220] { + color: #FFD700 +} + +div.highlight .-Color[class*=-BGC220] { + background-color: #FFD700 +} + +div.highlight .-Color[class*=-C221] { + color: #FFD75F +} + +div.highlight .-Color[class*=-BGC221] { + background-color: #FFD75F +} + +div.highlight .-Color[class*=-C222] { + color: #FFD787 +} + +div.highlight .-Color[class*=-BGC222] { + background-color: #FFD787 +} + +div.highlight .-Color[class*=-C223] { + color: #FFD7AF +} + +div.highlight .-Color[class*=-BGC223] { + background-color: #FFD7AF +} + +div.highlight .-Color[class*=-C224] { + color: #FFD7D7 +} + +div.highlight .-Color[class*=-BGC224] { + background-color: #FFD7D7 +} + +div.highlight .-Color[class*=-C225] { + color: #FFD7FF +} + +div.highlight .-Color[class*=-BGC225] { + background-color: #FFD7FF +} + +div.highlight .-Color[class*=-C226] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC226] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C227] { + color: #FFFF5F +} + +div.highlight .-Color[class*=-BGC227] { + background-color: #FFFF5F +} + +div.highlight .-Color[class*=-C228] { + color: #FFFF87 +} + +div.highlight .-Color[class*=-BGC228] { + background-color: #FFFF87 +} + +div.highlight .-Color[class*=-C229] { + color: #FFFFAF +} + +div.highlight .-Color[class*=-BGC229] { + background-color: #FFFFAF +} + +div.highlight .-Color[class*=-C230] { + color: #FFFFD7 +} + +div.highlight .-Color[class*=-BGC230] { + background-color: #FFFFD7 +} + +div.highlight .-Color[class*=-C231] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC231] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C232] { + color: #080808 +} + +div.highlight .-Color[class*=-BGC232] { + background-color: #080808 +} + +div.highlight .-Color[class*=-C233] { + color: #121212 +} + +div.highlight .-Color[class*=-BGC233] { + background-color: #121212 +} + +div.highlight .-Color[class*=-C234] { + color: #1C1C1C +} + +div.highlight .-Color[class*=-BGC234] { + background-color: #1C1C1C +} + +div.highlight .-Color[class*=-C235] { + color: #262626 +} + +div.highlight .-Color[class*=-BGC235] { + background-color: #262626 +} + +div.highlight .-Color[class*=-C236] { + color: #303030 +} + +div.highlight .-Color[class*=-BGC236] { + background-color: #303030 +} + +div.highlight .-Color[class*=-C237] { + color: #3A3A3A +} + +div.highlight .-Color[class*=-BGC237] { + background-color: #3A3A3A +} + +div.highlight .-Color[class*=-C238] { + color: #444444 +} + +div.highlight .-Color[class*=-BGC238] { + background-color: #444444 +} + +div.highlight .-Color[class*=-C239] { + color: #4E4E4E +} + +div.highlight .-Color[class*=-BGC239] { + background-color: #4E4E4E +} + +div.highlight .-Color[class*=-C240] { + color: #585858 +} + +div.highlight .-Color[class*=-BGC240] { + background-color: #585858 +} + +div.highlight .-Color[class*=-C241] { + color: #626262 +} + +div.highlight .-Color[class*=-BGC241] { + background-color: #626262 +} + +div.highlight .-Color[class*=-C242] { + color: #6C6C6C +} + +div.highlight .-Color[class*=-BGC242] { + background-color: #6C6C6C +} + +div.highlight .-Color[class*=-C243] { + color: #767676 +} + +div.highlight .-Color[class*=-BGC243] { + background-color: #767676 +} + +div.highlight .-Color[class*=-C244] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC244] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C245] { + color: #8A8A8A +} + +div.highlight .-Color[class*=-BGC245] { + background-color: #8A8A8A +} + +div.highlight .-Color[class*=-C246] { + color: #949494 +} + +div.highlight .-Color[class*=-BGC246] { + background-color: #949494 +} + +div.highlight .-Color[class*=-C247] { + color: #9E9E9E +} + +div.highlight .-Color[class*=-BGC247] { + background-color: #9E9E9E +} + +div.highlight .-Color[class*=-C248] { + color: #A8A8A8 +} + +div.highlight .-Color[class*=-BGC248] { + background-color: #A8A8A8 +} + +div.highlight .-Color[class*=-C249] { + color: #B2B2B2 +} + +div.highlight .-Color[class*=-BGC249] { + background-color: #B2B2B2 +} + +div.highlight .-Color[class*=-C250] { + color: #BCBCBC +} + +div.highlight .-Color[class*=-BGC250] { + background-color: #BCBCBC +} + +div.highlight .-Color[class*=-C251] { + color: #C6C6C6 +} + +div.highlight .-Color[class*=-BGC251] { + background-color: #C6C6C6 +} + +div.highlight .-Color[class*=-C252] { + color: #D0D0D0 +} + +div.highlight .-Color[class*=-BGC252] { + background-color: #D0D0D0 +} + +div.highlight .-Color[class*=-C253] { + color: #DADADA +} + +div.highlight .-Color[class*=-BGC253] { + background-color: #DADADA +} + +div.highlight .-Color[class*=-C254] { + color: #E4E4E4 +} + +div.highlight .-Color[class*=-BGC254] { + background-color: #E4E4E4 +} + +div.highlight .-Color[class*=-C255] { + color: #EEEEEE +} + +div.highlight .-Color[class*=-BGC255] { + background-color: #EEEEEE +} diff --git a/singlehtml/_static/plus.png b/singlehtml/_static/plus.png new file mode 100644 index 0000000..7107cec Binary files /dev/null and b/singlehtml/_static/plus.png differ diff --git a/singlehtml/_static/pygments.css b/singlehtml/_static/pygments.css new file mode 100644 index 0000000..84ab303 --- /dev/null +++ b/singlehtml/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/singlehtml/_static/searchtools.js b/singlehtml/_static/searchtools.js new file mode 100644 index 0000000..b08d58c --- /dev/null +++ b/singlehtml/_static/searchtools.js @@ -0,0 +1,620 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/singlehtml/_static/sphinx-design.min.css b/singlehtml/_static/sphinx-design.min.css new file mode 100644 index 0000000..860c36d --- /dev/null +++ b/singlehtml/_static/sphinx-design.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative;font-size:var(--sd-fontsize-dropdown)}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary.sd-summary-title{padding:.5em .6em .5em 1em;font-size:var(--sd-fontsize-dropdown-title);font-weight:var(--sd-fontweight-dropdown-title);user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;list-style:none;display:inline-flex;justify-content:space-between}details.sd-dropdown summary.sd-summary-title::-webkit-details-marker{display:none}details.sd-dropdown summary.sd-summary-title:focus{outline:none}details.sd-dropdown summary.sd-summary-title .sd-summary-icon{margin-right:.6em;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary.sd-summary-title .sd-summary-text{flex-grow:1;line-height:1.5;padding-right:.5rem}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker{pointer-events:none;display:inline-flex;align-items:center}details.sd-dropdown summary.sd-summary-title .sd-summary-state-marker svg{opacity:.6}details.sd-dropdown summary.sd-summary-title:hover .sd-summary-state-marker svg{opacity:1;transform:scale(1.1)}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown .sd-summary-chevron-right{transition:.25s}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-right{transform:rotate(90deg)}details.sd-dropdown[open]>.sd-summary-title .sd-summary-chevron-down{transform:rotate(180deg)}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-bg: rgba(0, 113, 188, 0.2);--sd-color-secondary-bg: rgba(108, 117, 125, 0.2);--sd-color-success-bg: rgba(40, 167, 69, 0.2);--sd-color-info-bg: rgba(23, 162, 184, 0.2);--sd-color-warning-bg: rgba(240, 179, 126, 0.2);--sd-color-danger-bg: rgba(220, 53, 69, 0.2);--sd-color-light-bg: rgba(248, 249, 250, 0.2);--sd-color-muted-bg: rgba(108, 117, 125, 0.2);--sd-color-dark-bg: rgba(33, 37, 41, 0.2);--sd-color-black-bg: rgba(0, 0, 0, 0.2);--sd-color-white-bg: rgba(255, 255, 255, 0.2);--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem;--sd-fontsize-dropdown: inherit;--sd-fontsize-dropdown-title: 1rem;--sd-fontweight-dropdown-title: 700} diff --git a/singlehtml/_static/sphinx_highlight.js b/singlehtml/_static/sphinx_highlight.js new file mode 100644 index 0000000..8a96c69 --- /dev/null +++ b/singlehtml/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/singlehtml/_static/sphinx_lesson.css b/singlehtml/_static/sphinx_lesson.css new file mode 100644 index 0000000..14b20c6 --- /dev/null +++ b/singlehtml/_static/sphinx_lesson.css @@ -0,0 +1,51 @@ +/* sphinx_lesson.css */ + +body.wy-body-for-nav img.with-border { + border: 2px solid; +} + +.rst-content .admonition-no-content { + padding-bottom: 0px; +} + +.rst-content .demo > .admonition-title::before { + content: "\01F440"; /* Eyes */ } +.rst-content .type-along > .admonition-title::before { + content: "\02328\0FE0F"; /* Keyboard */ } +.rst-content .exercise > .admonition-title::before { + content: "\0270D\0FE0F"; /* Hand */ } +.rst-content .solution > .admonition-title::before { + content: "\02714\0FE0E"; /* Check mark */ } +.rst-content .homework > .admonition-title::before { + content: "\01F4DD"; /* Memo */ } +.rst-content .discussion > .admonition-title::before { + content: "\01F4AC"; /* Speech balloon */ } +.rst-content .questions > .admonition-title::before { + content: "\02753\0FE0E"; /* Question mark */ } +.rst-content .prerequisites > .admonition-title::before { + content: "\02699"; /* Gear */ } +.rst-content .seealso > .admonition-title::before { + content: "\027A1\0FE0E"; /* Question mark */ } + + +/* instructor-note */ +.rst-content .instructor-note { + background: #e7e7e7; +} +.rst-content .instructor-note > .admonition-title { + background: #6a6a6a; +} +.rst-content .instructor-note > .admonition-title::before { + content: ""; +} + + +/* sphinx_toggle_button, make the font white */ +.rst-content .toggle.admonition button.toggle-button { + color: white; +} + +/* sphinx-togglebutton, remove underflow when toggled to hidden mode */ +.rst-content .admonition.toggle-hidden { + padding-bottom: 0px; +} diff --git a/singlehtml/_static/sphinx_rtd_theme_ext_color_contrast.css b/singlehtml/_static/sphinx_rtd_theme_ext_color_contrast.css new file mode 100644 index 0000000..e68feb8 --- /dev/null +++ b/singlehtml/_static/sphinx_rtd_theme_ext_color_contrast.css @@ -0,0 +1,47 @@ +/* The following are for web accessibility of sphinx_rtd_theme: they + * solve some of the most frequent contrast issues. Remove when this + * solved: + * https://github.com/readthedocs/sphinx_rtd_theme/issues/971 + */ +/* background: #fcfcfc, note boxes #E7F2FA */ +a { color: #2573A7; } /* original #2980B9, #1F5C84; */ +body { color: #242424; } /* original #404040, #383838 */ +.wy-side-nav-search>a, .wy-side-nav-search .wy-dropdown>a { + color: #ffffff; +} /* original #fcfcfc */ +footer { color: #737373; } /* original gray=#808080*/ +footer span.commit code, footer span.commit .rst-content tt, .rst-content footer span.commit tt { + color: #737373; +} /* original gray=#808080*/ +.rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal { + color: #AB2314; +} +/* Sidebar background */ +.wy-side-nav-search { background-color: #277CB4;} + +/* Same, but for pygments */ +.highlight .ch { color: #3E7A89; } /* #! line */ +.highlight .c1 { color: #3E7A89; } /* also comments */ +.highlight .nv { color: #AD3ECC; } /* variable */ +.highlight .gp { color: #B45608; } /* prompt character, $*/ +.highlight .si { color: #3975B1; } /* ${} variable text */ +.highlight .nc { color: #0C78A7; } + +/* Sphinx admonitions */ +/* warning */ +.wy-alert.wy-alert-warning .wy-alert-title, .rst-content .wy-alert-warning.note .wy-alert-title, .rst-content .attention .wy-alert-title, .rst-content .caution .wy-alert-title, .rst-content .wy-alert-warning.danger .wy-alert-title, .rst-content .wy-alert-warning.error .wy-alert-title, .rst-content .wy-alert-warning.hint .wy-alert-title, .rst-content .wy-alert-warning.important .wy-alert-title, .rst-content .wy-alert-warning.tip .wy-alert-title, .rst-content .warning .wy-alert-title, .rst-content .wy-alert-warning.seealso .wy-alert-title, .rst-content .admonition-todo .wy-alert-title, .rst-content .wy-alert-warning.admonition .wy-alert-title, .wy-alert.wy-alert-warning .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-warning .admonition-title, .rst-content .wy-alert-warning.note .admonition-title, .rst-content .attention .admonition-title, .rst-content .caution .admonition-title, .rst-content .wy-alert-warning.danger .admonition-title, .rst-content .wy-alert-warning.error .admonition-title, .rst-content .wy-alert-warning.hint .admonition-title, .rst-content .wy-alert-warning.important .admonition-title, .rst-content .wy-alert-warning.tip .admonition-title, .rst-content .warning .admonition-title, .rst-content .wy-alert-warning.seealso .admonition-title, .rst-content .admonition-todo .admonition-title, .rst-content .wy-alert-warning.admonition .admonition-title { + background: #B15E16; } +/* important */ +.wy-alert.wy-alert-success .wy-alert-title, .rst-content .wy-alert-success.note .wy-alert-title, .rst-content .wy-alert-success.attention .wy-alert-title, .rst-content .wy-alert-success.caution .wy-alert-title, .rst-content .wy-alert-success.danger .wy-alert-title, .rst-content .wy-alert-success.error .wy-alert-title, .rst-content .hint .wy-alert-title, .rst-content .important .wy-alert-title, .rst-content .tip .wy-alert-title, .rst-content .wy-alert-success.warning .wy-alert-title, .rst-content .wy-alert-success.seealso .wy-alert-title, .rst-content .wy-alert-success.admonition-todo .wy-alert-title, .rst-content .wy-alert-success.admonition .wy-alert-title, .wy-alert.wy-alert-success .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-success .admonition-title, .rst-content .wy-alert-success.note .admonition-title, .rst-content .wy-alert-success.attention .admonition-title, .rst-content .wy-alert-success.caution .admonition-title, .rst-content .wy-alert-success.danger .admonition-title, .rst-content .wy-alert-success.error .admonition-title, .rst-content .hint .admonition-title, .rst-content .important .admonition-title, .rst-content .tip .admonition-title, .rst-content .wy-alert-success.warning .admonition-title, .rst-content .wy-alert-success.seealso .admonition-title, .rst-content .wy-alert-success.admonition-todo .admonition-title, .rst-content .wy-alert-success.admonition .admonition-title { + background: #12826C; } +/* seealso, note, etc */ +.wy-alert.wy-alert-info .wy-alert-title, .rst-content .note .wy-alert-title, .rst-content .wy-alert-info.attention .wy-alert-title, .rst-content .wy-alert-info.caution .wy-alert-title, .rst-content .wy-alert-info.danger .wy-alert-title, .rst-content .wy-alert-info.error .wy-alert-title, .rst-content .wy-alert-info.hint .wy-alert-title, .rst-content .wy-alert-info.important .wy-alert-title, .rst-content .wy-alert-info.tip .wy-alert-title, .rst-content .wy-alert-info.warning .wy-alert-title, .rst-content .seealso .wy-alert-title, .rst-content .wy-alert-info.admonition-todo .wy-alert-title, .rst-content .wy-alert-info.admonition .wy-alert-title, .wy-alert.wy-alert-info .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-info .admonition-title, .rst-content .note .admonition-title, .rst-content .wy-alert-info.attention .admonition-title, .rst-content .wy-alert-info.caution .admonition-title, .rst-content .wy-alert-info.danger .admonition-title, .rst-content .wy-alert-info.error .admonition-title, .rst-content .wy-alert-info.hint .admonition-title, .rst-content .wy-alert-info.important .admonition-title, .rst-content .wy-alert-info.tip .admonition-title, .rst-content .wy-alert-info.warning .admonition-title, .rst-content .seealso .admonition-title, .rst-content .wy-alert-info.admonition-todo .admonition-title, .rst-content .wy-alert-info.admonition .admonition-title { + background: #277CB4; } +/* error, danger */ +.rst-content .danger .admonition-title, .rst-content .danger .wy-alert-title, .rst-content .error .admonition-title, .rst-content .error .wy-alert-title, .rst-content .wy-alert-danger.admonition-todo .admonition-title, .rst-content .wy-alert-danger.admonition-todo .wy-alert-title, .rst-content .wy-alert-danger.admonition .admonition-title, .rst-content .wy-alert-danger.admonition .wy-alert-title, .rst-content .wy-alert-danger.attention .admonition-title, .rst-content .wy-alert-danger.attention .wy-alert-title, .rst-content .wy-alert-danger.caution .admonition-title, .rst-content .wy-alert-danger.caution .wy-alert-title, .rst-content .wy-alert-danger.hint .admonition-title, .rst-content .wy-alert-danger.hint .wy-alert-title, .rst-content .wy-alert-danger.important .admonition-title, .rst-content .wy-alert-danger.important .wy-alert-title, .rst-content .wy-alert-danger.note .admonition-title, .rst-content .wy-alert-danger.note .wy-alert-title, .rst-content .wy-alert-danger.seealso .admonition-title, .rst-content .wy-alert-danger.seealso .wy-alert-title, .rst-content .wy-alert-danger.tip .admonition-title, .rst-content .wy-alert-danger.tip .wy-alert-title, .rst-content .wy-alert-danger.warning .admonition-title, .rst-content .wy-alert-danger.warning .wy-alert-title, .rst-content .wy-alert.wy-alert-danger .admonition-title, .wy-alert.wy-alert-danger .rst-content .admonition-title, .wy-alert.wy-alert-danger .wy-alert-title { + background: #e31704; +} + +/* Generic admonition titles */ +.wy-alert-title, .rst-content .admonition-title { + background: #277CB4; } diff --git a/singlehtml/_static/tabs.css b/singlehtml/_static/tabs.css new file mode 100644 index 0000000..957ba60 --- /dev/null +++ b/singlehtml/_static/tabs.css @@ -0,0 +1,89 @@ +.sphinx-tabs { + margin-bottom: 1rem; +} + +[role="tablist"] { + border-bottom: 1px solid #a0b3bf; +} + +.sphinx-tabs-tab { + position: relative; + font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; + color: #1D5C87; + line-height: 24px; + margin: 0; + font-size: 16px; + font-weight: 400; + background-color: rgba(255, 255, 255, 0); + border-radius: 5px 5px 0 0; + border: 0; + padding: 1rem 1.5rem; + margin-bottom: 0; +} + +.sphinx-tabs-tab[aria-selected="true"] { + font-weight: 700; + border: 1px solid #a0b3bf; + border-bottom: 1px solid white; + margin: -1px; + background-color: white; +} + +.sphinx-tabs-tab:focus { + z-index: 1; + outline-offset: 1px; +} + +.sphinx-tabs-panel { + position: relative; + padding: 1rem; + border: 1px solid #a0b3bf; + margin: 0px -1px -1px -1px; + border-radius: 0 0 5px 5px; + border-top: 0; + background: white; +} + +.sphinx-tabs-panel.code-tab { + padding: 0.4rem; +} + +.sphinx-tab img { + margin-bottom: 24 px; +} + +/* Dark theme preference styling */ + +@media (prefers-color-scheme: dark) { + body[data-theme="auto"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); + } + + body[data-theme="auto"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); + } + + body[data-theme="auto"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 1px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); + } +} + +/* Explicit dark theme styling */ + +body[data-theme="dark"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); +} + +body[data-theme="dark"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); +} + +body[data-theme="dark"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 2px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); +} diff --git a/singlehtml/_static/tabs.js b/singlehtml/_static/tabs.js new file mode 100644 index 0000000..48dc303 --- /dev/null +++ b/singlehtml/_static/tabs.js @@ -0,0 +1,145 @@ +try { + var session = window.sessionStorage || {}; +} catch (e) { + var session = {}; +} + +window.addEventListener("DOMContentLoaded", () => { + const allTabs = document.querySelectorAll('.sphinx-tabs-tab'); + const tabLists = document.querySelectorAll('[role="tablist"]'); + + allTabs.forEach(tab => { + tab.addEventListener("click", changeTabs); + }); + + tabLists.forEach(tabList => { + tabList.addEventListener("keydown", keyTabs); + }); + + // Restore group tab selection from session + const lastSelected = session.getItem('sphinx-tabs-last-selected'); + if (lastSelected != null) selectNamedTabs(lastSelected); +}); + +/** + * Key focus left and right between sibling elements using arrows + * @param {Node} e the element in focus when key was pressed + */ +function keyTabs(e) { + const tab = e.target; + let nextTab = null; + if (e.keyCode === 39 || e.keyCode === 37) { + tab.setAttribute("tabindex", -1); + // Move right + if (e.keyCode === 39) { + nextTab = tab.nextElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.firstElementChild; + } + // Move left + } else if (e.keyCode === 37) { + nextTab = tab.previousElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.lastElementChild; + } + } + } + + if (nextTab !== null) { + nextTab.setAttribute("tabindex", 0); + nextTab.focus(); + } +} + +/** + * Select or deselect clicked tab. If a group tab + * is selected, also select tab in other tabLists. + * @param {Node} e the element that was clicked + */ +function changeTabs(e) { + // Use this instead of the element that was clicked, in case it's a child + const notSelected = this.getAttribute("aria-selected") === "false"; + const positionBefore = this.parentNode.getBoundingClientRect().top; + const notClosable = !this.parentNode.classList.contains("closeable"); + + deselectTabList(this); + + if (notSelected || notClosable) { + selectTab(this); + const name = this.getAttribute("name"); + selectNamedTabs(name, this.id); + + if (this.classList.contains("group-tab")) { + // Persist during session + session.setItem('sphinx-tabs-last-selected', name); + } + } + + const positionAfter = this.parentNode.getBoundingClientRect().top; + const positionDelta = positionAfter - positionBefore; + // Scroll to offset content resizing + window.scrollTo(0, window.scrollY + positionDelta); +} + +/** + * Select tab and show associated panel. + * @param {Node} tab tab to select + */ +function selectTab(tab) { + tab.setAttribute("aria-selected", true); + + // Show the associated panel + document + .getElementById(tab.getAttribute("aria-controls")) + .removeAttribute("hidden"); +} + +/** + * Hide the panels associated with all tabs within the + * tablist containing this tab. + * @param {Node} tab a tab within the tablist to deselect + */ +function deselectTabList(tab) { + const parent = tab.parentNode; + const grandparent = parent.parentNode; + + Array.from(parent.children) + .forEach(t => t.setAttribute("aria-selected", false)); + + Array.from(grandparent.children) + .slice(1) // Skip tablist + .forEach(panel => panel.setAttribute("hidden", true)); +} + +/** + * Select grouped tabs with the same name, but no the tab + * with the given id. + * @param {Node} name name of grouped tab to be selected + * @param {Node} clickedId id of clicked tab + */ +function selectNamedTabs(name, clickedId=null) { + const groupedTabs = document.querySelectorAll(`.sphinx-tabs-tab[name="${name}"]`); + const tabLists = Array.from(groupedTabs).map(tab => tab.parentNode); + + tabLists + .forEach(tabList => { + // Don't want to change the tabList containing the clicked tab + const clickedTab = tabList.querySelector(`[id="${clickedId}"]`); + if (clickedTab === null ) { + // Select first tab with matching name + const tab = tabList.querySelector(`.sphinx-tabs-tab[name="${name}"]`); + deselectTabList(tab); + selectTab(tab); + } + }) +} + +if (typeof exports === 'undefined') { + exports = {}; +} + +exports.keyTabs = keyTabs; +exports.changeTabs = changeTabs; +exports.selectTab = selectTab; +exports.deselectTabList = deselectTabList; +exports.selectNamedTabs = selectNamedTabs; diff --git a/singlehtml/_static/term_role_formatting.css b/singlehtml/_static/term_role_formatting.css new file mode 100644 index 0000000..0b66095 --- /dev/null +++ b/singlehtml/_static/term_role_formatting.css @@ -0,0 +1,4 @@ +/* Make terms bold */ +a.reference span.std-term { + font-weight: bold; +} diff --git a/singlehtml/_static/togglebutton.css b/singlehtml/_static/togglebutton.css new file mode 100644 index 0000000..54a6787 --- /dev/null +++ b/singlehtml/_static/togglebutton.css @@ -0,0 +1,160 @@ +/** + * Admonition-based toggles + */ + +/* Visibility of the target */ +.admonition.toggle .admonition-title ~ * { + transition: opacity .3s, height .3s; +} + +/* Toggle buttons inside admonitions so we see the title */ +.admonition.toggle { + position: relative; +} + +/* Titles should cut off earlier to avoid overlapping w/ button */ +.admonition.toggle .admonition-title { + padding-right: 25%; + cursor: pointer; +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:hover { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 1%); +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:active { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 3%); +} + +/* Remove extra whitespace below the admonition title when hidden */ +.admonition.toggle-hidden { + padding-bottom: 0; +} + +.admonition.toggle-hidden .admonition-title { + margin-bottom: 0; +} + +/* hides all the content of a page until de-toggled */ +.admonition.toggle-hidden .admonition-title ~ * { + height: 0; + margin: 0; + opacity: 0; + visibility: hidden; +} + +/* General button style and position*/ +button.toggle-button { + /** + * Background and shape. By default there's no background + * but users can style as they wish + */ + background: none; + border: none; + outline: none; + + /* Positioning just inside the admonition title */ + position: absolute; + right: 0.5em; + padding: 0px; + border: none; + outline: none; +} + +/* Display the toggle hint on wide screens */ +@media (min-width: 768px) { + button.toggle-button.toggle-button-hidden:before { + content: attr(data-toggle-hint); /* This will be filled in by JS */ + font-size: .8em; + align-self: center; + } +} + +/* Icon behavior */ +.tb-icon { + transition: transform .2s ease-out; + height: 1.5em; + width: 1.5em; + stroke: currentColor; /* So that we inherit the color of other text */ +} + +/* The icon should point right when closed, down when open. */ +/* Open */ +.admonition.toggle button .tb-icon { + transform: rotate(90deg); +} + +/* Closed */ +.admonition.toggle button.toggle-button-hidden .tb-icon { + transform: rotate(0deg); +} + +/* With details toggles, we don't rotate the icon so it points right */ +details.toggle-details .tb-icon { + height: 1.4em; + width: 1.4em; + margin-top: 0.1em; /* To center the button vertically */ +} + + +/** + * Details-based toggles. + * In this case, we wrap elements with `.toggle` in a details block. + */ + +/* Details blocks */ +details.toggle-details { + margin: 1em 0; +} + + +details.toggle-details summary { + display: flex; + align-items: center; + cursor: pointer; + list-style: none; + border-radius: .2em; + border-left: 3px solid #1976d2; + background-color: rgb(204 204 204 / 10%); + padding: 0.2em 0.7em 0.3em 0.5em; /* Less padding on left because the SVG has left margin */ + font-size: 0.9em; +} + +details.toggle-details summary:hover { + background-color: rgb(204 204 204 / 20%); +} + +details.toggle-details summary:active { + background: rgb(204 204 204 / 28%); +} + +.toggle-details__summary-text { + margin-left: 0.2em; +} + +details.toggle-details[open] summary { + margin-bottom: .5em; +} + +details.toggle-details[open] summary .tb-icon { + transform: rotate(90deg); +} + +details.toggle-details[open] summary ~ * { + animation: toggle-fade-in .3s ease-out; +} + +@keyframes toggle-fade-in { + from {opacity: 0%;} + to {opacity: 100%;} +} + +/* Print rules - we hide all toggle button elements at print */ +@media print { + /* Always hide the summary so the button doesn't show up */ + details.toggle-details summary { + display: none; + } +} \ No newline at end of file diff --git a/singlehtml/_static/togglebutton.js b/singlehtml/_static/togglebutton.js new file mode 100644 index 0000000..215a7ee --- /dev/null +++ b/singlehtml/_static/togglebutton.js @@ -0,0 +1,187 @@ +/** + * Add Toggle Buttons to elements + */ + +let toggleChevron = ` + + + +`; + +var initToggleItems = () => { + var itemsToToggle = document.querySelectorAll(togglebuttonSelector); + console.log(`[togglebutton]: Adding toggle buttons to ${itemsToToggle.length} items`) + // Add the button to each admonition and hook up a callback to toggle visibility + itemsToToggle.forEach((item, index) => { + if (item.classList.contains("admonition")) { + // If it's an admonition block, then we'll add a button inside + // Generate unique IDs for this item + var toggleID = `toggle-${index}`; + var buttonID = `button-${toggleID}`; + + item.setAttribute('id', toggleID); + if (!item.classList.contains("toggle")){ + item.classList.add("toggle"); + } + // This is the button that will be added to each item to trigger the toggle + var collapseButton = ` + `; + + title = item.querySelector(".admonition-title") + title.insertAdjacentHTML("beforeend", collapseButton); + thisButton = document.getElementById(buttonID); + + // Add click handlers for the button + admonition title (if admonition) + admonitionTitle = document.querySelector(`#${toggleID} > .admonition-title`) + if (admonitionTitle) { + // If an admonition, then make the whole title block clickable + admonitionTitle.addEventListener('click', toggleClickHandler); + admonitionTitle.dataset.target = toggleID + admonitionTitle.dataset.button = buttonID + } else { + // If not an admonition then we'll listen for the button click + thisButton.addEventListener('click', toggleClickHandler); + } + + // Now hide the item for this toggle button unless explicitly noted to show + if (!item.classList.contains("toggle-shown")) { + toggleHidden(thisButton); + } + } else { + // If not an admonition, wrap the block in a
block + // Define the structure of the details block and insert it as a sibling + var detailsBlock = ` +
+ + ${toggleChevron} + ${toggleHintShow} + +
`; + item.insertAdjacentHTML("beforebegin", detailsBlock); + + // Now move the toggle-able content inside of the details block + details = item.previousElementSibling + details.appendChild(item) + item.classList.add("toggle-details__container") + + // Set up a click trigger to change the text as needed + details.addEventListener('click', (click) => { + let parent = click.target.parentElement; + if (parent.tagName.toLowerCase() == "details") { + summary = parent.querySelector("summary"); + details = parent; + } else { + summary = parent; + details = parent.parentElement; + } + // Update the inner text for the proper hint + if (details.open) { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintShow; + } else { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintHide; + } + + }); + + // If we have a toggle-shown class, open details block should be open + if (item.classList.contains("toggle-shown")) { + details.click(); + } + } + }) +}; + +// This should simply add / remove the collapsed class and change the button text +var toggleHidden = (button) => { + target = button.dataset['target'] + var itemToToggle = document.getElementById(target); + if (itemToToggle.classList.contains("toggle-hidden")) { + itemToToggle.classList.remove("toggle-hidden"); + button.classList.remove("toggle-button-hidden"); + } else { + itemToToggle.classList.add("toggle-hidden"); + button.classList.add("toggle-button-hidden"); + } +} + +var toggleClickHandler = (click) => { + // Be cause the admonition title is clickable and extends to the whole admonition + // We only look for a click event on this title to trigger the toggle. + + if (click.target.classList.contains("admonition-title")) { + button = click.target.querySelector(".toggle-button"); + } else if (click.target.classList.contains("tb-icon")) { + // We've clicked the icon and need to search up one parent for the button + button = click.target.parentElement; + } else if (click.target.tagName == "polyline") { + // We've clicked the SVG elements inside the button, need to up 2 layers + button = click.target.parentElement.parentElement; + } else if (click.target.classList.contains("toggle-button")) { + // We've clicked the button itself and so don't need to do anything + button = click.target; + } else { + console.log(`[togglebutton]: Couldn't find button for ${click.target}`) + } + target = document.getElementById(button.dataset['button']); + toggleHidden(target); +} + +// If we want to blanket-add toggle classes to certain cells +var addToggleToSelector = () => { + const selector = ""; + if (selector.length > 0) { + document.querySelectorAll(selector).forEach((item) => { + item.classList.add("toggle"); + }) + } +} + +// Helper function to run when the DOM is finished +const sphinxToggleRunWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} +sphinxToggleRunWhenDOMLoaded(addToggleToSelector) +sphinxToggleRunWhenDOMLoaded(initToggleItems) + +/** Toggle details blocks to be open when printing */ +if (toggleOpenOnPrint == "true") { + window.addEventListener("beforeprint", () => { + // Open the details + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.dataset["togglestatus"] = el.open; + el.open = true; + }); + + // Open the admonitions + document.querySelectorAll(".admonition.toggle.toggle-hidden").forEach((el) => { + console.log(el); + el.querySelector("button.toggle-button").click(); + el.dataset["toggle_after_print"] = "true"; + }); + }); + window.addEventListener("afterprint", () => { + // Re-close the details that were closed + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.open = el.dataset["togglestatus"] == "true"; + delete el.dataset["togglestatus"]; + }); + + // Re-close the admonition toggle buttons + document.querySelectorAll(".admonition.toggle").forEach((el) => { + if (el.dataset["toggle_after_print"] == "true") { + el.querySelector("button.toggle-button").click(); + delete el.dataset["toggle_after_print"]; + } + }); + }); +} diff --git a/singlehtml/index.html b/singlehtml/index.html new file mode 100644 index 0000000..0a783a7 --- /dev/null +++ b/singlehtml/index.html @@ -0,0 +1,6234 @@ + + + + + + + Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Train the trainer workshop

+
+

August/September 2024 CodeRefinery train the trainer workshop

+

Do you teach the use of computers and computational tools? Are you curious about scaling your training and learn about tested and proven practices from CodeRefinery workshops and other trainers? Join us for the CodeRefinery train the trainer workshop: four self-contained sessions on tools and techniques for computational training offer a great chance to enhance your teaching skills and learn about new tools and practices. What you will learn is also used a lot outside CodeRefinery, whenever good beginner friendly training is needed.

+

Learning objectives:

+
    +
  • Learn about tools and techniques and practice to create engaging online teaching experiences (screenshare, audio, etc.).

  • +
  • Become mentally ready to be an instructor in a collaborative interactive online workshop (not only large workshops but in general).

  • +
  • Learn how to design and develop lesson material collaboratively.

  • +
+

Target audience:

+
    +
  • Everyone teaching online workshops about computational topics or interested in teaching.

  • +
  • Previous and future instructors and helpers of CodeRefinery workshops.

  • +
+

Prerequisites: +An interest in teaching.

+

Workshop structure: +We aim for a mix of modular presentations and work in small groups. The latter will be done in breakoutrooms - +be prepared to switch on your camera and have a fruitful exchange with fellow participants!

+

Organizers and instructors:

+

The workshop is organized by partner organizations of the CodeRefinery project.

+

Facilitators and instructors:

+
    +
  • Radovan Bast

  • +
  • Richard Darst

  • +
  • Bjørn Lindi

  • +
  • Dhanya Pushpadas

  • +
  • Jarno Rantaharju

  • +
  • Stephan Smuts

  • +
  • Stepas Toliautas

  • +
  • Samantha Wittke

  • +
+

Content and timing:

+

The workshop consists of four sessions every Tuesday between August +13th and September 3rd 2024, + to +:

+
    +
  • Session 1: About lesson design, deployment and iterative improvement (Aug 13)

  • +
  • Session 2: Tools and techniques adopted in CodeRefinery workshops (Aug 20)

  • +
  • Session 3: About teaching & cool things we all would like to share (Aug 27)

  • +
  • Session 4: Workshop streaming practices and post-workshop tasks (Sep 3)

  • +
+

You can join all sessions, or the just the ones that interest you. More details on each session will be shared later.

+

The workshop is free of charge for everyone, please register below to get the Zoom link and other useful information for the workshop.

+

The workshop is over and registration is closed now.

+

If you have any questions, please write to support@coderefinery.org.

+
+
+
+

Lesson design and development

+
+

Objectives

+
    +
  • We share our design processes for teaching material and presentations.

  • +
  • Learn how to design lessons “backwards”, starting from learning objectives +and learner personas.

  • +
  • Learn good practices for improving existing material based on feedback.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 20 min

  • +
  • Exercises: 35 min

  • +
+
+
+

Exercise: How do you design your teaching material?

+
+

We collect notes using a shared document (5 min)

+
    +
  • When you start preparing a new lesson or training material, where do you start?

  • +
  • What tricks help you with “writer’s block” or the empty page problem?

  • +
  • Maybe you haven’t designed training material yet. But how do you start when creating a new presentation?

  • +
  • If your design process has changed over time, please describe what you used to do and what you do now instead.

  • +
  • What do you know now about preparing lessons/training/presentations that you wish you knew earlier?

  • +
+
+
+
+

Creating new teaching material

+
+

Typical problems

+
    +
  • Someone creates a lesson, but they think about what is interesting to them, +not what is important for the learners.

  • +
  • “I want to show a number of things which I think are cool about +tool X - how do I press these into 90 minutes?”

  • +
  • Write down material you want to cover and then sprinkle in some exercises.

  • +
  • Thinking about how I work, not how the learners work.

  • +
  • Trying to bring learners to their level/setup, not trying to meet the learners +where they are.

  • +
  • Not really knowing the learning objectives or the learner personas.

  • +
+
+
+

Better approach

+

Good questions to ask and discuss with a group of colleagues from diverse backgrounds:

+
    +
  • What is the expected educational level of my audience?

  • +
  • Have they been already exposed to the technologies I am planning to teach?

  • +
  • What tools do they already use?

  • +
  • What are the main issues they are currently experiencing?

  • +
  • What do they need to remember/understand/apply/analyze/evaluate/create +(Bloom’s taxonomy)?

  • +
  • Define learner personas.

  • +
  • It may be an advantage to share an imperfect lesson with others early to +collect feedback and suggestions before the lesson “solidifies” too much. +Draft it and collect feedback. The result will probably be better than +working in isolation towards a “perfect” lesson.

  • +
+
+
+

The process of designing a lesson “backwards”

+

As described in “A lesson design process” in the book Teaching Tech +Together:

+
    +
  1. Understand your learners.

  2. +
  3. Brainstorm rough ideas.

  4. +
  5. Create an summative assessment to know your overall goal.

    +
    +

    [Think of the things your learners will be able to do at the end of the lesson]

    +
    +
  6. +
  7. Create formative assessments to go from the starting point to this.

    +
    +

    [Think of some engaging and active exercises]

    +
    +
  8. +
  9. Order the formative assessments (exercises) into a reasonable order.

  10. +
  11. Write just enough material to get from one assessment (exercise) to +another.

  12. +
  13. Describe the course so the learners know if it is relevant to them.

  14. +
+
+
+
+

Improving existing lessons

+
+

All CodeRefinery lessons are on GitHub

+ +
+

Collect feedback during the workshop:

+
    +
  • Collect feedback from learners and instructors (Example from a past +workshop).

  • +
  • Convert feedback about lessons and suggestions for improvements into issues +so that these don’t get lost and stay close to the lesson material.

  • +
+

Collect feedback before you start a big rewrite:

+
    +
  • First open an issue and describe your idea and collect feedback before you +start with an extensive rewrite.

  • +
  • For things still under construction, open a draft pull/merge request to collect +feedback and to signal to others what you are working on.

  • +
+

Small picture changes vs. big picture changes:

+
    +
  • Lesson changes should be accompanied with instructor guide changes (it’s like +a documentation for the lesson material).

  • +
  • Instructor guide is essential for new instructors.

  • +
  • Before making larger changes, talk with somebody and discuss these changes.

  • +
+
+
+

Use case: our lessons

+

As an example to demonstrate the process of designing and improving lessons, we +will have a look at one of our own lessons: Introduction to version control +with Git.

+
    +
  • Initial 2014-2016 version

    + +
  • +
  • Some time in 2014-2015 attended Carpentries instructor training.

  • +
  • 2016: CodeRefinery started.

  • +
  • 2017: Started a new repository based on the Carpentries lesson template (at the time using Jekyll).

    +
      +
    • Exercises become part of the lesson.

    • +
    • We start in the command line and only later move to GitHub.

    • +
    +
  • +
  • 2019: A lot more thought about learning objectives and personas.

    +
      +
    • Also license change to CC-BY.

    • +
    +
  • +
  • 2022: Convert lesson from Jekyll to Sphinx.

    +
      +
    • Using the tools that we teach/advocate.

    • +
    • We can have tabs and better code highlighting/emphasis.

    • +
    • Easier local preview (Python environment instead of Ruby environment which we were not used to in our daily work).

    • +
    +
  • +
  • 2024: Big redesign. We move the lesson closer to where learners are.

    +
      +
    • Start from GitHub instead of on the command line.

    • +
    • Start from an existing repository instead of with an empty one.

    • +
    • Offer several tracks to participate in the lesson (GitHub, VS Code, and command line) and learners can choose which one they want to follow.

    • +
    • Blog post: We have completely changed our Git lessons. Hopefully to the better.

    • +
    +
  • +
  • Next steps?

    +
      +
    • Making the lesson citable following +our blog post.

    • +
    • Improvements based on what we learn from this workshop.

    • +
    +
  • +
+

The overarching trend was to make the lesson simpler and more accessible - to +meet the learners where they are instead of pulling them to the tool choices of +the instructors. Looking back, we learned a lot and the learning process is +not over yet.

+
+
+

Exercise: Discussion about learning objectives and exercise design

+
+

We work in groups but use the shared document as result (20 min)

+
    +
  1. As a group pick a lesson topic. It can be one of the topics listed here but +you can also choose something else that your group is interested in, or a topic +that you have taught before or would like to teach. Some suggestions:

    +
      +
    • Git: Creating a repository and porting your project to Git and GitHub

    • +
    • Git: Basic commands

    • +
    • Git: Branching and merging

    • +
    • Git: Recovering from typical mistakes

    • +
    • Code documentation

    • +
    • Jupyter Notebooks

    • +
    • Collaboration using Git and GitHub/GitLab

    • +
    • Using GitHub without the command line

    • +
    • Project organization

    • +
    • Automated testing

    • +
    • Data transfer

    • +
    • Data management and versioning

    • +
    • Code quality and good practices

    • +
    • Modular code development

    • +
    • How to release and publish your code

    • +
    • How to document and track code dependencies

    • +
    • Recording environments in containers

    • +
    • Profiling memory and CPU usage

    • +
    • Strategies for parallelization

    • +
    • Conda environments

    • +
    • Data processing using workflow managers

    • +
    • Regular expressions

    • +
    • Making papers in LaTeX

    • +
    • Making figures in your favorite programming language

    • +
    • Linux shell basics

    • +
    • Something non-technical, such as painting a room

    • +
    • Introduction to high-performance computing

    • +
    • A lesson you always wanted to teach

    • +
    • +
    +
  2. +
  3. Try to define 2-3 learning objectives for the lesson and write them down. +You can think of these as “three simple enough messages that someone will +remember the next day” - they need to be pretty simple.

  4. +
  5. Can you come up with one or two engaging exercises that could be used to +demonstrate one of those objectives? +They should be simple enough people can actually do them. Creating simple exercises is not easy. +Some standard exercise types:

    +
      +
    • Multiple choice (easy to get feedback via a classroom tool - try to design each wrong answer so that it identifies a specific misconception).

    • +
    • Code yourself (traditional programming)

    • +
    • Code yourself + multiple choice to see what the answer is (allows you to get feedback)

    • +
    • Inverted coding (given code, have to debug)

    • +
    • Parsons problems (working solution but lines in random order, learner must only put in proper order)

    • +
    • Fill in the blank

    • +
    • Discussions, self directed learning exercises

    • +
    +
  6. +
+
+
+
+

Great resources

+ +
+
+
+

Lessons with version control

+
+

Objectives

+
    +
  • Understand why version control is useful even for teaching material

  • +
  • Understand how version control managed lessons can be modified.

  • +
  • Understand how the CodeRefinery lesson template is used to create new lessons

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 25 min

  • +
  • Exercises or demos: 20 min

  • +
+
+
+

Why version control?

+
    +
  • If you are in CodeRefinery TTT, you probably know what version +control is and why it is important.

  • +
  • The benefits of version control also extend to lessons:

    +
      +
    • Change history

    • +
    • Others can submit contributions

    • +
    • Others can make derived versions and sync up later

    • +
    • Same workflow as everything else

    • +
    • Write it like documentation: probably more reading after than +watching it as a presentation.

    • +
    +
  • +
  • Disadvantages

    +
      +
    • “What you see is what you get” editing is hard

    • +
    • Requires knowing version control

    • +
    +
  • +
+
+

Accepting the smallest contribution

+

Question: if someone wants to make a tiny fix to your material, can they?

+
+
+
+

Tour of lesson templates options

+

There are different ways to make lessons with git. Some dedicated to +teaching:

+ +

Our philosophy is that anything works: it doesn’t have to be just +designed for lessons

+
    +
  • Jupyter Book

    +
      +
    • Example: https://jupyterbook.org/

    • +
    • Note: is based on sphinx, many extensions here are used in CR lessons

    • +
    +
  • +
  • Various ways to make slides out of Markdown

  • +
  • Cicero: GitHub-hosted Markdown to slides easily

    + +
  • +
  • Whatever your existing documentation is.

  • +
+

We like the CodeRefinery format, but think that you should use +whatever fits your needs the most.

+
+
+

Sphinx

+
    +
  • We build all our lesson material with Sphinx

  • +
  • Generate HTML/PDF/LaTeX from RST and Markdown.

  • +
  • Many Python projects use Sphinx for documentation but Sphinx is not limited to Python.

  • +
  • Read the docs hosts public Sphinx documentation for free!

  • +
  • Also hostable anywhere else, like Github pages, like our lesson material

  • +
  • For code a selling point for Sphinx is that also API documentation +is possible.

  • +
+

Sphinx is a doc generator, not HTML generator. It can:

+
    +
  • Markdown, Jupyter, and ReST (and more…) inputs. Executable inputs.

    +
      +
    • jupyter-book is Sphinx, so anything it can do we can do. This was one of the +inspirations for using Sphinx

    • +
    +
  • +
  • Good support for inline code. Much more than static code display, if +you want to look at extensions.

  • +
  • Generate different output formats (html, single-page html, pdf, epub, etc.)

  • +
  • Strong cross-referencing within and between projects

  • +
+
+
+

CodeRefinery lesson template

+

It is “just a normal Sphinx project” - with extensions:

+
    +
  • Sphinx lesson extension

    +
      +
    • adds is various directives (boxes) tuned to lesson purposes

    • +
    • provides a sample organization and template repo you can use so that lessons look consistent

    • +
    +
  • +
  • Sphinx gives us other nice features for free

    +
      +
    • Tabs: they are very important for us and allow us to customize in-place instead of copying everything and fragmenting lessons

    • +
    • Emphasize lines: they make it easier to spot what has changed in longer code snippets

    • +
    • Various input formats

      +
        +
      • Markdown (via the MyST-parser), ReStructured text, Jupyter +Notebooks.

      • +
      +
    • +
    • Many other features designed for presenting and interacting with code

    • +
    +
  • +
  • It’s fine if you use some other static site generator or git-based lesson method.

  • +
+
+

Instructors go through the building and contributing process

+

Depending on the course, instructors will demo what is roughly +exercise 4 below. Or a course might go straight to exercises.

+
    +
  • Instructors decide what change they would want to make

  • +
  • Instructors clone the repository

  • +
  • Instructors make the change

  • +
  • Instructors set up the build environment

  • +
  • Instructors build and preview

  • +
  • Instructors command and send upstream

  • +
+
+
+
+

Exercises

+

Some exercises have prerequisites (Git or Github accounts). Most +instances of this course will have you do 1 and 2 below.

+
+

Lesson-VCS-1: Present and discuss your own lesson formats

+

We don’t want to push everyone towards one format, but as long as you +use Git, it’s easy to share and reuse.

+
    +
  • Discuss what formats you do use

  • +
  • Within your team, show examples of the lessons formats you use +now. Discuss what is good and to-be-improved about them.

  • +
  • Look at how they source is managed and how easy it might be to edit.

  • +
+
+
+

Lesson-VCS-2: Tour a CodeRefinery or Carpentries lesson on Github

+
    +
  • Look at either a CodeRefinery or Carpentries lesson

    + +
  • +
  • Can you find

    +
      +
    • Where is the content of the lessons?

    • +
    • What recent change propsals (pull requests) have been made?

    • +
    • What are the open issues?

    • +
    • How you would contribute something?

    • +
    • How would you use this yourself?

    • +
    +
  • +
+
+
+

Lesson-VCS-3: Modify a CodeRefinery example lesson on Github

+

In this, you will make a change to a lesson on Github, using only the +Github interface. (Github account required, and we assume some +knowledge of Github. Ask for help in your team if it is new to you!)

+
    +
  • Navigate to the example lesson we have set up: +repo, web

  • +
  • Go to some page and follow the link to go to the respective page on +Github. (Alternatively, you can find the page from the Github repo directly).

  • +
  • Follow the Github flow to make a change, and open a Pull Request +with the change proposal:

    +
      +
    • Click on the pencil icon

    • +
    • Make a change

    • +
    • Follow the flow to make a commit and change. You’ll fork the +repository to make your own copy, add a message, and open a pull +request.

    • +
    +
  • +
+

We will look at these together and accept some changes.

+
+
+

Lesson-VCS-4: Clone and build a CodeRefinery lesson locally

+

In this exercise, you will use Git to clone one a CodeRefinery lesson +and try to preview it locally. It assumes installation and knowledge +of Git.

+
    +
  • Use this sample repository: +git-intro (or whatever +else you would like)

  • +
  • Clone the repository to your own computer

  • +
  • Create a virtual environment using the requirements.txt +contained within the repository.

  • +
  • Build the lesson.

    +
      +
    • Most people will probably run: sphinx-build content/ _build/

    • +
    • If you have make installed you can make html

    • +
    • Look in the _build directory for the built HTML files.

    • +
    +
  • +
+

Overall, this is pretty easy and straightforward, if you have a Python +environment set up. The CodeRefinery documentation +lesson teaches +this for every operating system.

+

This same tool can be used to build documentation for other software +projects and is pretty standard.

+
+
+

Lesson-VCS-5: (advanced) Create your own lesson using the CodeRefinery format

+

In this lesson, you’ll copy the CodeRefinery template and do basic +modifications for your own lesson.

+
    +
  • Clone the lesson template: +https://github.com/coderefinery/sphinx-lesson-template

  • +
  • Attempt to build it as it is (see the previous exercise)

  • +
  • How can you do tabs?

  • +
  • How can you highlight lines in code boxes?

  • +
  • How can you change color, logo and fonts?

  • +
  • What directives are available?

  • +
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Version control takes teaching materials to the next level: +shareable and easy to contribute

  • +
  • There are different formats that use version control, but we like +Sphinx with a sphinx-lesson extension.

  • +
+
+
+
+
+

How we collect feedback and measure impact

+
+

Objectives

+
    +
  • Discuss how one can collect feedback from learners (“what can we improve?”).

  • +
  • Discuss how we convert feedback into actionable items.

  • +
  • Discuss how we measure the impact of teaching (“did we achieve our goals?”).

  • +
  • Discuss the “why”.

  • +
  • Get to know the reasons and sources of inspiration behind major lesson and workshop updates.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 20 min

  • +
  • Exercises: 10 min

  • +
+
+
+

Asking questions before the workshop

+ +
+
+

Collecting feedback as we teach

+
    +
  • Each day we ask for feedback in the collaborative notes.

    +
      +
    • One good thing about today.

    • +
    • One thing to improve for next time.

    • +
    • Any other comments?

    • +
    +
  • +
  • During the workshop we sometimes check in and ask about the pace, example:

    +
    How is the speed so far? (add an "o")
    +- Too fast:   oooooo
    +- Too slow:   ooo
    +- Just right: ooooooooooooooooooo
    +
    +
    +
  • +
  • We publish all questions, answers, and feedback. Example: https://coderefinery.github.io/2024-03-12-workshop/questions/

  • +
  • How we follow up:

    +
      +
    • Some problems we can fix already before the next workshop day.

    • +
    • We convert feedback/problems into GitHub issues and track these close to the lesson material.

    • +
    +
  • +
+
+
+

Trying to measure impact with longer-term surveys

+ +
+
+

Lessons learned

+
    +
  • Think about how to measure impact/success from the beginning.

  • +
  • Make the feedback and survey results public.

  • +
  • Make the results persistent and citable.

  • +
  • Have a mechanism to follow-up on feedback.

  • +
  • Anonymization is more than just removing or dissociating names.

  • +
  • Take time designing your survey and collect feedback on the survey itself.

  • +
+
+
+

Take time designing your survey

+

We are not experts in survey design but we reached out to RISE Research +Institutes of Sweden to get feedback on our survey questions. They provided us +with a lot of valuable feedback and suggestions for improvements. +Below are few examples.

+
+

Example 1

+

First version of our survey question about impact:

+
    +
  • “Do our workshops help to save time in future?” Please quantify in hours saved: …

  • +
+

Feedback:

+
    +
  • Difficult to answer.

  • +
  • Since when? Until all eternity?

  • +
+
+Screenshot of earlier version of the survey question about impact. +
+

Earlier version of the survey question about impact.

+
+
+

Feedback:

+
    +
  • The question “Do our workshops help to save time in future?” is unspecified, +unnecessary, and leading.

  • +
  • “No time saving” does not match the wording “save time” in the question.

  • +
+
+Screenshot of later version of the survey question about impact. +
+

Later version of the survey question about impact.

+
+
+
    +
  • The wording “have you saved” now matches “No time saved”.

  • +
+
+
+

Example 2

+
    +
  • Earlier version:

    +
    Would you judge your code to be better reusable/reproducible/modular/documented
    +as a result of attending the workshop?
    +
    +- More reusable
    +- More reproducible
    +- More modular
    +- Better documented
    +- None of the above
    +
    +
    +
  • +
  • Feedback: The question is not neutrally formulated and risks leading to +over-reporting of yes answers. Consider balancing so that the questions are +formulated more neutrally.

  • +
  • Reformulated to:

    +
    After attending the workshop, would you judge your code to be
    +more reusable or not more reusable?
    +
    +- My code is more reusable
    +- My code is not more reusable
    +- Not sure
    +
    +
    +
  • +
+
+
+

Example 3

+
    +
  • Early version:

    +
    What else has changed in how you write code since attending the workshop?
    +
    +[free-form text field]
    +
    +
    +
  • +
  • Feedback: Leading and assumes that something has changed.

  • +
  • Reformulated to:

    +
    Has anything else changed in how you write code for your research after
    +attending the workshop?
    +
    +[free-form text field]
    +
    +
    +
  • +
+
+
+

Example 4

+
    +
  • Earlier version:

    +
    Has it become easier for you to collaborate on software development with your
    +colleagues and collaborators?
    +
    +- Yes
    +- Not sure
    +- No
    +
    +
    +
  • +
  • Feedback:

    +
      +
    • Leading question.

    • +
    • Avoid “Yes” and “No” response options because respondents tend to answer +“Yes” if that option is available, leading to a risk of measurement error +(acquiescence bias).

    • +
    • Do not place “Not sure” in the middle of the scale because it captures +participants who actually don’t know and should therefore be placed at the +bottom instead of in the middle of the scale.

    • +
    +
  • +
  • Reformulated to:

    +
    After attending the workshop, has it become easier or not for you to
    +collaborate on software development with your colleagues and collaborators?
    +
    +- Collaboration is easier
    +- Collaboration is not easier
    +- Not sure
    +
    +
    +
  • +
+
+
+
+

Exercise: Group discussion (10 min)

+
+

Group discussion using the collaborative notes

+
    +
  • What tricks/techniques have you tried in your teaching or seen in someone +else’s teaching that you think have been particularly effective in collecting +feedback from learners?

  • +
  • Can you give tips or share your experiences about how to convert feedback +into actionable items?

  • +
  • How do you measure the impact of your teaching? Any tips or experiences about +what you have tried or seen other courses do?

  • +
  • Anybody knows of good resources on survey design? Please link them in +the collaborative notes.

  • +
+
+
+
+
+
+
+

About the CodeRefinery project and CodeRefinery workshops in general

+
+

Objectives

+
    +
  • Discuss what CodeRefinery is and how we got here

  • +
  • Understand about the challenges to define our target audience

  • +
+
+

CodeRefinery is a +Nordic e-Infrastructure Collaboration (NeIC) +project that has started in October 2016 and is currently +funded until February 2025. We are working on the continuation plans.

+

The funding from 2022-2025 is designed to keep this project active +beyond 2025 by forming a support network and building a community of +instructors and contributors.

+
+

History

+

The CodeRefinery project idea grew out of two SeSE courses given at KTH Stockholm in 2014 and 2016. +The project proposal itself was submitted to NeIC in 2015, accepted in 2015, and started in 2016.

+

We have started by porting own lessons to the Carpentries teaching style and +format, and collaboratively and iteratively grew and improved the material to +its present form.

+
+
+

Goals

+
    +
  • Develop and maintain training material on good enough software development practices for researchers that write code/scripts/notebooks.

  • +
  • Our material addresses all academic disciplines and tries to be as programming language-independent as possible.

  • +
  • Provide a code repository hosting service that is open and free +for all researchers based in universities and research institutes from Nordic countries.

  • +
  • Provide training opportunities in the Nordics using (Carpentries and) CodeRefinery training materials.

  • +
  • Evolve the project towards a community-driven project with a network of instructors and contributors.

  • +
+
+
+

Community

+
+_images/community.png +
+

Image showing the key areas of the CodeRefinery community: Workshops, chat inlcuding help channel, online meetings and co-working, +other collaborative training, eg on High Performance Computing topics.

+
+
+

CodeRefinery is not just workshops, we are community and want you to be part of it!

+

There are many different levels of involvement, from the occasional commenter in chat, +CodeRefinery ambassador (people who like the project and workshops and help us spreading the word) or lesson issue creators and lesson contributors to +local host, co-instructor or co-organizer.

+

Best first step in any case is to join the CodeRefinery Zulip chat +or let us know about your interest at support@coderefinery.org.

+
+
+

Target audience

+

One common question we get is how do we relate to the Carpentries. +This section describes how we see it:

+
+

Carpentries audience

+

The Carpentries aims to teach computational competence to learners through an applied approach, +avoiding the theoretical and general in favor of the practical and specific.

+

Mostly, learners do not need to have any prior experience in programming. +One major goal of a Carpentries workshop is to raise awareness on the tools researchers can learn/use to speed up their research.

+

By showing learners how to solve specific problems with specific tools and providing hands-on practice, +learners develops confidence for future learning.

+
+

Novices

+

We often qualify Carpentries learners as novices: they do not know what they need to learn yet. +A typical example is the usage of version control: the Carpentries lesson +Version Control with Git +aims to give a +very high level conceptual overview of Git but it does not explain how it can be used in research projects.

+
+
+
+

CodeRefinery audience

+

In that sense, CodeRefinery workshops differ from Carpentries workshops as we assume +our audience already writes code and scripts and we aim at teaching them best software practices.

+

Our learners usually do not have a good overview of best software practices but are aware of the need to learn them. +Very often, they know of the tools (Git, Jupyter, etc.) we are teaching +but have difficulties to make the best use of them in their software development workflow.

+

Whenever we can, we direct learners that do not have sufficient coding experience to Carpentries workshops.

+
+

Competent practitioners

+

We often qualify CodeRefinery learners as competent practitioners because they already have an understanding of their needs.

+
+ +
+
+

Keypoints: CodeRefinery

+
    +
  • Teaches intermediate-level software development tool lessons

  • +
  • It is difficult to define “best practices”, we try to teach “good enough” practices

  • +
  • Training network for other lessons

  • +
  • Publicly-funded discrete projects (3 projects actually) transitioning towards an open community project

  • +
  • We have online material, teaching, and exercise sessions

  • +
  • Our main target audience are competent practitioners, but also novices and experts can get something out of the workshops

  • +
  • We want more people to work with us, and to work with more people

  • +
+
+
+
+
+
+

Collaborative notes

+
+

Objectives

+
    +
  • Be able to provide a highly interactive online workshop environment with collaborative documents

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Exercise: 15 min

  • +
  • Questions & Answers: 5 min

  • +
+
+
+

Introduction

+

The Collaborative document is how you interact with the participants. +The participants can ask questions and give feedback through the collaborative +document. During a CodeRefinery session there can be a large a volume of questions. +A dedicated person, a Collaborative document-manager, is needed to answer and edit the collaborative document. +Let us see how the collaborative document is used, then discuss the role of +the editor or collaborative document-manager.

+
+
+

Collaborative document mechanics and controls

+

Technologies that can be used as a collaborative document are Hackmd, HedgeDoc, +or Google Docs

+

Hackmd or HedgeDoc are real-time text editor online. We use it to:

+
    +
  • As a threaded chat, to answer questions and provide other information without +interrupting the main flow of the room.

  • +
  • provide everyone with a more equal opportunity to ask questions.

  • +
  • create notes which will be archived, for your later reference.

  • +
+

You do not need to login/create an account to be able to edit the document.

+
+

Basic controls

+
+_images/hackmd--controls.png +
+

This may look slightly different on mobile devices and small windows.

+
+
+
    +
  • At the top (left or right), you can switch between view, +edit, and split view and edit modes.

  • +
  • You write in markdown here. Don’t +worry about the syntax, just see what others do and try to be like +that! Someone will come and fix any problems there may be.

  • +
  • Please go back to view mode if you think you won’t edit for a +while - it will still live update.

  • +
+
+
+

Asking questions

+

Always ask questions and add new sections at the very bottom. +You can also answer and comment on older questions, too.

+
+_images/hackmd--questions2.png +
+

Questions and answers in bullet points

+
+
+

Since we plan to publish the questions and answers later as part +of the workshop page, we recommend to not use any names. You can indicate +your own name to make it easier to discuss more during the workshop but +then always use this form: [name=Myname]. This makes it easier for +us to automatically remove all names before publishing the notes.

+

Other hints:

+
    +
  • Use +1 to agree with a statement or question (we are more likely +to comment on it).

  • +
  • Please leave some blank lines at the bottom

  • +
  • NOTE: Please don’t “select all”, it highlights for everyone and adds a +risk of losing data (there are periodic backups, but not instant).

  • +
  • It can be quite demanding to follow the collaborative document closely. Keep an eye +on it, but consider how distracted you may get from the course. For +things beyond the scope of the course, we may come back and answer +later.

  • +
+
+
+

Don’t get overwhelmed

+

There can be a flood of information on the collaborative document. Scan for what is +important, then if you would like come back later. But it is +important to keep checking it.

+
+
+

Privacy

+
    +
  • Assume the collaborative document is public and published: you never +need to put your name there.

  • +
  • The collaborative document will be published on the website afterwards. We will +remove all non-instructors names, but it’s easier if you don’t add +it there in the first place.

  • +
  • Please keep the link private during the workshop, since since +security is “editable by those who have the link”.

  • +
  • You can use [name=YOURNAME], to name yourself. We will remove +all names (but not the comments) before archiving the notes (use +this format to make it easy for us).

  • +
+
+
+
+

Exercise

+
+

Discuss how to collaborate and handle questions (15 min)

+

Write down your conclusions in the shared document. Items to discuss are:

+
    +
  • What is your experience with questions and discussions while teaching?

  • +
  • How do you deal with them?

  • +
  • What kind of technologies do you prefer: chat, shared document, or voices +and discussion raised during instruction? And why?

  • +
+
+
+
+

Collaborative Document Manager

+

We have one person who is a “Collaborative Document helper”. This isn’t the only +person that should edit and answer, but one person shouldn’t have too +much else on their mind so can focus on it. They also make sure that +the collaborative document is updated with exercise, break, and other meta-information to +keep people on track.

+

Below, (*) = important.

+
+

Before the workshop

+
    +
  • Create a new collaborative document for the workshop

  • +
  • make sure that editing is enabled for anyone without login

  • +
  • Add workshop information, links to the workshop page and material +and an example question and answer to the top of the collaborative document(see below)

  • +
+
+
+

Most things to edit (everyone)

+

Make it easy to post after the course and consistent to follow:

+
    +
  • Tag all names with [name=XXX] (so they can be removed later), +remove other personal data or make it obvious.

  • +
  • Add in information on exercises (new section for them, link, end +time, what to accomplish)

  • +
  • Make a logical section structure (# for title, ## for sections, +### for episodes, etc. - or what makes sense)

  • +
+
+
+

General Collaborative Document practices

+
+_images/hackmd--full-demo.png +
+

A live demo of a Collaborative Document during a Q&A time. The two instructors are +discussing some of the import answers. Multiple learners have asked +questions, multiple answers, and some remaining to be answered

+
+
+

Keep it formatted well:

+
    +
  • (*) Tag names you see with [name=XXX] so that we can remove it +later.

  • +
  • Heading level # is only the page title

  • +
  • Add a new ## heading when a new lesson or similar thing is +started (introduction, icebreaker, break between lessons, etc)

  • +
  • Add a new ### heading when a new episode, exercise, break +(within exercise session)

  • +
  • Ensure people are asking questions at the bottom, direct them there +if they aren’t.

  • +
  • (*) Ensure each question is a bullet point. Each answer or follow-up +should be a bullet point below.

    +
      +
    • Should you use more deeply nested bullet points, or have only one +level below the initial question? It depends on the context, but +if a conversation goes on too long, try not to let it go too +deep.

    • +
    +
  • +
+

Update with meta-talk, so that learners can follow along easily:

+
    +
  • Add Icebreaker and introductory material of the day. Try to talk to +people as they joined to get them to open the collaborative document and answer.

  • +
  • Anything important for following along should not be only said via +voice. It needs to be in the collaborative document, too.

  • +
  • New lessons or episodes, with links to them.

  • +
  • For exercises, link to exercise and add the duration, end time, +goals. If these are unclear, bring it up to the instructor by voice.

  • +
  • Add a status display about breaks.

  • +
+

Screenshare it when necessary:

+
    +
  • During breaks and other times, share the collaborative document(including the +notification about break, and when it ends).

  • +
  • It is nice if the arrangement allows some of the latest questions to +be seen, so people are reminded to ask there.

  • +
  • Someone else may do this, but should make sure it happens.

  • +
+

Answer questions

+
    +
  • If there is an question that should be answered by the instructor by +voice, bring it up (by voice) to the instructor immediately.

  • +
  • How soon do you answer questions? Two points of view:

    +
      +
    • Answer questions right away: can be really intense to follow.

    • +
    • Wait some so that we don’t overload learners: reduces the info +flow. But then do people need to check back more often.

    • +
    • You need to find your own balance. Maybe a quick answer right +away, and more detailed later. Or delay answers during the most +important parts of the lecture.

    • +
    +
  • +
  • Avoid wall-of-text answers. If reading an answer takes too long, it +puts the person (and other people who even try to read it) behind +even more by taking up valuable mental energy. If an answer needs a +wall of text, consider these alternatives:

    +
      +
    • Progressive bullet points getting more detailed (first ones +useful alone for basic cases)

    • +
    • Don’t be worried to say “don’t worry about this now, let’s talk +later.”

    • +
    • Figure out the root problem instead of answering every possible +interpretation

    • +
    • Declare it advanced and that you will come back later.

    • +
    +
  • +
+

Ensure it can be posted quickly:

+
    +
  • The collaborative document gets posted to the workshop webpage. For this, it needs some +minimal amount of formatting (it doesn’t need to be perfect, just +not horrible).

  • +
  • All names and private information needs to be stripped. This is why +you should rigorously tag all names with [name=XXX] so they can be +removed (see above).

    +
      +
    • Learner names can be completely removed. CR staff names can be +[name=CR] or something similar.

    • +
    • There may be other private URLs at the top or bottom.

    • +
    +
  • +
  • If possible, send the PR adding the collaborative document to the workshop webpage +(though others can do this, too).

  • +
+
+
+

Collaborative document format example

+
# Workshop, day 1
+
+
+## Lesson name
+https://coderefinery.github.io/lesson/
+
+### Episode name
+https://coderefinery.github.io/01-episode/
+
+- This is a question
+  - Anwser
+  - More detailed answer
+- question
+  - answer
+
+### Exercises:
+https://link-to-exercise/.../.../#section
+20 minutes, until xx:45
+Try to accomplish all of points 1-3.  Parts 4-5 are optional.
+
+Breakout room status:
+- room 2, need help with Linux permissions
+- room 5, done
+
+### Break
+:::danger
+We are on a 10 minute break until xx:10
+:::
+
+
+## Lesson 2
+https://coderefinery.github.io/lesson-2/
+
+
+
+
+
+

Posting the collaborative document to the website

+

The collaborative document should be posted sooner rather than later, and hopefully the +steps above will make it easy to do so quickly. You could wait a few +hours, to allow any remaining questions to be asked an answered.

+
    +
  • Download as markdown

  • +
  • Remove any private links at the top

  • +
  • Adjust headings so that they are reasonable

  • +
  • Look for private info and remove it

    +
      +
    • Search document for [name=???] (change to [name=staff] or +[name=learner])

    • +
    • Any names not tagged with [name=]

    • +
    • usernames in URLs

    • +
    • private links

    • +
    +
  • +
+
+
+

Feedback template

+
## Feedback, day N
+
+:::info
+### News for day N+1
+- .
+- .
+:::
+
+### Today was (multi-answer):
+- too fast: 
+- just right: 
+- too slow: 
+- too easy: 
+- right level: 
+- too advanced: 
+- I would recommend this course to others: 
+- Exercises were good: 
+- I would recommend today to others: 
+- I wouldn't recommend today: 
+
+### One good thing about today:
+- ...
+- ...
+
+### One thing to be improved for next time:
+- ...
+- ...
+
+### Any other comments:
+- ...
+- ...
+
+
+
+

Keypoints

+
    +
  • Having a collaborative document improves communication and interaction.

  • +
  • Answering questions requires a dedicated person - A Collaborative Document Manager.

  • +
  • The collaborative document should be posted on the web site as soon as possible.

  • +
+
+
+
+
+
+

A workshop seen from different perspectives

+
+

Objectives

+
    +
  • Understand the general structure of CodeRefinery workshops and why it is the way it is

  • +
  • Get to know the different roles of a workshop and which ones are the most essential ones

  • +
  • Understand the importance of installation instructions and how they contribute to learners success

  • +
  • Understand the importance of onboarding and a welcoming community for volunteers in a workshop

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 15 min

  • +
  • Roles journeys can be shortened to looking only at instructor role.

  • +
+
+
+

Note

+

This episode focuses on the large scale streamed workshop setup. Some of the features can also be applied to smaller scale workshops though.

+
+
+

Discussion

+
+

Discussion

+

In breakoutrooms: choose one or two questions to talk about your own experiences; summary in collaborative notes:

+
    +
  • What kind of roles have you been in yourself regarding workshops?

  • +
  • How were you prepared for your role?

  • +
  • What are the things you would like to know before a workshop?

  • +
  • How are you preparing your participants for your trainings?

  • +
  • What was the best workshop experience for you as learner, helper or instructor? What made it great?

  • +
+
+
+
+

One workshop - many parts

+
+_images/CR_workshop_setup.png +
+

Image showing the different phases of a CodeRefinery workshop described below. Also showing that while there is only two people teaching, many people work behind the scenes.

+
+
+
+

Before the workshop

+
    +
  • During winter/summer: “Someone” takes the coordinator role for the next workshop

  • +
  • Coordinator fills other roles:

    +
      +
    • Coordinator: collects necessary lesson updates, supports other coordinators

    • +
    • Registration coordinator: Sets up web page, starts and manages registration

    • +
    • Instructor coordinator: Finds instructors and onboards them

    • +
    • Advertising coordinator: Prepares advertizement texts and finds people to distribute them

    • +
    • Team coordinator: Gathers local organizers/teams

    • +
    • Bring your own code session coordinator: If available, offer BYOC session after main workshop

    • +
    +
  • +
  • Instructor: Onboarding with (instructor-) coordinator and previous instructor of lesson; update of lesson materials (urgent issues and personal touches)

  • +
  • Local organizer/Team lead: Group onboarding ~ week/or two before workshop

  • +
  • Learner: Gets installation instructions, invited to installation help session, workshop info from event page and summary via e-mail

  • +
  • Collaborative notes manager sets up the notes document

  • +
+
+

Note

+

Onboarding manuals

+
    +
  • Outline of what will happen during the workshop

  • +
  • Discussion of different strategies to handle the exercise sessions

  • +
  • Lowering the barrier to ask for support by meeting some organizers

  • +
  • Q&A

  • +
+
+
+

Note

+

Installation instructions

+
    +
  • Instructions for all operating systems

  • +
  • Goal: Learners leave the workshop and are ready to apply the learned tools and techniques to their own work

  • +
  • Support session for installation challenges

  • +
+
+
+
+

During the workshop

+
+_images/BYOC.png +
+

Image showing the different ways learners can do the exercises. No matter which way they choose, they always watch the stream and interact with instructors and organizers via collaborative notes. Individual learners do the exercises alone, people in online or local classrooms in addition get to discuss with their peers.

+
+
+
    +
  • Everyone watches stream

  • +
  • Co-instructors +- Present content +- Answer questions in collaborative notes

  • +
  • Collaborative notes manager

    +
      +
    • Keeps the collaborative notes clean

    • +
    • Helps answering questions

    • +
    • Adds sections

    • +
    • Archives the document after each day

    • +
    +
  • +
  • Learners do exercises individually or in team

  • +
  • Local organizer / Team lead

    +
      +
    • Guides learners through exercises

    • +
    • Facilitates discussion

    • +
    +
  • +
  • (Registration-) coordinator sends out e-mails to participants after each day (summary + preparation)

  • +
  • Director/Broadcaster manages the streaming (see session 4)

  • +
+
+
+

After the workshop

+
    +
  • Coordinator collects lessons learned based on experience and feedback and turns them into issues

  • +
  • Coordinator organizes debriefing week after the workshop, where anyone can join to give feedback

  • +
  • “Someone” sends out post-workshop survey half a year after workshop

  • +
  • Coordinator organizes “Bring your own code” sessions

  • +
  • Broadcaster prepares and shares recording (see session 4)

  • +
+
+

Note

+

Bring your own code sessions

+

We want to support learners to apply what they have learned in the workshop to their own work by offering one/two sessions where they can drop in, and discuss challenges with CodeRefinery instructors and helpers.

+
+_images/welcome.png +
+

Image showing a classroom learning about git leading to a discussion between student and teacher to start a welcoming environment for asking for help.

+
+
+
+
+
+
+

This sounds like a lot of people and time investment!

+
    +
  • Many roles can be combined or adjusted as needed

  • +
  • Some roles can be taken on by multiple people

  • +
+

So how many people are needed for this kind of workshop?

+
    +
  • Recommended minimum: 2-3 people

  • +
  • Optimum: ~ 4-5 people +The more people you involve, the more time goes into coordination work.

  • +
+
+
+

How did we get to this setup?

+
    +
  • Collaborative in-person workshops since 2016 around the Nordics

  • +
  • Moved online in 2020

  • +
  • Started with “traditional zoom” workshops, breakoutrooms, volunteer helpers

  • +
  • Thought about scaling and ease of joining -> current setup (More about this in session 4)

  • +
  • Continuous development

  • +
+

We also still do smaller scale local workshops, if instructors are available. +You can offer your own CodeRefinery workshop by inviting other CodeRefinery instructors. +You can also reuse single lessons and integrate them into your own teaching.

+
+
+

Workshop roles and their journeys

+
+

Individual learner journey

+
    +
  • Registration

  • +
  • Installation

  • +
  • (if appicable: Invited to local meetup)

  • +
  • Workshop

    +
      +
    • Watch stream

    • +
    • Q&A in notes

    • +
    • Exercises alone or in team

    • +
    • Daily feedback

    • +
    +
  • +
  • Debrief/ Feedback session

  • +
  • Post workshop survey

  • +
+
+
+

Instructor journey

+
    +
  • Indicate interest in CodeRefinery chat

  • +
  • Onboarding

  • +
  • Lesson material updates

  • +
  • Teaching

  • +
  • (if wished: supports answering questions in notes)

  • +
  • Debrief

  • +
+
+
+

Team lead / Local host journey

+
    +
  • Registration

  • +
  • (if applicable: run own registration)

  • +
  • Onboarding

  • +
  • Workshop

    +
      +
    • Watch stream

    • +
    • Facilitate exercises/discussions

    • +
    • Daily feedback

    • +
    +
  • +
  • Debrief / feedback / survey

  • +
+
+
+

Other roles

+

Director and broadcaster roles will be discussed in Session 4. +For more in-depth descriptions and other roles (host, instructor, registration coordinator, etc), see also our CodeRefinery manuals.

+
+
+
+

Different roles as stepping stones for community involvement

+
+_images/steps.png +
+

Image showing a person jumping from step to step following learner, helper, expert helper, co-instructor, co-organizer.

+
+
+

There is no “one way” to get involved. Do what feels right. +Interested in teaching with us? Let us know and we can discuss what is a suitable path for you!

+
+

Keypoints

+
    +
  • CodeRefinery workshops are a collaborative effort with many different roles

  • +
  • Onboarding the different roles is one key aspect of our workshops

  • +
  • Everyone has their own path

  • +
+
+
+
+
+

Sound

+
+

Objectives

+
    +
  • Understand that sound quality is very important

  • +
  • Evaluate your and others sound quality and know how to improve it

  • +
  • Test tips and tricks for achieving good sound quality

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Exercises: 10 min

  • +
+
+
+

The importance of audio

+
    +
  • Pleasing audio quality makes events much more enjoyable

  • +
  • Audio is one of the most important things you can control

  • +
  • Things that can go wrong:

    +
      +
    • Too quiet

    • +
    • Too loud

    • +
    • Instructors’ volumes imbalanced

    • +
    • Background noise

    • +
    • Low-quality/breaking up audio hard to hear.

    • +
    • “Ducking” (first words lower volume, or lower volume other times)

    • +
    +
  • +
+
+
+

Tips for good sound quality

+
    +
  • Have a headset with mounted microphone

    +
      +
    • Even if you have a professional external microphone, it doesn’t +matter if your room has bad acoustics.

    • +
    • The close pickup can’t be beat with normal tools.

    • +
    • As long as it’s headset mounted, price doesn’t seem to matter +that much.

    • +
    +
  • +
  • Don’t use Bluetooth

    +
      +
    • Bluetooth can have too much latency (300-500ms)

    • +
    • This may seem small but for interactive work, it’s a lot

    • +
    • Use a wired headset, or wireless with a non-Bluetooth USB plug +(like gaming headsets have). These have much lower latency.

    • +
    • Bluetooth 5 can have much lower latency, but you probably +shouldn’t count on that without testing.

    • +
    • It can also have lower sound quality on some devices due to +bandwidth limitations.

    • +
    +
  • +
  • Once you have a headset, turn input noise cancellation to low +(wherever it might be: headphone, meeting software, etc.).

  • +
+
+
+

Balancing and dynamic adjustment

+
    +
  • It’s important that instructors volumes match.

  • +
  • An exercise will go over a systematic procedure for matching +volumes.

    +
      +
    • Practice so that you can do this quickly.

    • +
    +
  • +
  • May need re-adjusting when instructors swap out or start getting +excited.

  • +
  • An exercise below will demonstrate our procedure.

  • +
+
+
+

Speak up when there are problems

+
    +
  • If you notice someone with audio issues, let them know right away +(voice if bad, or chat/notes if less urgent).

  • +
  • Take the time to fix it as soon as practical.

  • +
  • Make a culture of speaking up, helping, and not suffering.

  • +
+
+
+

Recommendations

+
    +
  • Procure some reasonable headset.

  • +
  • Low/medium-priced gaming-type headsets have worked well for us.

    +
      +
    • (gaming headsets usually aren’t Bluetooth, because gaming needs +low latency.)

    • +
    +
  • +
  • Show this page to your workplace (if you have one) and call a good +headset work equipment.

  • +
+
+
+

Exercises

+
+

Sound-1: Evaluate sound quality

+

It’s important to be able to discuss with others the quality of their +audio. They can’t hear themselves, after all.

+
    +
  • Within the teams, discuss each person’s audio quality and what kind +of setup they have.

  • +
  • Be respectful and constructive (and realize that people came +prepared to listen, not teach).

  • +
  • Consider, for example

    +
      +
    • Volume

    • +
    • Clarity

    • +
    • Background noise

    • +
    • Noise cancellation artifacts

    • +
    • “Ducking”: first words at lower volume or missing

    • +
    +
  • +
  • Discuss how to bring this up during other courses and meetings.

  • +
+
+
+

Sound-2: Adjust volume up and down

+

In addition to individual quality, it is important that sound is +balanced among all instructors. Have you ever been to a event when +one person is too quiet and they can’t make themselves any louder? +And they can’t adjust it?

+

You should ensure that you have a range of volumes available to you. +You might have to look into several different locations in order to +make the full adjustment ().

+
    +
  • Go to your sound settings

  • +
  • One by one, each person

    +
      +
    • Adjusts their microphone volume so quiet that they can’t be heard.

    • +
    • Adjusts their microphone volume so that it is extremely loud (this +may require going beyond 100% if possible).

    • +
    +
  • +
  • Basically, make sure you aren’t so close to either end that you have +no potential to make an adjustment in that direction.

  • +
  • Everyone tries to set the volume to something reasonable, in +preparation for the next exercise.

  • +
+

Once you know where these settings are , you won’t be panicked when the +volume is too low or high during a course.

+
+
+

Sound-3: Do a balance check

+

It’s important that instructor audio is balanced (the same volume). +But how can you do this?

+
    +
  • Pick a leader.

  • +
  • The leader decides the order (“I am first, then [name-1] and +[name-2]”)

  • +
  • The leader says “one”. Everyone else says “one” in the order +specified.

  • +
  • The leader says “two”. Everyone else says “two” in the order.

  • +
  • The leader asks for opinions on who they think is louder or softer. +If there are more than three people, you can figure it out +yourselves. With less than two, you have to ask someone in the +audience.

  • +
+

Example:

+
    +
  • Leader: Let’s do a sound check. I am first, then AAA and BBB.

  • +
  • Leader: One

  • +
  • AAA: One

  • +
  • BBB: One

  • +
  • Leader: Two

  • +
  • AAA: Two

  • +
  • BBB: Two

  • +
  • Leader: Three

  • +
  • AAA: Three

  • +
  • BBB: Three

  • +
  • Leader: How did that sound to everyone?

  • +
  • [Someone else]: Leader and BBB were pretty similar but AAA is a bit +lower.

  • +
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Audio quality is important and one of the most notable parts of the +workshop.

  • +
  • Improving audio isn’t hard or expensive, but does require preparation.

  • +
+
+
+
+
+

How to prepare a quality screen-share

+
+

Objectives

+
    +
  • Discuss the importance of a well planned screen-share.

  • +
  • Learn how to prepare and how to test your screen-share setup.

  • +
  • Know about typical pitfalls and habits to avoid.

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 15 min

  • +
  • Exercises: 15 min

  • +
+
+
+

Share portrait layout instead of sharing entire screen when teaching online

+
    +
  • Many learners will have a smaller screen than you.

  • +
  • You should plan for learners with only one small screen.

  • +
  • A learner will need to focus on both your screen share and their +work.

  • +
  • Share a portrait/vertical half of your screen (840 × 1080 is our standard and your +maximum).

  • +
  • Zoom provides a “Share a part of screen” that is good for this.

    +
      +
    • Our latest streaming setup (day 4) can take the portrait part for +you so you can share landscape.

    • +
    • Zoom + Linux + Wayland display manager doesn’t have “Share a +portion of the screen”

      +
        +
      • You can share a single window portrait.

      • +
      • Or you can start your desktop session in “X11” or “Xorg” legacy +mode.

      • +
      • Or possibly other workarounds (does anyone know other solutions?)

      • +
      +
    • +
    +
  • +
+
+_images/landscape.png +
+

A FullHD 1920x1080 screen shared. Learners have to make this really small if +they want to have something else open.

+
+
+
+_images/portrait.png +
+

Portrait layout. Allows learners to have something else open in the other half.

+
+
+

Motivation for portrait layout:

+
    +
  • This makes it easier for you to look at some other notes or to coordinate +with other instructors at the same time +without distracting with too much information.

  • +
  • This makes it possible for participants to have something else open in the +other screen half: terminal or browser or notebook.

  • +
+
+

Instructor perspective

+
+_images/instructor.png +
+

I1: +This is how it can look for the instructor. Zoom is sharing a portion of the left +side, the right side is free for following notes, chat, etc.

+
+
+
+
+

Learner perspective

+

Here are three examples of how it can look for the learner.

+
+_images/learner-large.png +
+

L1: +Learner with a large screen, Zoom in dual-monitor mode so that the instructor +pictures are not shown. Screen-share is on the left side, collaborative notes +at bottom left, terminal and web browser on the right.

+
+
+
+_images/learner-normal.png +
+

L2: +A learner with a single large screen (Zoom in “single monitor mode”). +Instructor screen share at right, learner stuff at left.

+
+
+
+_images/learner-small.png +
+

L3: +A learner with a particularly small screen. Instructor screen-share at left, +your windows at right.

+
+
+
+
+
+

Share the history of your commands

+

Even if you type slowly it is almost impossible to follow every command. We +all get distracted or want to read up on something or while following a command +fails on the learner laptop while instructor gets no error.

+

Add pauses and share the commands that you have typed so that one can catch up.

+

Below are some examples (some more successful than others) of sharing history +of commands.

+
+_images/history-portrait.png +
+

H1: +A vertical screen layout shared. Note the extra shell history at the top. The +web browser is at the bottom, because the Zoom toolbar can cover the bottom +bit.

+
+
+
+_images/history-rsh.png +
+

H2: +This isn’t a screen-share from CodeRefinery, but may be instructive. Note the +horizontal layout and shell history at the bottom right.

+
+
+
+_images/history-landscape-dark.png +
+

H3: +Similar to above, but dark. Includes contents on the right.

+
+
+
+_images/history-portrait-light.png +
+

H4: +Jupyter + terminal, including the fish shell and the terminal history.

+
+
+
+_images/history-portrait-dark.png +
+

H5: +Lesson + terminal, tmux plus terminal history and dark background.

+
+
+
+_images/portrait.png +
+

H6: +HPC Kickstart course. Note the colors contrast of the windows and colors of +the prompt and text. The history is smaller and doesn’t take up primary +working space. The working directory is in the window title bar.

+
+
+
+https://raw.githubusercontent.com/bast/history-window/main/demo.gif +
+

H7: +Show command history “picture-in-picture”, in the same terminal window.

+
+
+
+
+

How to configure history sharing

+

You need to find a way to show the recent commands you have entered, so that +learners can see the recent commands. Below are many solutions. Try them out +and see what works for you.

+
    +
  • prompt-log: +It adds a interesting idea that the command you enter is in color and also +provides terminal history before the command returns.

  • +
  • Simple: The simple way is PROMPT_COMMAND="history -a" and then +tail -f -n0 ~/.bash_history, but this doesn’t capture ssh, +sub-shells, and only shows the command after it is completed.

  • +
  • Better yet still simple: Many Software Carpentry instructors use +this script, +which sets the prompt, splits the terminal window using tmux and displays command history +in the upper panel. Requirement: tmux

  • +
  • Better (bash): This prints the output before the command is run, +instead of after. Tail with tail -f ~/demos.out.

    +
    BASH_LOG=~/demos.out
    +bash_log_commands () {
    +    # https://superuser.com/questions/175799
    +    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    +    [[ "$PROMPT_COMMAND" =~ "$BASH_COMMAND" ]] && return # don't cause a preexec for $PROMPT_COMMAND
    +    local this_command=`HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"`;
    +    echo "$this_command" >> "$BASH_LOG"
    +}
    +trap 'bash_log_commands' DEBUG
    +
    +
    +
  • +
  • Better (zsh): This works like above, with zsh. Tail with tail -f ~/demos.out.

    +
    preexec() { echo $1 >> ~/demos.out }
    +
    +
    +
  • +
  • Better (fish): This works like above, but for fish. Tail with +tail -f ~/demos.out.

    +
    function cmd_log --on-event fish_preexec ; echo "$argv" >> ~/demos.out  ; end
    +
    +
    +
  • +
  • Better (tmuxp): This will save some typing. +TmuxP is a Python program (pip install tmuxp) that gives you programmable tmux sessions. One configuration that +works (in this case for fish shell):

    +
    session_name: demo
    +windows:
    +  - window_name: demo
    +    layout: main-horizontal
    +    options:
    +      main-pane-height: 7
    +    panes:
    +      - shell_command:
    +          - touch /tmp/demo.history
    +          - tail -f /tmp/demo.history
    +      - shell_command:
    +          - function cmd_log --on-event fish_preexec ; echo "$argv" >> /tmp/demo.history  ; end
    +
    +
    +
  • +
  • Windows PowerShell: In Windows Terminal, +a split can be made by pressing CTRL+SHIFT+=. Then, in one of the splits, the following +PowerShell command will start tracking the shell history:

    +
    Get-Content (Get-PSReadlineOption).HistorySavePath -Wait
    +
    +
    +

    Unfortunately, this only shows commands after they have been executed.

    +
  • +
  • Tavatar: shell history mirroring teaching tool can copy recent history to a remote server.

  • +
  • history-window: Show command +history “picture-in-picture” when teaching command line. Requires Bash.

  • +
+
+
+

Font, colors, and prompt

+
+

Terminal color schemes

+
    +
  • Dark text on light background, not dark theme. Research and our +experience says that dark-text-on-light is better in some cases and +similar in others.

  • +
  • You might want to make the background light grey, to avoid +over-saturating people’s eyes and provide some contrast to the pure +white web browser. (this was an accessibility recommendation when +looking for ideal color schemes)

  • +
  • Do you have any yellows or reds in your prompt or program outputs? +Adjust colors if possible.

  • +
+
+
+

Font size

+
    +
  • Font should be large (a separate history terminal can have a smaller +font).

  • +
  • Be prepared to resize the terminal and font as needed. Find out +the keyboard shortcuts to do this since you will need it.

  • +
+
+
+

Prompt

+

At the beginning of the workshop your goal is to have a shell +as easy to follow as possible and as close to what learners will +see on their screens:

+
    +
  • Your prompt should be minimal: few distractions, and not take up many +columns of text.

  • +
  • prompt-log does +this for you.

  • +
  • The minimum to do is is export PS1='\$ '.

  • +
  • Blank line between entries: export PS1='\n\$ '.

  • +
  • Have a space after the $ or % or whatever prompt character you +use.

  • +
  • Strongly consider the Bash shell. This is what most new people will +use, and Bash will be less confusing to them.

  • +
  • Eliminate menu bars and any other decoration that uses valuable +screen space.

  • +
  • Add colors only if it simplifies the reading of the prompt.

  • +
+

Later in the workshop or in more advanced lessons:

+
    +
  • Using other shells and being more adventurous is OK - learners will +know what is essential to the terminal and what is extra for your +environment.

  • +
+

Try to find a good balance between:

+
    +
  • Showing a simple setup and showing a more realistic setup.

  • +
  • Showing a consistent setup among all instructors and showing a +variety of setups.

  • +
+
+
+
+

Habits we need to un-learn

+
    +
  • Do not clear the terminal. Un-learn CTRL-L or clear if possible. +More people will wonder what +just got lost than are helped by seeing a blank screen. Push +ENTER a few times instead to add some white space.

  • +
  • Do not rapidly switch between windows or navigate quickly between multiple +terminals, browser tabs, etc. This is useful during your own work when nobody +is watching, but it is very hard to follow for learners.

  • +
  • Avoid using aliases or shortcuts that are not part of the +standard setup. Learners probably don’t have them, and they will fail +if they try to follow your typing. Consider even to rename corresponding +files (.bashrc, .gitconfig, .ssh/config, .ssh/authorized_keys, .conda/*).

  • +
  • Be careful about using tab completion or reverse history search if these +haven’t been introduced yet.

  • +
+
+
+

Desktop environment and browser

+
    +
  • Try to remove window title bars if they take up lots of space +without adding value to the learner.

  • +
  • Can you easily resize your windows for adjusting during teaching?

  • +
  • Does your web browser have a way to reduce its menu bars and other +decoration size?

    +
      +
    • Firefox-based browsers: go to about:config and set +layout.css.devPixelsPerPx to a value slightly smaller than one, +like 0.75. Be careful you don’t set it too small or large since +it might be hard to recover! When you set it to something smaller +than 1, all window decorations become smaller, and you compensate +by zooming in on the website more (you can set the default zoom to +be greater than 100% to compensate). Overall, you get more +information and less distraction.

    • +
    +
  • +
+
+
+

How to switch between teaching setup and work setup?

+
    +
  • Make a dedicated “demos” profile in your terminal emulator, if +relevant. Or use a different terminal emulator just for demos.

  • +
  • Same idea for the browser: Consider using a different browser profile for +teaching/demos.

  • +
  • Another idea is to containerize the setup for teaching. +We might demonstrate this during the Sharing teaching gems session later.

  • +
+
+
+

Keypoints

+
    +
  • Share portrait layout instead of sharing entire screen

  • +
  • Adjust your prompt to make commands easy to read

  • +
  • Readability and beauty is important: adjust your setup for your audience

  • +
  • Share the history of your commands

  • +
  • Get set up a few days in advance and get feedback from someone else. +Feedback and time to improve is very important to make things clear and accessible. +10 minutes before the session starts is typically too late.

  • +
+
+
+
+

Exercises

+
+

Evaluate screen captures (20 min)

+

Evaluate screenshots on this page. Discuss the trade-offs of each one. Which +one do you prefer? Which are useful in each situation?

+

Please take notes in the collaborative document.

+
+
+

Set up your own environment (20 min)

+

Set up your screen to teach something. Get some feedback from another learner +or your exercise group.

+
+
+
+

Other resources

+ +
+
+
+
+
+

Computational thinking

+
+

Objectives

+
    +
  • Explain what is computational thinking

  • +
  • Get to know how the theory of computational thinking can be used in teaching

  • +
  • Short exercise

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 10 min

  • +
+
+

Materials available as slides.

+
+

Keypoints

+
    +
  • Computational Thinking consists of 4 main parts: decomposition, pattern recognition, abstraction and algorithmic design.

  • +
  • How can this be a useful framework for solving problems?

  • +
  • How can this be used practically?

  • +
+
+
+
+

CodeRefinery teaching philosophies

+
+

Objectives

+
    +
  • Get to know the teaching philosophies of CodeRefinery instructors

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Discussion: 20 min

  • +
+
+
+

Introduction

+

During this episode we split into breakoutrooms and discuss own teaching philosophies. +Collect your teaching philosophies in the collaborative document. We will be going through +these and the end of the lesson.

+
+

Ice-breaker in groups (20 minutes)

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+
+

Instructor views

+

Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops.

+

It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us.

+
+

Video recordings

+

We have recorded some of the below as videos: https://www.youtube.com/playlist?list=PLpLblYHCzJAAHF89P-GCjEXWC8CF-7nhX

+
+
+

Bjørn Lindi

+

My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this “BLOB” (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the “BLOB”, to be able to share it with others.

+

In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic.

+

When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson.

+

Tools that I find useful in preparing a lesson is concept maps and Learner Personas (though I have developed too few of them):

+ +
+
+

Radovan Bast

+

My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos.

+

My goal for a lesson is to spark curiosity to try things after the lesson, both +for the novices (“This looks like a useful tool, I want to try using it after +the workshop.”) and the more experienced participants (“Aha - I did not know +you could do this. I wonder whether I can make it work with X.”). I like to +start lessons with a question because this makes participants look up from +their browsers.

+

Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise.

+

For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate the +answer.

+

I try to avoid jargon and “war stories” from the professional developers’ +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid “customer”, +“production”, also a lot of Agile jargon is hard to relate to.

+

Less and clear is better than more and unclear. Simple examples are better than +complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +“simply”, “just”, “easy”. If participants take home one or two points from a +lesson, that’s for me success.

+

I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don’t want to be +surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or slide. +This allows me to skip and distill the essence and not read bullet point by +bullet point.

+

I try to never deviate from the script and if I do, be very explicit about it.

+

A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel listening to me.

+

I very much like the co-teaching approach where the other person helps +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson.

+
+
+

Sabry Razick

+

My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case.

+
+
+

Richard Darst

+

Like many people, I’ve often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I’ve realized long ago that my most important lessons weren’t +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I’ve realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds.

+

My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I’m often start at the +very basics, because this is what I see missing most often.

+

When teaching, I like lots of audience questions and don’t mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don’t have to know everything perfectly, just show how +you’d approach a problem.

+
+
+

Stepas Toliautas

+

I aim for my learners to understand things (concepts, techniques…), instead of just memorizing them. The phrase I use from time to time when teaching information technology topics (be it hardware or software) is “there is no magic”: everything can be explained if necessary. While CodeRefinery also emphasizes usefulness/ immediate applicability of the content, often having the correct notions actually helps to start using them sooner and with less mistakes.

+

I try to guide my audience through the presented material with occasional questions related to previous topics and common knowledge – to help them link the concepts already during the lesson. I’m also fully aware that waiting for someone to answer is quite uncomfortable in-person and doubly so in an online environment, especially if no one uses their cameras :)

+

And if I get the question I don’t have the answer for (or material to show it) at the moment, in university classes I prepare and come back to it next time. While with one-off workshops there might not be a “next time”, open-source material used by CodeRefinery allows to have the same outcome: the latest and greatest version stays available for self-study afterwards.

+
+
+
+

Summary

+
+

Keypoints

+
    +
  • People have different viewpoints on teaching.

  • +
+
+
+
+
+

Co-teaching

+
+

Objectives

+
    +
  • Get to know the principle of co-teaching: How we do it and how you can too.

  • +
  • Learn the team teaching concept and how to tailor it to your situation.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 15 min

  • +
  • Exercises: 10 min

  • +
  • Discussion: 5 min

  • +
+
+
+

Overview

+

CodeRefinery lessons benefit from the application of the concepts of co-teaching.

+
+

Co-teaching

+

Co-teaching can be defined as “the division of labor between educators to plan, organize, instruct and make assessments on the same group of students, generally in a common classroom, and often with a strong focus on those teaching as a team complementing one another’s particular skills or other strengths”.

+
+

Co-teaching can be used in various forms, some of which are present in our workshops:

+
    +
  • Teaching + support, e.g. one of the teachers leading instruction while the other watches over and maintains the collaborative document (HackMD/HedgeDoc/…).

  • +
  • Another similar example is remote learning groups that watch the streamed CodeRefinery lessons guided by the local instructors.

  • +
  • Having open-source material and planning jointly allows multiple instances of a lesson to be held by multiple teachers:

    +
      +
    • parallel teaching, to different audiences at the same time,

    • +
    • alternative teaching, to different audiences at the same or different time, with potential content adjustments (for example, different installation procedures).

    • +
    +
  • +
  • Team teaching, where the lesson is presented by multiple (in most cases, two) teachers who actively engage in conversation with each other. The team-teaching concept is explained in more detail in the CodeRefinery manual.

  • +
+

In reality, different forms are very often mixed or fused together, even within a single lesson.

+

Co-teaching is not an online-only concept. However, it is very practical in online teaching due to larger number of instructors and learners potentially available to join a teaching session.

+
+
+

Co-teaching and team teaching benefits

+
    +
  • It saves preparation time. Co-teachers can rely on each other’s strengths while creating/ revising the material as well as in unexpected situations during the lesson.

  • +
  • It helps with onboarding new instructors. One of the co-teachers can be learning at the same time, either the subtleties of the material taught (in this case literally being the “voice of the audience”) or the teaching process itself.

  • +
  • Team teaching looks more interactive and engaging to the audience in many cases, without forcing the learners to speak up if they can’t or don’t want to do so.

  • +
  • It also ensures responsive feedback and less workload by having more active minds.

  • +
+
+

Are there any downsides?

+

Not every learner and not every instructor might like the team-teaching approach.

+
    +
  • It might seem less structured, unprepared, and chaotic, even with preparation.

    +
      +
    • It might create situations where instructors accidentally talk over each other or “interrupt” and change the flow of the lesson.

    • +
    • For some instructors it can be stressful to not know in advance what questions they get asked from the co-instructor.

    • +
    • Sometimes when an unexpected question is asked that throws the other instructor off, it can add to the feeling of chaos and unpreparedness.

    • +
    +
  • +
  • It can be interactive and engaging but it can also end up awkward if the co-teachers don’t have a good synergy.

    +
      +
    • Can sound awkward: Main instructor talking all the time and at the end asking co-instructor whether everything is clear and co-instructor only saying “yes”.

    • +
    • Possibly more engaging: Co-instructor asking questions which help with the flow and a common understanding of the material.

    • +
    +
  • +
+
+
+
+

Team teaching specifics

+
    +
  • For successful team teaching, additional coordination is needed, first of all to agree on the teaching model (see below) and the person in control (the director) for the lesson or its parts.

  • +
  • It’s useful to keep track of the lecture plan. The discussion is a good way to make lesson more interactive and adjust to the audience, but deviating too much will become disorienting (for example, if someone dropped their attention for a minute and now is trying to catch-up by reading lecture notes).

  • +
  • Experienced solo teacher might have a habit to keep talking (lecturing), while the co-teacher might not want to “interrupt”. Therefore, it is important for the leading presenter to anticipate and allow for remarks/ questions, and this can be different from one’s previous teaching style at first.

  • +
+
+
+

Team teaching models

+

We propose two basic models, but of course there is a constant continuum.

+
+

Guide and demo-giver

+

One person serves the role of guide, explaining the big picture and context of the examples.

+

Another, the demo-giver,

+
    +
  • shows the typing and does the examples,

  • +
  • might take the role of a learner who is asking about what is going on, to actually explain the details, or to comment occasionally.

  • +
+

Hands-on demos and exercises work especially well like this.

+
+
+

Presenter and interviewer

+

In this case, one is the presenter who is mostly explaining (including demos or examples), and trying to move the forward through the material.

+

Another, the interviewer,

+
    +
  • serves as a learner or spotter,

  • +
  • fills in gaps by asking relevant questions,

  • +
  • tries to comment to the presenter when things are going off track.

  • +
+

This can be seen as closer to classical teaching, but with a dedicated and prepared “voice of the audience”.

+
+
+

Exercise

+
+

Discuss the models of team teaching (10 min)

+

While in breakout rooms, discuss one of the basic team-teaching models presented here:

+
    +
  • Have you already tried this or similar model in your teaching?

  • +
  • Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best?

  • +
+

Write your comments in the collaborative document.

+
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Co-teaching focuses on complementing individual skills and strengths in teaching process.

  • +
  • Co-teaching may save time, reduce teachers’ workload and make lessons more interactive/ engaging.

  • +
  • Team teaching requires some adjustments in lesson preparation and delivery.

  • +
+
+
+
+
+

Sharing teaching gems

+
+

Objectives

+
    +
  • Our goal is to share our teaching tricks and tools and demonstrate them in +very short presentations/discussions.

  • +
+
+
+

Instructor note

+
    +
  • Demonstrations: 35 min

  • +
+
+

Here we encourage participants to take the screen share for 3 minutes and +demonstrate either some tool or trick they found useful for their teaching or +something from a course you liked.

+
+
+
+
+

Session 4 intro

+

This session covers streaming and technical production. Some +introductory notes:

+
    +
  • (As of 2024) This is the first and only comprehensive introduction +to our online streaming.

  • +
  • These practices are new and well-refined internally, but a +different kind of refinement is needed to teach and reuse them.

  • +
  • The lessons have outlines of what to talk about, but it’s just an +outline. It is not refined, since thees things are new. Many +things will have to be figured out as we talk.

  • +
  • This session is a demo of lots of basics.

    +
      +
    • Ask questions - otherwise it will be boring

    • +
    • If you want to use this in real life: you will need mentoring +sessions and active help. Contact us to do that.

    • +
    +
  • +
+
+

Warning

+

Audio and video weirdness

+

We are setting up video and audio recording, but also capturing that +for re-sharing it. There may be anomalies as video or audio +feedback. Please be prepared.

+
+
+
+

Why we stream

+
+

Objectives

+
    +
  • Learn the general history of CodeRefinery streaming.

  • +
  • Discuss the benefits of streaming and recording

  • +
  • Discuss the downsides and difficulties

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 10 min

  • +
  • Q&A: 5 min

  • +
  • Exercises: 0 min

  • +
+
+

This is a general discussion of the topics of the day, focused on the +history of why we stream and record, how we got here, and how people +feel about it. We won’t focus on how anything is done.

+
+

Icebreaker questions

+
    +
  • What is the most people you have taught for?

  • +
  • What are the distinct parts of teaching, that can be +separated? (teaching, helping, etc)

  • +
+
+
+

What is streaming and recording?

+
    +
  • Streaming is mass communication: one to many

    +
      +
    • Interaction audience→presenters is more limited (but different)

    • +
    +
  • +
  • Using consumer-grade tools, normal people can reach huge audiences +by Twitch/YouTube/etc.

  • +
  • This isn’t actually that hard: people with much less training than +us do it all the time.

  • +
  • They reach huge audiences and maintain engagement for long events.

  • +
+

Recording and rapid video editing is useful even without +streaming.

+
+
+

History

+
    +
  • In-person workshops

    +
      +
    • 3 × full day, required travel, infrequent, one-shot

    • +
    +
  • +
  • Covid and remote teaching

    +
      +
    • Traditional “Zoom” teaching several times

    • +
    +
  • +
  • Mega-CodeRefinery workshop

    +
      +
    • 100-person Zoom teaching

    • +
    • Emphasis on teams

    • +
    +
  • +
  • Research Software Hour

    +
      +
    • Livestream free-form discussions on Twitch

    • +
    +
  • +
  • Streamed “HPC Kickstart” courses

  • +
+
+
+

Benefits and disadvantages

+

Benefits:

+
    +
  • Larger size gives more (but different) interaction possibility

    +
      +
    • “Notes” for async Q&A

    • +
    +
  • +
  • Recording (with no privacy risk) allows instant reviews

  • +
  • Stream-scale allows for many of the things you have learned about in +days 1-3.

  • +
+

Disadvantages:

+
    +
  • Requires training for using the tools

  • +
  • Requires a certain scale to be worth it

  • +
  • Coordination is much harder for big events

  • +
+

When would I recommend it?

+
    +
  • No: For small courses

  • +
  • Questionable: Medium sized courses with no videos

  • +
  • Yes: When you want the largest audience

  • +
  • Yes: When you want without registration required

  • +
  • Yes: When you want good reusability/fast videos

  • +
+
+
+

Future prospects (briefly)

+
    +
  • Streaming probably stays as a CodeRefinery tool

  • +
  • We can scale our courses much larger than they are now. Why don’t +we, together with others?

  • +
  • These tools are useful in other places too

    +
      +
    • I’ve used them to record my own talks to make videos of my +single-person presentations or record conference talks nicer than Zoom.

    • +
    +
  • +
+
+
+

Q&A

+

Q&A from audience

+
+

Keypoints

+
    +
  • Streaming optimizes a course for different things

  • +
  • The disadvantages can be compensated for

  • +
  • There are benefits and disadvantages

  • +
+
+
+
+
+

Behind the stream

+
+

Objectives

+
    +
  • Take a first look at the broadcaster’s view.

  • +
  • Get to know what happens “behind the stream” of a workshop

  • +
  • See what the “broadcaster” sees and what they need to do.

  • +
  • Not yet: learn details of how to do this.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Q&A 10 min

  • +
+
+

In this episode, you’ll see an end-to-end view of streaming from the +broadcaster’s point of view. It’s a tour but not an explanation or +tutorial.

+
+

Who does what

+

We have certain role definitions:

+
    +
  • Broadcaster: Our term for the person who manages the streaming.

  • +
  • Director: Person who is guiding the instructors to their +sessions, changing the scenes, calling the breaks, etc.

    +
      +
    • Could be the same as broadcaster.

    • +
    +
  • +
  • Instructor: One who is teaching. They don’t have to know +anything else about how streaming works.

  • +
+

This lesson describes what the Broadcaster/Director sees.

+
+
+

Window layouts

+

What does the broadcaster see on their screen?

+
    +
  • What are the main windows you see?

  • +
  • What do each of them do?

  • +
  • Which ones do you need to focus on?

  • +
  • How do you keep all this straight in your head?

  • +
+
+
+

CodeRefinery control panel

+
    +
  • A custom application that controls scenes

  • +
  • Based on OBS-websocket (remote control connection for OBS - we’ll +learn about this later)

  • +
  • Can also work remotely, so that you can have a remote director

  • +
+
+
+

How scenes are controlled

+

What has to be done during a course?

+
    +
  • How do you start the stream?

  • +
  • How do you change the view?

  • +
  • How do you adjust things based on what the instructors share?

  • +
  • How do you coordinate with the instructors?

  • +
  • How do you know when to change the view?

  • +
+
+
+

Getting it set up

+
    +
  • How hard was it to figure this out?

  • +
  • How hard is it to set it up for each new workshop?

  • +
+
+
+

What can go wrong

+
    +
  • What’s the worst that has happened?

  • +
  • What if you need to walk away for a bit?

  • +
  • Someone broadcasts something unexpectedly

  • +
+
+
+

Alternatives

+
    +
  • Youtube vs Twitch

  • +
  • Zoom stream directly to YouTube/Twitch

  • +
  • Direct streaming platform, e.g. streamyard

  • +
+
+
+

Q&A

+

Q&A from audience

+
+

Keypoints

+
    +
  • The broadcaster’s view shouldn’t be so scary.

  • +
  • There is a lot to manage, but each individual part isn’t that hard.

  • +
+
+
+
+
+

Video editing

+
+

Objectives

+
    +
  • Get to know ways of quick video editing to be able to provide +accessible videos

  • +
  • Learn how video editing can be distributed and done the same day.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 20 min

  • +
+
+

Video recordings could be useful for people watching later, +but also are (perhaps more) useful for immediate review and catching +up after missing a day in a workshop. For this, they need to be +released immediately, within a few hours of the workshop. +CodeRefinery does this, and you can too.

+

Hypothesis: videos must be processed the same evening as they were +recorded, otherwise (it may never happen) or (it’s too late to be +useful). To do that, we have to make processing good enough (not +perfect) and fast and the work distributeable.

+
+

Primary articles

+ +
+
+

How this relates to streaming

+
    +
  • If you stream, then the audience can not appear in the recorded +videos

  • +
  • This allows you to release videos very quickly if you have the +right tools.

  • +
  • When you have a large audience, the videos start helping more +(review a missed day, catch up later, review later)

  • +
  • Thus

    +
      +
    • If you would never want videos, there may never be a benefit to +streaming

    • +
    • If you want videos, it gives motivation to stream.

    • +
    +
  • +
+
+
+

Summary

+
    +
  • Basic principle: privacy is more important than any other factor. +If we can’t guarantee privacy, we can’t release videos at all.

    +
      +
    • Disclaimers such as “if you don’t want to appear in a recording, +leave your video off and don’t say anything”, since a) accidents +happen especially when coming back from breakout rooms. b) it +creates an incentive to not interact or participate in the course.

    • +
    +
  • +
  • Livestreaming is important here: by separating the instruction from +the audience audio/video, there is no privacy risk in the raw +recording. They could be released or shared unprocessed.

  • +
  • Our overall priorities

    +
      +
    1. No learner (or anyone not staff) video, audio, names, etc. are +present in the recordings.

    2. +
    3. Good descriptions.

    4. +
    5. Removing breaks and other dead time.

    6. +
    7. Splitting videos into useful chunks (e.g. per-episode), perhaps +equal with the next one:

    8. +
    9. Good Table of Contents information so learners can jump to the +right spots (this also helps with “good description”.)

    10. +
    +
  • +
  • ffmpeg-editlist +allows us to define an edit in a text file (crowdsourceable on +Github), and then generate videos very quickly.

  • +
+
+
+

How we do it

+

The full explanation is in the form of the exercises below. As a +summary:

+
    +
  • Record raw video (if from a stream, audience can’t possibly be in +it)

  • +
  • Run Whisper to get good-enough subtitles. Distribute to someone for +checking and improving.

  • +
  • Define the editing steps (which segments become which videos and +their descriptions) in a YAML file.

  • +
  • Run ffmpeg-editlist, which takes combines the previous three steps +into final videos.

  • +
+
+
+

Exercises

+
+

Exercise A

+

These exercises will take you through the whole sequence.

+
+

Editing-1: Get your sample video

+

Download a sample video:

+ +
+

Editing-2: Run Whisper to generate raw subtitles and test video.

+

First off, install Whisper and generate the base subtitles, based +on the. Since this is probably too much to expect for a short +lesson, they are provided for you (above), but if you want you can +try using Whisper, or generating the subtitles some other way.

+

You can start generating subtitles now, while you do the next +steps, so that they are ready by the time you are ready to apply +the editlist. ffmpeg-editlist can also slice up the subtitles from +the main video to make subtitles for each segment you cut out.

+

Whisper is left as an exercise to the reader.

+ +
+
+
+

Editing-3: Create the basic editlist.yaml file

+

Install +ffmpeg-editlist and +try to follow its instructions, to create an edit with these features:

+
    +
  • The input definition.

  • +
  • Two output sections: the “Intro to the course”, and “From data +storage to your science” talks (Remember it said the recording +started at 11:35… look at the schedule for hints on when it +might start!). This should have a start/end timestamp from the +original video.

  • +
+

A basic example:

+
- input: day1-raw.mkv
+
+# This is the output from one section.  Your result should have two of these sections.
+- output: part1.mkv
+  title: something
+  description: >-
+    some long
+    description of the
+    segment
+  editlist:
+    - start: 10:00    # start timestamp of the section, in *original* video
+    - end: 20:00      # end timestamp of the section, in the *original* video
+
+
+ +
+
+

Discussion: what makes a video easy to edit?

+
    +
  • Clear speaking and have high audio quality.

  • +
  • For subtitle generation: Separate sentences cleanly, otherwise it +gets in a “stream of words” instead of “punctuated sentences” +mode.

  • +
  • Clearly screen-sharing the place you are at, including section +name.

  • +
  • Clear transitions, “OK, now let’s move on to the next lesson, +LESSON-NAME. Going back to the main page, we see it here.”

  • +
  • Clearly indicate where the transitions are

  • +
  • Hover mouse cursor over the area you are currently talking about.

  • +
  • Scroll screen when you move on to a new topic.

  • +
  • Accurate course webpage and sticking to the schedule

  • +
+

All of these are also good for learners. By editing videos, you +become an advocate for good teaching overall.

+
+
+

Editing-4: Run ffmpeg-editlist

+

Install ffmpeg-editlist: pip install ffmpeg-editlist[srt] (you +may want to use a virtual environment, but these are very minimal +dependencies).

+

The ffmpeg command line tool must be available in your +PATH.

+ +
+
+

Editing-5: Add more features

+
    +
  • Several chapter definitions.(re-run and you should see a +.info.txt file also generated). Video chapter definitions +are timestamps of the original video, that get translated to +timestamps of the output video.

    +
    - output: part1.mkv
    +  editlist:
    +  - start: 10:00
    +  - -: Introduction    #  <-- New, `-` means "at start time"
    +  - 10:45: Part 1      #  <-- New
    +  - 15:00: Part 2      #  <-- New
    +  - end: 20:00
    +
    +
    +

    Look at the .info.txt files that come out now. What is new in it?

    +
  • +
  • Add in “workshop title”, “workshop description”, and see the +.info.txt files that come out now. This is ready for +copy-pasting into a YouTube description (first line is the title, +rest is the description).

    +

    Look at the new .info.txt files. What is new?

    +
  • +
+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+
+
+

Editing-7: Generate the final output file.

+
    +
  • Run ffmpeg-editlist with the --reencode option: this +re-encodes the video and makes sure that there is no black point +at the start.

  • +
  • If you re-run with --check, it won’t output a new video file, +but it will re-output the .info.txt and .srt files. +This is useful when you adjust descriptions or chapters.

  • +
+
+
+

Discussion: how to distribute this?

+

Create a flowchat of all the parts that need to be done, and which +parts can be done in parallel. Don’t forget things that you might +need to do before the workshop starts.

+

How hard was this editing? Was it worth it?

+
+
+
+

Exercise B

+

This is a more limited (and older) version of the above exercise, +using an synthetic example video.

+
+

Use ffmpeg-editlist to edit this sample video

+

Prerequisites: ffmpeg must be installed on your computer +outside of Python. Be able to install ffmpeg-editlist. This is +simple in a Python virtual environment, but if not the only +dependency is PyYAML.

+ + +
+
+
+
+

See also

+ +
+

Keypoints

+
    +
  • Video editing is very useful for learning

  • +
  • Set your time budget and make it good enough in that time

  • +
  • Reviewing videos improves your teaching, too.

  • +
+
+
+
+
+

Open Broadcaster Software (OBS) introduction

+
+

Objectives

+
    +
  • Understand that OBS is a video mixer.

  • +
  • Understand the basic controls and features of OBS.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 15 min

  • +
  • Q&A 5 min

  • +
+
+ +

In this episode, you’ll get more familiar with the OBS portion of the +streaming setup. You’ll see how it’s used, but not yet how to +configure it from scratch. You’ll learn how to be a “director”.

+
+

What is OBS?

+
    +
  • Formally “OBS Studio”

  • +
  • Most commonly known as a livestreaming application.

  • +
  • Open source, free.

  • +
  • Cross-platform, easy to use screencasting and streaming application.

  • +
  • Real-time video mixer.

  • +
+
+
+

OBS user interface

+
    +
  • We’ll click through each view.

  • +
  • What does each view do?

  • +
  • Let’s click through the buttons.

  • +
  • Let’s see the important config options.

  • +
+
+
+

OBS during a course

+
    +
  • What management is needed.

  • +
  • The control panel.

  • +
  • Audio.

  • +
  • Adjusting windows and so on.

  • +
+
+
+

Hardware requirements

+
    +
  • Reasonably powerful broadcast computer

    +
      +
    • CodeRefinerys streaming computer is 8 CPU AMD, 64GB memory

    • +
    • That is way overkill: a powerful laptop can probably do this.

    • +
    +
  • +
  • Large second monitor for laying out the windows you capture

  • +
  • Stable internet connection (wired preferable)

    +
      +
    • CodeRefinery’s broadcast is the slowest purchasable: 100 Mbit down / +25Mbit up

    • +
    +
  • +
+
+
+

Q&A

+

We’ll answer audience questions.

+
+
+

See also

+ +
+

Keypoints

+
    +
  • OBS may seem complicated, but it’s a graphical application and most +pieces make sense once you know how it works.

  • +
+
+
+
+
+

Open Broadcaster Software (OBS) setup

+
+

Objectives

+
    +
  • See how to configure OBS using the pre-made CodeRefinery scene +collections

  • +
  • Modify the collections to suit your needs.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: ?? min

  • +
  • Hands-on: ?? min

  • +
  • Q&A: ?? min

  • +
+
+ +

In this lesson, we’ll see how to configure OBS from scratch for your +purposes. We’ll do this by deleting the instructor’s configuration +and trying to recreate it

+

This section is short, since it has never been done before: we’ll just +give it a short and update the lesson later.

+
+

CodeRefinery OBS configs

+
    +
  • CodeRefinery configs are shared in a repository: +https://github.com/coderefinery/obs-config

  • +
  • These can be imported to pre-configure some things

  • +
  • There are two types of configs:

    +
      +
    • Profiles

      +
        +
      • Servers, resolutions, audio, video, etc.

      • +
      +
    • +
    • Scene collections

      +
        +
      • The graphical layouts.

      • +
      +
    • +
    +
  • +
+
+
+

Installing the OBS config

+
    +
  • Clone the git repository.

  • +
  • Import the profile and scene collections under their respective +menus.

  • +
+
+
+

Initial setup

+
    +
  • Click through each menu and change anything that is needed

  • +
  • Set the streaming server

  • +
+
+

The instructor will go through the setup.

+
    +
  • Reset configuration: mv .config/obs-studio/ .config/obs-studio-old/

  • +
  • Import profiles/TeachingStreamingv3/

  • +
  • Import scenes/TeachingStreamingZoomv3.json

  • +
+
+
+
+

Set up the remote control

+
    +
  • Create a Python environment and install it: pip install https://github.com/coderefinery/obs-cr/archive/refs/heads/master.zip

  • +
  • Run it: python obs_cr/control.py localhost:4445 TOKEN --broadcaster

  • +
  • There are more options but let’s not cover them yet… and leave +this for a hands-on session.

  • +
+
+
+

Setup before each course

+
    +
  • Re-confirm audio

  • +
  • Re-confirm each scene

  • +
  • Test everything

  • +
  • rkdarst has a rather long +checklist, +but each individual step is short.

  • +
+
+
+

Q&A

+

We’ll answer audience questions.

+
+

Keypoints

+
    +
  • Most of our configuration has been OBS may seem complicated, but it’s a graphical application and most +pieces make sense once you know how it works.

  • +
+
+
+
+
+

What’s next?

+
+

Objectives

+
    +
  • Know next steps if you want to do streaming

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 5 min

  • +
  • Q&A 5 min

  • +
+
+

What comes next?

+
    +
  • We talked a lot about theory, and gave demonstrations.

  • +
  • Hands-on is very different. We recommend working with someone to +put it in practice.

  • +
  • +
+
    +
  • Work with someone who can show you the way

  • +
  • Use it for smaller courses with a backup plan

  • +
+
+

See also

+
+

Keypoints

+
    +
  • These lessons about streaming have been the theoretical part of +streaming training.

  • +
+
+
+
+
+
+
+

Collaborative notes archives from workshops

+
+

August/September 2024

+
+

Day1: Session 1 (13.08.24) - About lesson design, deployment and iterative improvement

+
+
:calendar: Schedule
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 10.00

Lesson design and development

10.15 - 11.00

8.15 - 9.00

10.00 - 10.15

Break

11.00 - 11.15

9.00 - 9.15

10.15 - 11.00

Lessons with version control

11.15 - 12.00

9.15 - 10.00

11.00 - 11.15

Break

12.00 - 12.15

10.00 - 10.15

11.15 - 12.00

How we collect feedback and measure impact

12.15 - 13.00

10.15 - 11.00

+
+
+
:icecream: Icebreaker
+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :Decaffed … and going strong …

  • +
  • :coffee: 🤔

  • +
  • :100: (ironically!) :coffee: intake happening

  • +
  • :smile:

  • +
  • :tired_face:

  • +
  • :coffee: :party:

  • +
  • :coffee: :happy:

  • +
  • 😪

  • +
  • just got zoom installed / before my coffee

  • +
  • :smil-

  • +
  • :sweat_smile: (+)

  • +
  • :yawning_face:

  • +
  • :is it morning already?

  • +
  • :smile:

  • +
  • :yawning_face:

  • +
  • :nerded_face:

  • +
  • 🥵

  • +
  • :smile:

  • +
  • :sleeping:

  • +
  • :sleepy: :coffee: :smiley_cat:

  • +
  • 🥳

  • +
  • :coffee:

  • +
  • :coffee:

  • +
+
+
+
Introduction in breakoutrooms.
+
    +
  • Name / Affiliation / Location

  • +
+
+
+
About teaching
+

What is the hardest thing about teaching for you?

+
    +
  • Knowing how “it’s going”, whether learners are happy or not (especially when teaching online) :+1:

  • +
  • The preparation the night before. It is always much more that I would hope, no matter how prepared I want it to be :+1: :+1:

  • +
  • Managing groups with vastly different academic backgrounds

  • +
  • Teaching wide spectrum of skill level at the same time. :+1: :+1: :+1: :+1:

  • +
  • Time management! (Knowing how much can fit in a sessions) :+1: :+1:

  • +
  • General preparation time, how to fit it into the regular work schedule, and estimate how much time is needed for prep.

  • +
  • How to reduce too much text into just the right amount

  • +
  • Preparation of the session material and estimating the right amount of time for each section

  • +
  • Getting learners to take the first step: sign up for and attend a workshop, when they don’t think programming is a skill they can learn

  • +
  • Getting learners to take the second step: translating what they’ve learned in a workshop into something they can apply

  • +
  • preparation and time management

  • +
  • Engaging with the students which was much easier for me when I used to coach

  • +
  • Finding the right depth for an unknown audience for “my topic”

  • +
  • education background of participants and their learning objectives

  • +
+

What is the best thing about teaching for you?

+
    +
  • Seeing when learner gets interested/curious about something and takes inspiration from the course. :+1:

  • +
  • Seeing it works and someone can do something new.

  • +
  • Motivated students grasping new stuff

  • +
  • Students picking up and running with the matertial and skills I give them and using it for their own work. :+1:

  • +
  • The “ah-ha!” moment when a student gets it! :+1::100: :+1:

  • +
  • Learning from students who know about some topic more than you do. :+1:

  • +
  • Being able to help people reach their goals, by showing them something new.

  • +
  • Teaching is optimism acted out in the hope of making a difference both ways I suppose.

  • +
  • The feeling of accomplishment when you see learning grow and implement the learnings :book:

  • +
  • mutual learning and impact on learners :+1:

  • +
  • Results and feedbacks / Mutual interests and interesting discussions

  • +
  • mutual learning and I can also learn lots of things and new ideas from participants

  • +
+
+
+
+
:question: Questions
+
+
General / Practicalities
+
    +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms? I’m not in a place where I can talk, so if we’re going to talk a lot I’ll need to move offices

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    +
  • +
  • +
+
+
+
Episode 1: Lesson design and development
+

Materials: https://coderefinery.github.io/train-the-trainer/lesson-development/ +Discussion:

+
    +
  • When you start preparing a new lesson or training material, where do you start?

    +
      +
    • I look at existing materials on the same topic, but chose/refine topics based on the perceived needs/interests of the presumed audience

    • +
    • Outline of structure and Material collection for a new lesson :+1:

    • +
    • What material I have already? (what other material is already out there?)

    • +
    • Start by looking for related resources (documents, videos, courses, etc) to have a base data and better understanding of what have been done around the topic

    • +
    • Know your audience

    • +
    • Review existing material

    • +
    • Think about learning objectives (to keep focus on essential things)

    • +
    • Think of three things simple enough that they will be remembered the next day. Design around that.

    • +
    • I write down the thoughts that I have and then go back and structure it.

    • +
    +
  • +
  • What tricks help you with “writer’s block” or the empty page problem?

    +
      +
    • Write anything down that comes to mind, sometimes draw something, looking out the window :)

    • +
    • Do a mind map - what concepts do I want to get across?

    • +
    • Starting small, for example a list of headings and then building around it. :+1:

    • +
    • What does one know about the target audience and why should they be spending longer than 1 minute listening to what they will eventually get to hear?

    • +
    • Get some inspiration from another source.

    • +
    • Start with the three things above

    • +
    • Start with the plan and the overview design

    • +
    • Some kind of outline / main message(s)

    • +
    • Start with three things. Three supporting points for each of these.

    • +
    +
  • +
  • Maybe you haven’t designed training material yet. But how do you start when creating a new presentation?

    +
      +
    • Think about the learning objectives and try to break them down into steps

    • +
    • Title, Objectives, target audience and Plan

    • +
    • Some kind of outline / main message(s). Get as many images as I can, instead of words

    • +
    • Draft an outline and use chatgpt to fill in details

    • +
    • Example of how the teaching content is applied in a real-world context

    • +
    +
  • +
  • If your design process has changed over time, please describe what you used to do and what you do now instead.

    +
      +
    • I look more at existing materials and try to get more information about the audience. Unfortunately getting information about the audience before the event is hard

    • +
    • I used to start from the begginning and get from there but that often meant a very polished start and a rushed end. Now I try an overview first, then fil out sparsed details at every section

    • +
    • Updating the data and tweak the presentation

    • +
    • If I am teaching a small group (or one to one) talk to them before hand - find out what they know already, what they want to learn.

    • +
    +
  • +
  • What do you know now about preparing lessons/training/presentations that you wish you knew earlier?

    +
      +
    • less is more. It’s better to have 2-3 main messages rather than trying to show everything in one go :+1: :+1: :+1: :+1:

    • +
    • how much practice time the learners need to master what’s taught

    • +
    • Don’t worry about something going wrong. It often makes the lesson (and thus the material) more presistent in memory. :+1:

    • +
    • Try and remove everything except what you want the person to learn

      +
        +
      • That’s a very tough part for me in the sense that I never know how much of an underlying “black box” is still ok….

      • +
      +
    • +
    • Designing intermediate materials is hard, and requires putting some “gatekeeping” making sure that learners are directed to appropriate courses

    • +
    • When I see a cool graphic, concept, slide, etc., download it and save it in my ‘new-materials’ folder to use later on!

    • +
    • I have come to the conclusion that perhaps a more “agile” approach to developing materials (try to do design/teaching iterations quickly) might be the best way to go, but there are risks with this approach too

    • +
    +
  • +
+

Questions

+
    +
  • From zoom chat: Can you expand on what a learner persona is?

    +
      +
    • A defined example person described in terms of the materials you are preparing, making up a story about the background and interest of t

    • +
    • Answer from chat: A learner persona is a blackbox which has a very simple algorithm inside: GIGO.

    • +
    • Answer from chat: I think it’s the same as ICP (Ideal customer persona) where you describe the learner as a customer

    • +
    • Answer from chat: I’m a big fan of “How Learning Works” by Ambrose et al https://bookshop.org/p/books/how-learning-works-eight-research-based-principles-for-smart-teaching-michele-dipietro/18640868?ean=9781119861690

    • +
    • See also book: Teaching tech together

    • +
    +
  • +
+
+

CodeRefinery lessons: https://coderefinery.org/lessons/

+
+
    +
  • From chat: Do you have an example of an instructor guide?

    + +
  • +
  • From zoom chat: Do you have a “measure” of how better are the new lesson compared to the old ones? Does it make sense to talk about measurements here?

    +
      +
    • So far we only have daily feedback that we collect at the end of the day and we can compare that to earlier daily feedbacks. More about that in the last episode of today. But measuring this is indeed not easy and it also takes time to capture the effect during longer-term surveys. Some of the changes were more leap-of-faith than based on data.

    • +
    • I guess that sometimes one can use “compelling arguments” instead of data to justify a decision

    • +
    +
  • +
  • Software Carpentry does teach using the command line, and gives a session on the command line before. What do you think about this approach? Are you stating that a 3-hour lesson about CLI is not sufficient to make people comfortable enough to use that for version control?

    +
      +
    • Yes, good question. For CR we consider it a more advanced step: we do think people should learn command line, but it’s for a different course. We accept some people might not know it or want to know it so adapt to that.

    • +
    • In general, we’ve found the “you need X, but have to learn A, B, and C first” approach should be avoided if possible: people are busy, try to reach people where they are.

    • +
    +
  • +
+
+

Exercise in breakoutrooms

+
+
    +
  • Room 1

    +
      +
    • Research data management

    • +
    • Objectives

      +
        +
      • Research life cycle

      • +
      • FAIR principles (Findable, Accessible, Interoperable, Reusable)

      • +
      +
    • +
    • Exercise

      +
        +
      • develop a data management plan (DMP) that outlines how their research data will be handled throughout its lifecycle.

      • +
      +
    • +
    +
  • +
  • Room 2: What is the difference between eating breakfast and sitting through a lecture? (Tip: Start by listing the similarities …)

  • +
  • Room2 : Making papers in LaTeX +- What is LaTex and how is it different from editors like Word +- Basic Structures +- How to find and use a template +- Including figure & table +- How to use references and labels +- Exercise: to create a new LaTeX document & edit it +- Excercise: common error messages: can you find the error in this code? +- Exce

  • +
  • Room 3

    +
      +
    • GPU Programming (1 hour intro)

    • +
    • Learning objectives:

      +
        +
      • What is GPU programming.

      • +
      • When is it usable, beneficial to use GPU programming?

      • +
      • What are technologies to do GPU programming?

      • +
      • [What are and how to manage typical issues]

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • Git / Figures / Project management / data cleaning

    • +
    • Chose data cleaning

    • +
    • Three learning objectives:

      +
        +
      1. What do we mean by “clean”? How to identify it?

      2. +
      3. Identify some common problems in a dataset

      4. +
      5. Identifying and handling missing values/fields

      6. +
      +
    • +
    • Exercise

      +
        +
      1. Discuss problems, find the most common ones

        +
          +
        • In small groups

        • +
        • What problems have you run into with datasets you’ve worked with?

        • +
        • What problems can you imagine, or have you heard about from colleagues/news/social media?

        • +
        • Report back, instructor collects all problems into a list

        • +
        +
      2. +
      3. Have a dataset to clean; a clean and a messy example

        +
          +
        • (identifying) Using a visualisation or overviewing tool?

        • +
        +
      4. +
      +
    • +
    +
  • +
  • Room 5

    +
      +
    • Jupyter Notebooks

    • +
    • Learning Objectives

      +
        +
      • Can setup an enviroment you can reuse / can share with others / a project.

      • +
      • The order you run the commands in needs to match the order of the code in the Notebook - otherwise you end up in a pickle.

      • +
      • Why use a Jupyter Notebook? What are the advantages? Easy to use environment.

      • +
      +
    • +
    • Exercise

      +
        +
      • Print variable assignments from different cells - show that the order you run the code is important.

      • +
      • hand out a domain specific notebook that does some calculations and visualization to run and modify, to show that you can share easily

      • +
      • show !pip install to add dependencies/features

      • +
      +
    • +
    +
  • +
  • Room 6

    +
      +
    • Using GitHub without the command line

    • +
    • Learning Outcomes:

      +
        +
      • Be able to discuss changes before merging changes into the main repository.

      • +
      • Publish a personal repository page ( I think its called intro repository)

      • +
      • Share their script/notebook/code/small data on GitHub

      • +
      • Homepage using GitHub pages or the README that becomes the “index page” of the GitHub user account page

      • +
      +
    • +
    • Learner personas:

      +
        +
      • Check the Personas of the learners

        +
          +
        • Somebody who has seen/heard of GitHub but hasn’t used it yet

        • +
        • Someone using it for their own work but struggling with collaboration

        • +
        +
      • +
      +
    • +
    • Exercises:

      +
        +
      • Upload/share an example dataset or script

      • +
      • Review another collaborators pull request.

      • +
      • Take part in the discussion on a pull request.

      • +
      +
    • +
    +
  • +
  • Room 7 +Linux shell basics: why do we want to teach them? +(this took most of the time for the discussion)

    +
      +
    • Learning objectives:

      +
        +
      1. Filesystem: Directory (CLI) - Folder (GUI) analogy

      2. +
      3. Basic commands (which commands are basic? make a survey of shell histories and get the most common ones)

      4. +
      5. Basic constructs (e.g., for loops, pipes, while loops… which ones are basic? See above)

      6. +
      +
    • +
    +
  • +
+
+

Note from chat: Zoom timer: https://support.zoom.com/hc/en/article?id=zm_kb&sysparm_article=KB0068677

+
+
+
+
Episode 2: Lessons with version control
+

Materials: https://coderefinery.github.io/train-the-trainer/lessons-with-git/

+

Poll options: I want to hear about:

+
    +
  • A: Why use version control for teaching materials

  • +
  • B: Different template options

  • +
  • C: How CodeRefinery does it; CodeRefinerys lesson template

  • +
+

Poll vote (multi-select): add a o to your answer +- A: ooo +- B: oooooo +- C: oooooooo :ghost:

+

Question to audience: if someone wants to make a tiny fix to your material, how hard is it?

+
    +
  • If my material is only in pdf format which is not online, then it is hard.

  • +
  • I hope it is easy - my material is in GitHub. Nobody has ever done that though!

  • +
  • Slides: hard to find, easy to edit; Git repos somewhat easy, unless they have to be built locally or with an action; HackMD easiest to edit.

    +
      +
    • if you use something like google slides they are not that difficult to find

    • +
    • known permanent address. Google docs et al fail on that/same for many pads.

    • +
    +
  • +
  • For this material today - very easy! e.g. https://github.com/coderefinery/train-the-trainer/pull/128

  • +
  • Template with an edit button in the HTML pointing to the source-code in the repo.

  • +
+

Questions/Discussion topics

+
+

Upcoming CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/ +Please share with your networks, and let us know if you would like to co-teach a lesson (to support@coderefinery.org or in our Zulip chat)

+
+
    +
  • Changes to the material are sometimes not just tiny fixes. For example, one wants to present a slightly different selection of topics, but maybe some topics are “coupled” (perhaps naturally or perhaps just because of how they are presented), or change the general “theme” (e.g., life sciences vs theoretical physics) while keeping the actual topics the same. How could a lesson be developed to avoid having to do a huge rewrite?

    +
      +
    • You can try to modularize your material and keep non topic specific parts non themed. E.g. where you explain the functionality, don’t make reference to the example (not simple), so the example can be changed depending on the audience.

    • +
    +
  • +
  • What are the pros/cons of renaming a course / changing a repo name in GitHub?

    +
      +
    • It should be relatively unproblematic since GitHub will forward to the new name.

      +
        +
      • How long does Github keep the “old” name linked? Is there a max time it’s blocked, or changed as soon as a new one appears with the name?

        +
          +
        • in my experience it forwards “forever” until I create a new repo with the old name which will break the forward

        • +
        +
      • +
      +
    • +
    +
  • +
  • what should be in the readme for the git repo? (canonical address? contact points? license!)

    +
      +
    • https://coderefinery.github.io/mini-workshop/2/documentation/#often-a-readme-is-enough-checklist

      +
        +
      • I miss the url to the (main) repo in the readme

        +
          +
        • Do you mean the link to the rendered (lesson) page?

        • +
        +
      • +
      +
    • +
    • Link to rendered page: We often have this in the “about” section of the readme (see up right: https://github.com/coderefinery/train-the-trainer)

    • +
    • this gets lost in a fork, doesn’t it? so 20 folks forking and or reuploading the repo somewhere means the url gets lost?

      +
        +
      • True, but they might want to have their own version rendered?

        +
          +
        • yes, I have had issues finding and contributing to the “master” repo so all benefit. Else it gets cluttered. Both is valid

          +
            +
          • Good point though, the link to rendered page should probably also be included in the readme for completeness; ah and the link to the repository too, yes

            +
              +
            • so realistically we need a content folder and some more next to the readme as a best practice. sounds good!

            • +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • Is myst (markdown renderer) enabled by default in sphinx now?

    +
      +
    • to my knowledge no. we add the “myst_parser” extension to conf.py.

    • +
    +
  • +
+
+

Cicero: https://cicero.readthedocs.io/ +Sphinx documentation: https://www.sphinx-doc.org/en/master/ +Carpentries workbench for creating Carpentries lessons: https://carpentries.github.io/workbench/ +This is the testing lesson Richard showed: https://coderefinery.github.io/testing/ +And the corresponding repository: https://github.com/coderefinery/testing +You can lean back and watch, exercise coming in a bit :) +Richard will now edit our train the trainer material repository: https://github.com/coderefinery/train-the-trainer +The Sphinx extension for CodeRefinery lessons: https://github.com/coderefinery/sphinx-lesson +Empty lesson template to build your own lesson: https://github.com/coderefinery/sphinx-lesson-template

+
+

More questions

+
    +
  • Does the coderefinery.org page built on sphinx?

    +
      +
    • It’s built also from markdown but it uses https://www.getzola.org/ (which is more optimized to render websites, but we could do teaching also with Zola or create the project page using Sphinx)

    • +
    +
  • +
  • Is there a way to build and preview CR lessons without the command line?

    +
      +
    • The GitHub workflow we use creates HTML from all branches. This means that one can push a branch to GitHub, preview it there, and then open a pull request. One thing that would be nice but we don’t have yet is if a bot automatically posts the link to the preview to a pull request.

    • +
    +
  • +
  • For VCS-2, for the Carpentries Linux shell example, Lesson, Github repo, to me it seemed as though the Sandpaper setup they have makes a very nice interface, complicates the relationship between source and output. E.g on the soucre page https://github.com/swcarpentry/shell-novice/blob/main/index.md I could only see to ‘Prerequisits’ and not ‘Download files’ on the page https://swcarpentry.github.io/shell-novice/. Perhaps I have missed something?

    +
      +
    • I am sorry I don’t know the new Sandpaper setup well enough to answer this question.

    • +
    +
  • +
  • Do we have the instructions to build the lessons available somewhere to try out later?

    +
      +
    • https://github.com/coderefinery/sphinx-lesson

    • +
    +
  • +
+
+

Exercise VCS-1 (and VCS-2 (if time)) (https://coderefinery.github.io/train-the-trainer/lessons-with-git/#exercises) in breakoutrooms until xx:05

+

then short summary in main room and then break.

+

Use the notes below. Collect a list of lesson formats and discuss what you like about each of them.

+
+
    +
  • PDF slides by a presentation program

  • +
  • pdf slides with beamer in latex under source control.

  • +
  • Markdown slides via Github

  • +
  • CodeRefinery template

  • +
  • Carpentries template

  • +
  • Google Slides

  • +
  • git-book

  • +
  • Jupyter Book - allows creating a structured reference website using RST/Markdown, including Jupyter Notebooks to show result of running code

  • +
  • mdbook - create simple/minimal website using Markdown

  • +
  • Binder - allows learners to run their own live version of a github repository with Jupyter Notebooks, with only a web browser

  • +
  • Jupyter notebooks and jupyterhub platform

  • +
  • Jupyter + Nbviewer and custom css (read only) + Binder link (hands on)

  • +
  • RMarkdown

  • +
  • Quarto Slides

  • +
  • Reveal.js - write slides in HTML (also supports markdown)

    +
      +
    • Example: https://bl-presentations.erambler.co.uk/2024-02-21-idcc24/

    • +
    +
  • +
  • Remark.js - write slides in markdown

    +
      +
    • Example: https://bl-presentations.erambler.co.uk/2024-02-19-idcc-pids-workshop/

    • +
    +
  • +
+

Room discussions:

+
    +
  • Room 1

    +
      +
    • (https://smc-aau-cph.github.io/SPIS/README.html)

    • +
    • CodeRefinery template

    • +
    • Shared notes & blogs

    • +
    +
  • +
  • Room 2

    +
      +
    • demo the exercise

    • +
    +
  • +
  • Room 3

    +
      +
    • Mix of JupyterLab, Terminal within that, and traditional slides

    • +
    • Jupyter + RISE (benefit: slides that are editable and executable live)

    • +
    • Challenges

      +
        +
      • present code in an interactive way

      • +
      • handle lots of images/ figures without too much additional overhead when setting up the material

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • Material and tools depend on instructors

    • +
    • Some slide building tools

      +
        +
      • https://revealjs.com/

      • +
      • https://remarkjs.com/

      • +
      • https://github.com/rust-lang/mdBook

      • +
      +
    • +
    • Using flat git repos without fancy styling to make it easier to edit but still version controlled

    • +
    +
  • +
  • Room 5

    +
      +
    • Using R as a GIS: https://github.com/nickbearman/intro-r-spatial-analysis

      +
        +
      • Workbook: RMarkdown, Slides: Quarto

      • +
      • No continuous intergration

      • +
      +
    • +
    • Having a jupyter nbinder link to test the notebook

    • +
    • repo lives on codeberg in this example

    • +
    +
  • +
  • Room 7

    +
      +
    • Ex 1:

      +
        +
      • Sphinx, similar to CR

      • +
      • Sometimes pdfs generated with beamer package (or from pptx and odt), but blows up repository size if in version control

      • +
      +
    • +
    • Ex 2:

      +
        +
      • Content

        +
          +
        • CR: Content commonly found int the content folder

        • +
        • SC: Mostly under episodes

        • +
        +
      • +
      +
    • +
    • Question that came up:

      +
        +
      • is CR/Sphinx approach mostly for technical topics? What about language.

      • +
      • I guess by our nature it’s focused there. But probably could be used for others (I guess it it’s much easier to use git in a technical audience.)

      • +
      +
    • +
    +
  • +
+
+
+
Episode 3: How we collect feedback and measure impact
+

Materials: https://coderefinery.github.io/train-the-trainer/feedback-and-impact/

+

Questions to audience

+
    +
  • What tricks/techniques have you tried in your teaching or seen in someone else’s teaching that you think have been particularly effective in collecting feedback from learners?

    +
      +
    • preparing a survey and emailing it to participants as soon as the event ends (usually get <50% of answers but it’s a representative enough sample)

    • +
    • do engage with the audience, give them the time to get the courage to speak up

    • +
    • Be the audience yourself

      +
        +
      • yes! some problems/issues I don’t notice as instructor, only as listener

      • +
      +
    • +
    • Have time (e.g. 5 min) in the session to fill out the feedback form

    • +
    • If the course/workshop has several days/sections do a couple questions every change, then a full one afterwards

    • +
    • “Traffic light” feedback (e.g. for pacing or progress on exercises): give each learner two different coloured post-it notes for in-person, or use emoji for online, to indicate a current status

    • +
    +
  • +
  • Can you give tips or share your experiences about how to convert feedback into changes or actionable items?

    +
      +
    • ask questions about things you know you don’t know

    • +
    • “Don’t let the noise of others’ opinions drown out your own inner voice.” — Steve Jobs

    • +
    +
  • +
  • When people ask questions / get stuck with a specific step. Is there a typo I can change there and then in the workbook?

    +
      +
    • Being able to fix small things on the fly helps sometimes, otherwise open issues if working on github

    • +
    • If multiple people have the same question, then this is an indication that I should look at this in more detail

    • +
    +
  • +
  • How do you measure the impact of your teaching? Any tips or experiences about what you have tried or seen other courses do?

    +
      +
    • “How likely are you to recommend this workshop to others? (0/5)”

    • +
    • Check the ‘Garbage Out’ bin, what you find there will be what went across. The rest will be history…

    • +
    +
  • +
  • Anybody knows of good resources on survey design? Please link them here.

    +
      +
    • “Our job is to figure out what they’re going to want before they do… Our task is to read things that are not yet on the page.” - Steve Jobs

    • +
    +
  • +
+

Questions/Discussion points

+
    +
  • Feedback is necessary to design good lessons. Improvement can only be done iteratively. So the faster the iteration (design/teach), the better. But on the other hand, I cannot constantly bomb our community with training event emails. So I would like to try proposing a course many times a year, but I don’t want to spam everybody many times a year.

    +
      +
    • :+1:

    • +
    • With CR we also have a calendar that can be imported to different calendar applications, where we add all workshops: https://github.com/coderefinery/calendar/

    • +
    +
  • +
  • Does an even split of too fast / too slow mean speed is about right?!

    +
      +
    • I take it to mean “it’s roughly where it should be”. Would be better to accomdate the sides better though… (we do try to design for a broad audience: some easy stuff, some advanced stuff, so people can make their own path)

    • +
    • It could also indicate that the prerequisites/scope are not well defined :+1:

      +
        +
      • Based on long term surveys we also know though that even though the workshop might have been to fast, people appreciate having “heard things before and know where to find them later”

      • +
      +
    • +
    • perhaps the even split between too fast/too slow is ok only if the majority of votes goes for “just right” :+1:

    • +
    +
  • +
  • One of the most important disciplines in journalism is to challenge your working premises. (Bill Keller) This applies equally to learning as well.

    +
      +
    • Participants can be encouraged to write some posts on LinkedIn. If it is helpful some blurbs can be created for pre and post-workshop to generate more traction for Code Refinery and future participation.

    • +
    • Ask participants if they use Dev.to, hashnode etc to blog their work or use twitter etc to have a memory of their work.

    • +
    +
  • +
  • Do you have any suggestions for prerequisites? I try to make them clear, but occasionally people attend who clearly do not meet them. :+1:

    +
      +
    • I guess it depends how much it matters for the workshop itself. If you have group exercises etc, it probably matters? , lecture style maybe not so much?; important is that the participants themselves know that prerequisites exist and if they meet them

    • +
    • Sometimese people that do not meet the prerequisites join to get to “know what they don’t know”, find out where to find information on topics they might get interested in future etc

    • +
    • Other suggestions? Viewpoints? :)

    • +
    • Thank you - things for me to think about there :-)

    • +
    • With CR’s latest ideas, we try to make the prerequisites clear, but there is no capicity limit: it’s OK if people drop by and are less than prepared: it’s livestream, anyone can come. We try to have something for these people, too: learn what you are missing, why you might want to study more in the future.

    • +
    • Any thoughts on applying this to a more practical focused course, with a total capacity limit (i.e. not like CodeRefinery).

    • +
    +
  • +
  • Everytime you do a course on CodeRefinery, think of it as trying to bake a new cake with an old recipe with no idea about the individual taste preferences of the one you bake the cake for. Then, you will not experience too many surprises. Fine-tuning the recipe for one cohort still remains the ‘old recipe’ as far as the next ‘new cohort’ will be concerned. C’est la vie.

    +
      +
    • nice analogy!

    • +
    +
  • +
  • Question from chat: For examples 2 & 4, would you also consider using something like a Likert scale? E.g. Rate how well you agree with the statement “My code is more reusable as a result of attending a CodeRefinery workshop” (from 1 Strongly disagree to 5 Strongly agree)

    +
      +
    • Thanks! I am new to Likert scale and will read up on it. In my experience numbered answers can be useful for reporting. But I also like questions where we ask for what actually to change.

    • +
    +
  • +
  • Comment from chat: Richard, your point crowns the point of having CodeRefinery, With Radovan’s and Samantha’s acquiescence assured, I would like to suggest you wear a crown going forward, especially for the CodeRefinery session. Do we have a deal ?

    +
      +
    • I don’t quite understand this

    • +
    • I think it’s a tongue-in-cheek-comment (joke) but I am not sure…..

    • +
    +
  • +
  • What is the ideal way to allow people to interact while course is going on in the main online session, i.e. without a breakout room? Taking a pause or discussion in the background?

    +
      +
    • I’ve had some success with WhatsApp groups for a course - particually ones that run over 4 (or 2) sessions.

    • +
    • A quick survey/quiz

    • +
    • Question to the audience that we take time to answer but it helps to show the answers

    • +
    +
  • +
+
+
+
+
+
+

Wrapup

+
    +
  • Thank you for active participation :)

    +
      +
    • We’ll continue answering questions after the workshop and make the cleaned up (no names etc) available from the materials

    • +
    +
  • +
  • Next session Tuesday August 20, 9 CEST: Tools and techniques adopted in CodeRefinery workshops

    +
      +
    • we will talk about on-boarding, install help, roles, screensharing, sound, collaborative notes

    • +
    +
  • +
  • All workshop materials will stay available (after the full workshop also on Zenodo :tools:)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • If you want to co-teach with us in the upcoming (or next) CodeRefinery workshop (https://coderefinery.github.io/2024-09-10-workshop/); or just want to learn more about this opportunity: Send your name and e-mail address to support@coderefinery.org; we will contact you!

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • Lesson design approach

  • +
  • I liked the backwards lesson design, gives a name to a practice I’ve already been doing :+1: :+1:

  • +
  • Lessons from code refinery on lesson design. Learning about Sphinx.

  • +
  • Collaborative notes and anonymized archive of notes.

  • +
  • it’s nice to have a community to discuss these kinds of problems

  • +
  • Hearing the variety of tools people use for slides (PDF, Quarto, Beamer etc.)

  • +
  • Good intro of the tools, the jargon and the pedagogical philosophy of teaching tech.

  • +
  • The absolute openess in having everything publicly available - materials ofc but also questions, discussions, feedback, …

  • +
  • Thinking about all content being available publicly and as a git repo

  • +
  • Thanks for explaining the HedgeDoc interface, with view and edit options

    +
      +
    • Is there anyway to come back to this document later (e.g. tomorrow) and see what has changed since now? So I can see if any other questions have been asked/answered?

      +
        +
      • There is a “revision” point under “Menu” up right, which shows you different versions of this document

      • +
      +
    • +
    +
  • +
  • Modesty: the gentle art of enhancing your charm by pretending not to be aware of it. - Oliver Herford

  • +
  • +
+

What one thing would you improve about this session?

+
    +
  • Perhaps some more interactivity but can be hard to plan and time

    +
      +
    • We’ll see what we can do.

    • +
    +
  • +
  • Maybe mix the breakout groups up for each breakout session (although there are advantages to consistency too) :+1:

    +
      +
    • yes, pros and cons! For me, having consistency worked well this time.

    • +
    • Likely we will have different participants next week, and a bit of mixing will happen naturally.

    • +
    +
  • +
  • The pace of the presentations could be a little tighter (the pace is good for a discussion though)

  • +
  • Richard’s voice was only 80% audible

    +
      +
    • Sorry to hear that. It seemed fine on my end. Will check better for next session.

    • +
    +
  • +
  • Hands on simulation and collaborative notes

  • +
  • I found it difficult to follow the presentation and the collaborative notes at the same time

    +
      +
    • We will highlight the collaborative notes more in the next session. Our strategy usually is to say to focus on the “teaching part” and use the notes only when needed. Since you can go back and also check the notes later.

      +
        +
      • My problem is that I want to follow both since I don’t want to miss out on anything. As such, I have both windows (zoom and the notes) open side-by-side. Since there is near-constant real-time typing in the editor, and as such visible movement on screen, I get constantly distracted. This makes following the event quite exhausting.

      • +
      +
    • +
    +
  • +
  • Heads up to participants on using the break out rooms on voice interaction and screen sharing.

    +
      +
    • Do you mean that we should have mentioned it more clearly in the pre workshop email?

    • +
    +
  • +
  • I found it hard to follow with so many things going on at once…

    +
      +
    • A collaborative document being changed at the same time as…

    • +
    • Someone speaking and explaining content at the same time as…

    • +
    • Chat in a different application at the same time as…

    • +
    • Content changing in a termin application.

      +
        +
      • Thank you for the feedback. We will remove the Zoom chat out for the next session and explain the use of the collaborative notes more.

      • +
      +
    • +
    +
  • +
  • Make more use of defining and then making sure the learning objectives are met

    +
      +
    • True we did not talk about them much, will pick that up better for next session.

    • +
    +
  • +
  • UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. - Dennis Ritchie. You need to do a lot to prove that to be wrong, simply put.

  • +
  • Allocate some time for learners to type in the answers so that we don’t have to listen and type at the same time.

  • +
+

Any other comments?

+
    +
  • It’s great to hear other people’s experience

    +
      +
    • Good to hear :)

    • +
    +
  • +
  • Looking to meet you onsite if there are any events and get more emails from you :)

    +
      +
    • We will keep you informed :)

    • +
    +
  • +
  • Thanks for putting this together, I got a lot of inspiration for my own courses

    +
      +
    • Good to hear :)

    • +
    +
  • +
  • I didn’t know where to ask questions. It would work best for me to do it in zoom chat as that’s the application that I’m watching in..

    +
      +
    • Sorry for that, just to figure out why: Did you join a bit late?

      +
        +
      • No. Perhaps I just missed that or it was too quick for me or something?

        +
          +
        • Ok, sorry. Will try to make this more clear in next session.

        • +
        +
      • +
      • Perhaps also because there were so many things going on and jumping around. For me, the zoom chat is the constant (and obvious) place to ask questions while watching a shared screen, trying to find the right place in a moving collaborative document is difficult. It tears my attention into too many pieces. :+1:

      • +
      +
    • +
    +
  • +
  • Had a lot of content that assumed extant knowledge that I didn’t have. This wasn’t in the pre-requisites.

    +
      +
    • Do you have examples?

      +
        +
      • Yes! The code refinery templates and even just the way of doing that. I was expecting more on “when designing a lesson you should think about these steps” rather than this is how we do it and this is our tool for doing it. I guess I should have read the pre-workshop content better?

      • +
      • Ok, thank you for your feedback. You are right that we actually had some content that for sure would have been easier to follow for people with background knowledge about a certain topic.

      • +
      • “If you are in CodeRefinery TTT, you probably know what version control is and why it is important.” - extant knowledge, why not just add a sentence or two?

        +
          +
        • Please can you update in preparation for the next workshops so that I can decide whether or not they will be right for me?

          +
            +
          • Yes, we will think more thoroughly about this and send the info in the next email going out Wed/Thu

            +
              +
            • Thank you!

            • +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • Lots of the content was relevant to code refinery but not the wider topic (e.g. it was how to design a code refinery lesson and not how to design a lesson as stated in the session title)

    +
      +
    • We thought of the content of showing one way of doing things, ie “what we have learned”, if you have suggestions on how we could make that more clear on the event page, please let us know :)

      +
        +
      • “in a code refinery lesson” in the lesson/workshop description?

      • +
      +
    • +
    +
  • +
  • When you have pre-written “thank you for your active participation” it feels fake!

    +
      +
    • He, that is true, did not think about that. Thank you for the feedback. I would not have added it if Radovan and Richard would not have provided good feedback from circling the rooms.

    • +
    +
  • +
  • I found it vague and disorganised and difficult to follow. It felt like the instructors were presenting the content for the first time and didn’t know what to do next.

    +
      +
    • Thank you for your feedback. This is not the first time we have this training, but it is the first time in this constellation/way. The way of teaching may also sometimes make it seem new to instructors.

    • +
    +
  • +
  • I really liked the active exchange with other participants, but I also would have enjoyed a bit more technical content in the presentations. In a sense it felt less like a ‘training’ and more like a get-together :+1:.

    +
      +
    • Thank you for your feedback. We thought the name “workshop” would combine the training and exchange nature of this event. But maybe it didn’t do so enough? Do you have suggestions on how to clarify it on the event page?

      +
        +
      • Well, the ‘train the trainer’ title created the anticipation of being trained ;) don’t get me wrong, I liked the exchange, but I felt that the training aspect fell a little short. imho the workshop would benefit from a little more (instructional) content that is presented in a more structured way by the instructors (as opposed to ‘crowd-sourced knowledge’ that is collated in a loose collection of questions, notes and links)

      • +
      • Other than that, you could add another section on the main page, sth like ‘Workshop structure: we aim for a mix of modular presentations and work in small groups. The latter will be done in breakout rooms - be prepared to switch on your camera and have a fruitful exchange with fellow participants!’

        +
          +
        • Thank you for the suggestions, will add something like this :tools:

          +
            +
          • +

            Added : https://github.com/coderefinery/train-the-trainer/commit/03308595436e636b3bb37ed9d1f0dee39eeccd0f

            +
            +
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • My understanding (so far) of what (unlike the competition) CodeRefinery DOES NOT seek to exemplify - +https://images.ctfassets.net/rxqefefl3t5b/2k45BFtw4sBMlBfjr1OZ90/5c6ecd3628a43b0cdc79815f665e224a/Screenshot_2023-05-02_at_09.35.23.png?fl=progressive&q=80

  • +
  • My understanding of what (unlike the competition) today’s session of CodeRefinery DID exemplify - Definition of ‘Workshop’ from the Oxford dictionary of the English language “a period of discussion and practical work on a particular subject, in which a group of people share their knowledge and experience”

  • +
  • In my experience, even for the most seasoned Programmer coding, by its very nature, is nothing trivial, this being a simple straightforward fact just like there is no such thing as an egg which is a cube. I mean there is a reason why not just about everybody is a poet either. But, other minds have pointed this out without having to first explain why the universe is what it is in a way that could be understood without effort … https://i.pinimg.com/originals/7b/7e/c4/7b7ec4b91d2cf9d8e1b064678d205467.jpg

  • +
  • The inclusive environment feels very welcoming. Keep up the good work!

  • +
+

Thank you all for your feedback! Highly appreciated!

+
+
+
+

Day 2 : Session 2 (20.08.24)- Tools and techniques adopted in CodeRefinery workshops

+
+
:calendar: Schedule
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 9.25

About CodeRefinery workshops

10.15 - 10.25

8.15 - 8.25

9.25 - 9.55

Collaborative notes and interaction

10.25 - 10.55

8.25 - 8.55

9.55 - 10.10

Break

10.55 - 11.10

8.55 - 9.10

10.10 - 10.45

Workshop overview, roles, onboarding

11.10 - 11.45

9.10 - 9.45

10.45 - 11.05

Sound

11.45 - 12.05

9.45 - 10.05

11.05 - 11.20

Break

12.05 - 12.20

10.05 - 10.20

11.20 - 11.50

How to prepare a quality screen-share

12.20 - 12.50

10.20 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+
:icecream: Icebreaker
+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :-)

  • +
  • https://media.istockphoto.com/id/148421550/vector/bored-emoticon.jpg?s=612x612&w=0&k=20&c=uo5KBTqdJZbBQb_Xldhzuovx5t08fHfGR7dw7TCk90I=

  • +
  • :saluting_face:

  • +
  • :sleepy:

  • +
  • :coffee:

  • +
  • :umbrella:

  • +
  • :cocktail: :coffee:

  • +
  • :seedling:

  • +
  • :tired_face:

  • +
  • :sun_with_face:

  • +
  • 🥴 (:woozy_face: not converted?)

  • +
  • :coffee:

  • +
  • :sunflower: :book:

  • +
  • :satisfied:

  • +
  • :coffee:

  • +
  • :coffee:

  • +
  • 🥱:tired_face:

  • +
  • :bread: - I am baking bread today so I have been kneading dough while listening!

  • +
+
+
+
Introduction in breakoutrooms
+

Name / Affiliation / Location

+
+
+
Teaching
+
    +
  • Do you teach and organize teaching alone or with others? What would you prefer and why?

    +
      +
    • Coming together is a beginning; keeping together is progress; working together is success. – Edward Everett Hale

    • +
    • These days always with others. Alone is easier to prepare but almost always is harder during it.

    • +
    • Teaching with very diverse partners, it can be challenging to find a common language with people very different than you.

    • +
    • I teach alone, in the future there will be more collaboration with multiple team members. Both approaches have their pros and cons.

    • +
    • Both has its own distinct advantages

    • +
    • Most of my teaching is on my own, as a freelancer its more expensive to work with colleagues than to deliever a course on my own.

    • +
    • Teaching together, learns from each other, feedbacks to improve

    • +
    • Not formally taught yet, only given presentations actually .

    • +
    • collective teaching would benefit the teachers with collaborative curriculumn and experiences sharing.

    • +
    +
  • +
  • If applicable, have you seen any challenges when teaching together and how to overcome them?

    +
      +
    • It actually requires preparation,

    • +
    • Is it about teaching or about inspiring ? Discover the answer and get inspired …

    • +
    • It’s like being in a band: you might be great at improvising and your band-partners might be great at improvising too, but a bit of rehearsing makes even the impro gig much better

    • +
    • Need to plan before session, difficult if people don’t ‘plan’ in the same way, e.g. with the same time frame.

    • +
    • Heterogeneity in learners make it impossible to get the same result from everyone.

      +
        +
      • In fact, the same applies to teachers :D

      • +
      +
    • +
    • Teaching together requires to have similar opinions on how to teach. I share vews only with ~40% of my colleagues I think.

    • +
    +
  • +
  • No Teaching experience but it is good to give the outline of the lessons beforehand and learning goals.

  • +
+
+
+
+
+
:question: Questions
+
+
General / Practicalities
+
    +
  • What is this document for?

    +
      +
    • Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts)

    • +
    +
  • +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms?

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    • BR 1 : The Zoom chat does not work for the breakout room so we should take note of that. No webcam/mic = expect silence.

      +
        +
      • Thanks for notifying! This was not intended. Turned the chat back on.

      • +
      +
    • +
    +
  • +
+
+
+
+
+
Episode 1: CodeRefinery
+

Materials: https://coderefinery.github.io/train-the-trainer/coderefinery-intro/

+
    +
  • (questions continue here)

  • +
  • Is there the plan to build capacity / be paid to deliever courses?

    +
      +
    • We’ve discussed it but right now we don’t have many people who could accept money to do this (and maybe shouldn’t, because of their jobs). But, we would encourage others to use our materials as “independents” to deliver paid courses

    • +
    • One idea we have had is that paid courses could be delivered through the DRA (link below), who we know. Basically, DRA could find instructors and handle the money transfers (If someone wanted a paid course, we could help find someone to do it through DRA or independently)

    • +
    • :smile:

    • +
    +
  • +
  • Have you come across DRA, https://digital-research.academy/, Heidi Seibold, Joyce Kao who are doing similar work? I can connect you if you like.

    +
      +
    • Yes we have been discussing about possible future collaborations and are already sending possible clients their way (we, as a project cannot take money) :+1:

      +
        +
      • Excellent! :-D :smile:

      • +
      +
    • +
    +
  • +
  • .

  • +
+
+
+
Episode 2: Collaborative Notes
+

Materials: https://coderefinery.github.io/train-the-trainer/collaborative-notes/

+
    +
  • So anyone can type anonymously?

    +
      +
    • Yes, as long as you do not log in, you are Guest XXX

    • +
    • And at least in our hedgedoc case you cannot log in so you will always be anonymous. You can do [name=xxx], to add your name to a comment

    • +
    +
  • +
  • Test of +1

    +
      +
    • +1 :+1: :+1:

    • +
    • :-1: a test

    • +
    +
  • +
  • You are hosting your own version of HedgeDoc, and Hackmd.io is a similar (free) option. What are the limitations of the free hackmd.io? Should each center install their own HedgeDoc instance?

    +
      +
    • It seems the free version of HackMD has gotten worse lately. It works still well enough with a few people editing at the same time.

    • +
    +
  • +
  • Have there every been problems with the anonymity and CoC?

    +
      +
    • We haven’t had any issues so far.

    • +
    • With a different anonymous tool in a bachelor course, we had issues with anonymous participants (participants were posting slurs and unsafe links). The course organiser decided to stop allowing anonymous tools.

    • +
    +
  • +
  • Why not google documents?

    +
      +
    • Google documents are actually setting a hard limit for simultaneous writing, no more than 100 concucurrent editors. I am unsure if microsoft onedrive word documents would allow more users writing at the same time.

    • +
    +
  • +
  • What’s the most people you have every had on HackMD / Hedgedoc?

    +
      +
    • I believe about 200 active participants?

    • +
    +
  • +
  • What are your thoughts on using the build-in Zoom Q&A?

    +
      +
    • We haven’t tried this, in part because the way we do streaming now (you’ll see in session 4), participants aren’t in Zoom so don’t have access to that. The doc-format works pretty well though, when we keep it in this limited “write at end” format.

    • +
    +
  • +
  • How do you see what has changed? e.g. if leave the session at the end, can I come back tomorrow and see X has been added? e.g. a diff for this maybe?

    +
      +
    • In the menu up right there is revision, it does show the document and changes at different time step :+1: Thanks!

    • +
    • We recommend people only write at the bottom (and since we answer things live), so as a first level approximation you find where you were and read below that. Think of it more like chat than a full document. (Yes, we do revise questions at the end)

    • +
    +
  • +
  • How about flinga boards or similar tools?

    +
      +
    • My take is that the simplicity of a simple text document wins over free-form in-person-workshop-like tools.

    • +
    • There’s miro, can be a bit confusing though

    • +
    +
  • +
  • How does this work with small groups, e.g. 10-15 people?

    +
      +
    • Good question: it can be hard if people aren’t rigorous about it, people start only using chat/voice. So there seems to be some lower bound in size but we haven’t tested this much

    • +
    • And if the instructors never screenshare it to show what goes on it, then seems to be less used.

    • +
    • And if there aren’t other people to read/answer it during the session (perhaps less likely in a small course), it seems to be less used.

    • +
    +
  • +
+
+

Breakoutrooms until xx:55

+

Exercise/discussion: https://coderefinery.github.io/train-the-trainer/collaborative-notes/#exercise

+
+
    +
  • Breakout room 1:

    +
      +
    • Use of etherpad for collaborative discussion.

    • +
    • Use of slido for polling and quizzing.

    • +
    • Presemo as a slido alternative (https://www.aalto.fi/en/services/presemo-a-fully-web-based-classroom-participation-system)

    • +
    • Use of text based approach for questions rather than live can be helpful if there is a language barrier issue.

    • +
    +
      +
    • A good teaching session which had many questions coming spontaneously to the teacher is a non-entity of sorts. If the overall flow of feedback / questions increases it could indicate that the session will not prove to be a helpful experience. A signal that generates noise is, well, noise, if calling a spade a spade signals anything. Note that the ‘overall’ bit and the ‘to the teacher’ aspect are important. Both the best and the worst teaching session have two things in common: a teacher, and the fact that NO Materials of any kind are used, ie speech is the only channel of communication via a common language. The only difference is that it is not the same teacher, at least not in the same session at the same time.

    • +
    +

    Another less mentioned, but perhaps more relevant indicator of a great session is the simple fact that at the end of the session EVERYONE feels empowered, NOT tired. This is not an easy to quantify thing, but screams out the quality of the experience loud. More often then not, such sessions differ little from each other, apart from in terms of the theme / topic and the participant mix. It ends up being the ‘keep your cake and eat it too,’ of sorts, not quite the far less amusing post-bombardment devastation scenario in the wake of a take it or leave it go at anything.

    +
      +
    • profanity in collaborative documents where people can add content anonymously could be a problem (happens very rarely, fortunately and somewhat surprisingly)

    • +
    +
  • +
  • Breakout Room 2:

    +
      +
    • Good experiences with Zoom polls

    • +
    • Handling questions in hybrid setups: all participants (on-site and online) ask questions in written form

    • +
    • Collaborative notes can be challenging when conducting a course alone (without teaching assistants) :+1:

    • +
    • Providing a method to ask questions anonymously can make asking easier for shy participants

    • +
    • Questions can give valuable feedback on how the course is going

    • +
    • Online collaborative whiteboarding platforms such as Miro

      +
        +
      • Large monitors are useful for this not to have to drag a “periscope” around

      • +
      +
    • +
    +
  • +
  • Room 4

    +
      +
    • good experience with whatsapp chat for questions. since most learners have the app already and one thing less to install and set up

      +
        +
      • reply to question is a way to handle multiple questions at the same time but it works well for smaller groups

      • +
      +
    • +
    • experience with collaborative docs in in-person workshops: voice questions might “win” over the document

    • +
    • “seeding” questions may help to not have an empty document

    • +
    • it can help somebody to start and create a structure which helps others to see and follow

    • +
    • we discussed the Carpentries sticky notes system (red sticky note: signal tech issues and use for feedback, green sticky note: signal that exercise worked and for positive feedback)

      +
        +
      • Nice summary of sticky notes system: https://teachtogether.tech/en/#s:classroom-sticky-notes :+1:

      • +
      +
    • +
    • What is the success rate of in-person workshops after COVID? Discussion: Teachers prefer in person and learners prefer remote or recorded to spool back and relearn.

    • +
    +
  • +
  • Room 5

    +
      +
    • Good experience with Collaborative tools as HackMD and HedgeDoc while teaching with no bad feedback

      +
        +
      • When used with smaller groups works best as one-way, like sharing links with students and so on

      • +
      • Needs to be done as a team, quite difficult if teaching alone

      • +
      • Most useful when online/hybrid

      • +
      +
    • +
    • Anonymisity is important for transparent feedback and no biasis in classrooms

    • +
    • Not very collaborative but useful to share history or jupyter notebooks live https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush

    • +
    • Used Flinga before that seems like Figma and also onsite teaching using sticky notes

      +
        +
      • There’s miro.com but can be a bit confusing, more for brainstorming than for teaching

      • +
      +
    • +
    • Using quizzes apps like Kahoot is beneficial while teaching to have more engaging students

    • +
    • +
    +
  • +
  • Room 6

    +
      +
    • teaching teenagers (in presence) but using shared pad becomes quickly very chaotic, so only usable for short moments when answering very precise questions

      +
        +
      • Yeah, I can imagine. For CR we try to keep it in this very limited format (all questions bullet points, only add to the end) and I think that helps.

      • +
      +
    • +
    • using shared notepad for small workshop (5-10 people) to explore common thematic (mainly technical) to keep a shared notes and condense aftwerward (and publish on wiki to archive)

    • +
    • Difference between teaching in person and online. Some people prefer in-person and sometimes you have no option but to organise it online.

    • +
    • There are sometimes cultural differences and learners feel shy to ask / question the knowledge of the Teacher, so shared notes are a good way to safely ask questions.

    • +
    +
  • +
+

Questions continue:

+
    +
  • Have we demonstrated how we do polls in HedgeDoc? Add your vote by adding an o

    +
      +
    • yes: oooo (in session 1)

    • +
    • no:

    • +
    • :smile:

    • +
    • not sure: o

    • +
    +
  • +
+
+
+
Episode 3: One workshop, many perspectives
+

Materials: https://coderefinery.github.io/train-the-trainer/overview/ +Next CodeRefinery workshop in September: https://coderefinery.github.io/2024-09-10-workshop/

+
+

Exercise until xx:39

+

https://coderefinery.github.io/train-the-trainer/overview/#discussion

+
+
    +
  • Room 1

    +
      +
    • Send pre-workshop email with pre-requisite instructions on what should be set-up beforehand.

      +
        +
      • But, also mention that if help is needed for set-up, we will be ready before the session officially starts.

      • +
      +
    • +
    • Discussion on whether we push to work in a pre-ready environment (e.g. Binder, Colab) or in their own environment.

    • +
    • Lots of help needed both before and after.

    • +
    • Installations: as much as we can provide ready made environments for the learners, maybe installations will be something that the learners will face sooner or later. Maybe one should teach more about installations?

    • +
    • My only cherished role in a teaching-learning session is the that of one who is living the moment as if there were no tomorrow. What cuts all ways really is that “By failing to prepare, you are preparing to fail.” ― Benjamin Franklin. A helpful motto: “When one teaches, two learn.” — Robert Heinlein. The best experience cannot be given, it can only be allowed to flow its way, so get out of its way.

    • +
    +
  • +
  • Room 2

    +
      +
    • Frequently, a single person fills all the roles for a single or multi-day workshop

    • +
    • Collaboration with different centers/ universities can be challenging

    • +
    • Preparing participants: it’s essential for the instructor to go through the demos and be sure that they will work (no unpleasant surprises live). This can be extended to advance-prep for participants.

    • +
    • Best experience is to hear (live or in feedback notes) some positive things directed at you :)

    • +
    • Fully prepared environments (eg self-hosted JupyterHub) can make preparation for participants easy

    • +
    +
  • +
  • Room 3

    +
      +
    • Some students have problems with setuping the environment. Maybe having a step by step instructions could help. But some students don’t want to “start” the course before hand.

    • +
    • Preparing the environemnt before hand ensures everyone is onboard from day 1. The same thing happend in CSC training sessions and another session Peng attended.

    • +
    • Had experience in attending as teacher and student in previous workshops

    • +
    +
  • +
  • Room 4

    +
      +
    • knowing the background of the audience is helpful

      +
        +
      • Try and ask in advance of the background of the audience. Do a poll at the start of the workshop. In person one can do it interactive.

      • +
      +
    • +
    • among co-instructors: discuss topics and flow

    • +
    • if more people are involved, it can help changing roles from time to time to see different perspectives

    • +
    • preparation is key

    • +
    • Circulate instructions beforehand

      +
        +
      • Do a poll before session: Have you installed (QGIS) successfully?

      • +
      • Push hard to do this in the welcome email

      • +
      +
    • +
    • communicate clearly to the participants

    • +
    • +
    +
  • +
  • Room 5

    +
      +
    • We’ve all taken most roles

    • +
    • How to prepare in advance?

      +
        +
      • Meet and discuss once or twice

      • +
      • Make a pre-survey to check for interest and background

      • +
      • Going through the materials

      • +
      • Checking the toolkit (zoom)

      • +
      • Agree on the reponsibilities and back-up plans (bit of scenarios planning)

      • +
      +
    • +
    • How to prepare trainings in advance?

      +
        +
      • Collect resources and prepare the workshop plan

      • +
      • Having the material readily available online ans sharing it

      • +
      • Making a pre-survey

      • +
      +
    • +
    • What was the best workshop experience for you as learner, helper or instructor? What made it great?

      +
        +
      • learner

        +
          +
        • Engaging and practical workshop with more exercices and follow-up theoretical part explanations

        • +
        +
      • +
      • helper

        +
          +
        • When the instructor is well prepared and as helper ther’s only typos to fix and interesting questions to answer

        • +
        • Assist the instructor, coordinate the collaborative notes, and make sure that the time is respected

        • +
        +
      • +
      • instructor

        +
          +
        • I have a colleague whom I’ve ran the same workshop a few times already, goes quite smoothly now and we’ve made a few changes. Hard to reach that point with new colleagues but getting there

        • +
        • Students/participants were engaging with the material and many good feedback collected even some of them asked for the next workshop

        • +
        +
      • +
      +
    • +
    +
  • +
  • Room 6

    +
      +
    • What has made a great experience for you as a learner/helper/instructor?

    • +
    • Common ground between learners & teachers

      +
    • +
    • Motivation

      +
        +
      • Teaching is much more enjoyable when the learners want to be there

      • +
      • I spend a lot of time at the start of a workshop making sure learners feel that the content is possible for them to understand and master

      • +
      +
    • +
    +
  • +
+

Poll: I have joined a CodeRefinery workshop before: (add an o for your answer)

+
    +
  • yes (within last 2 years): ooooooo

  • +
  • yes (longer time ago): oo

  • +
  • no: oooooooo

  • +
  • +
+

(questions would continue below:)

+
    +
  • What is the motivation / advantages of streaming workshop versus using zoom?

    +
      +
    • We’ll cover this more in week 4, but roughly: zoom became unmanageable and essentially quiet once things got big. Streaming allowed “one to many” communication with no limit, and collab notes allowed better interaction anyway. By separating the rooms, it was more pleasant to teach. Videos could be released immediately since there was no risk of privacy of participants. There could still be in-person/online small groups who have “watching parties.”

    • +
    +
  • +
  • What are the blue red and green font colors here, does it symbolify anything or just a convention HedgeDoc uses?

    +
      +
    • Visual separation of formatting, mostly. (It helps to quickly realize you’ve missed/ mistyped a control Markdown symbol etc.)

    • +
    • Yeah, it’s bascically “code highlighting” for markdown. No special meaning but quite convenient for us.

    • +
    +
  • +
  • Is this next workshop only for team leads or also open for helpers and coordinators?

    +
      +
    • You mean the next session of this workshop or the upcoming “CodeRefinery workshop”(this one: https://coderefinery.github.io/2024-09-10-workshop/)?

      +
        +
      • The upcoming workshop coordinators are alredy working, but can be joined if you are interested

      • +
      • As helper roles we currently only have “collaborative notes helper”, which is all about helping to answer questions in the collaborative notes

      • +
      • We do have some co-teaching slots open :)

      • +
      • If interested: join the discussion in our chat: https://coderefinery.zulipchat.com/#narrow/stream/316508-coderefinery-tools-workshop/topic/Fall.202024.20CodeRefinery.20workshop

      • +
      +
    • +
    +
  • +
  • Can a person have multiple roles in a workshop as a helper and a teacher?

    +
      +
    • Yes, many teachers also contribute to the rest of the workshop by answering questions in collaborative notes. :+1:

    • +
    • Some teachers also host a local classroom in week one and do their teaching in week two of the workshop

    • +
    • Roles that do not go well together are broadcaster/director/host and instructor (goes well until there is a problem; co-teaching solves that partly)

    • +
    +
  • +
+
+
+
Episode 4: Sound
+

https://coderefinery.github.io/train-the-trainer/sound/

+
    +
  • To me, Richard is a bit quieter than the other two :+1: :+1: :+1:

    +
      +
    • to elaborate: I think that the audio coming from him is missing some mids

    • +
    • Do you have any links about this kind of evaluation and adjustment?

    • +
    +
  • +
  • Do you suggest / recommend a specific headset(s) with mounted microphone?

    +
      +
    • in our experience headsets with a microphone will almost always be better than a separate microphone sitting on the desk or in the monitor

    • +
    • +
    +
  • +
  • Speakers have different tones of voice and speaking styles, is there a recommendation or experience from CR workshops for how this is adjusted and catered to environemnts for listeners?

    +
      +
    • Yeah, people’s voices are different and we haven’t gone as far as voice training or improving.

    • +
    +
  • +
  • How to change the volume for speakers? Tried Zoom settings and system settings and didn’t help.

    +
      +
    • From linux I can use different pulsemixers pavucontrol, pulsemixer to set the gain to above 100%. I’m not sure the equivalent on other OSs but

    • +
    +
  • +
+
+
+

Exercise until xx:10 +https://coderefinery.github.io/train-the-trainer/sound/#exercises

+
+
    +
  • room 1

    +
      +
    • Practically, no typical headset is designed or can capture the technical purity of human voice within its natural environment. But one needs to understand the polar pattern of the (specific) microphone or how much of the signal will be picked up by the microphone from different directions, a sine qua non when it comes to mitigating unwanted sound sources to bleed into the signal.

    • +
    +
  • +
+

For best results, keep the right direction & distance to your (directional) mic. Usually, that’s between 15-30 cm to get get a natural sound. A microphone records everything it can, also silence, so check the headphone output BEFORE adjusting the gain, in some specific cases aim for a dry sound, ie the influence of the room or how audible the room is on the recording ! Finally, adjust the mix between dry and room sound, or change the frequency response in tandem using a compressor to reduce the dynamic range of a signal for a more consistent listening experience = the quietest parts of your signal will appear louder by reducing the loudest parts.

+

It is all about one thing and one thing only - love your voice, let people fall in love with the acoustic quality of your charm. So remember: GIGO, it matters!

+
    +
  • Room 3

    +
      +
    • Had different headsets and we could see the difference (bluetooth low quality)

    • +
    • How to change the volume?

      +
        +
      • It’s surprisingly hard to get more control than the basic slider you see in the apps! You need to look.

      • +
      +
    • +
    +
  • +
  • room 4

    +
      +
    • headset is probably better listening experience but they can be uncomfortable to wear during long meeting days :+1:

      +
        +
      • Yeah. Luckily only instructors

      • +
      • Therefore breaks are non-negotiable

      • +
      +
    • +
    • loud keyboard can be an issue

    • +
    • if one has a silent room that does not echo, it can be ok to teach without headset

    • +
    • on Linux I am using pulsemixer to adjust levels and pavucontrol to change outputs/sources

    • +
    • mic modes on mac

    • +
    • check default microphone for zoom.

    • +
    +
  • +
  • room 5

    +
      +
    • Most tricks help tuning yourself but hard to do it as a group. Perhaps doing a short recording.

      +
        +
      • Yeah. Some independent recording/playing aronud, but also asking for advice. I would do small group/one-on-one things.

      • +
      +
    • +
    • Background noises cancellation tools or wise choice of quiet environments

    • +
    • Audio check with colleagues or through the app with the audience saying numbers for example

    • +
    • Zoom or Teams have sound checks but work different in the app than the browser. They also work different across Operating systems

    • +
    • Some sound issues might be related to network speed or stability, also to RAM available. Worthwhile to try and control those as well

    • +
    • Make it welcoming for the audience to give you feedback on the audio and other settings, give reminders

    • +
    +
  • +
+
+
+
Episode 5: How to prepare a quality screen-share
+

Materials: https://coderefinery.github.io/train-the-trainer/screenshare/

+
    +
  • If your Zoom does not support “share portion of screen”, sharing a tab and resizing it to portrait for yourself is a possible workaround (this at least works when joining the call from Chromium browser)

    +
      +
    • Another workaround is to use an editor/IDE that displays multiple panels in one window and can show a web page, code files and terminal session +10

    • +
    +
  • +
  • Is ‘share a portion of your screen’ where you draw a box in Zoom to share a section?

    +
      +
    • yes :+1:

    • +
    +
  • +
  • When using zsh, one can run something like this in a terminal

    +
    tail -n $NLASTCOMMANDS -f ~/.zsh_history | sed 's/^.............../LAST COMMAND:/g'
    +
    +
    +

    (I place this in a window under the main terminal, I use i3)

    +
  • +
  • I am a bit confused on what platform you are putting this code?

    +
      +
    • Radovan is using Linux with (I think) the “i3 window manager”. It can be quite involved and there is lots of personal customization here.

    • +
    +
  • +
  • When teaching with a custom prompt, is it worth starting with the default (that your learners will see) and explicitly mentioning “I change these things to make it clearer when teaching”

    +
      +
    • One should always comment on what may be different. Thing is “default” may look different for many people :+1:

    • +
    • “I am not going to teach you how to customise your prompt, but here’s an online tutorial, be prepared to lose several days of your life…” :laughing:

    • +
    +
  • +
  • Now I can’t see the last line in the terminal

    +
      +
    • Yep, that’s a problem. It can be good to keep a buffer on the bottom of the screen.

    • +
    • If you move your mouse outside the Zoom window, the controls should go away. But still a good note.

      +
        +
      • My mouse was on another screen.

      • +
      • Ok, thanks.

      • +
      +
    • +
    • I think one can also make the zoom bars not auto-hide (then it won’t display under), but that is annoying also since it wastes space.

    • +
    +
  • +
  • Does anybody still use shellshare? Does it work?

    +
      +
    • We in CR haven’t used it much but we have seen it.

    • +
    +
  • +
  • Does the stacking of the screens work on windows?

    +
      +
    • Don’t know unfortunately

    • +
    +
  • +
+
+

Exercises (done together) +https://coderefinery.github.io/train-the-trainer/screenshare/#exercises

+

Write your cool tips and ideas below. +Stay after xx:00, to

+
+
    +
  • To be safe, I have created on my computer an account that I use only for teaching, so I do not need to do any manual set up

  • +
  • share history or jupyter notebooks live (5-10 secs refresh rate) into a git repo. Share the link with the learners so they can catch up https://github.com/mwakok/software_carpentries?tab=readme-ov-file#set-up-gitautopush

  • +
+
+
+
+
+

Wrapup

+
    +
  • Next session Tuesday August 27 9 CEST: About teaching & cool things we all would like to share

  • +
  • All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • Cool gems session: If you want to share something, please edit your registration and fill it in there (link to modify in registration confirmation); or e-mail to support@coderefinery.org

  • +
  • If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14:00 (Europe/Stockholm time)

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • Sound and screen share optimization as well as relevant tools and good practices for online instruction. “While you may be unable to control your users’ mindset, you can anticipate it, and make sure that your user experience caters to it.” - Jonathan Cherki

  • +
  • Nice opportunity to (re)think about my online teaching setup :+1: :+1: :+1:

  • +
  • Other ways to display command history :+1:

  • +
  • Did not know that bluetooth gear had so much latency! :+1:

  • +
  • A good reminder about headsets with microphones

  • +
  • Nice and friendly teaching. Thank you!

  • +
  • Screen share with command history and terminal customisation

  • +
  • Really useful tips on sound and screen sharing :+1:

  • +
  • Nice experience share

  • +
  • very useful and practical tips!

  • +
  • Easy to follow along and filled with useful tips on sound, video etc.

  • +
  • +
+

What one thing would you improve about this session?

+
    +
  • Just digging to find something: I have read some of the things you have talked about here already in some blog posts, so perhaps these sessions are not as shokingly full of new content as I imagined (but actually sharing experiences is something I can’t do by reading a blog post)

    +
      +
    • Perhaps: could you link some blog posts or other sources for what you have discussed so far? If it makes sense. Not sure.

    • +
    +
  • +
  • Talking about interface optimization approaches, which applies to sound as much as to visuals or any other aspect either for that matter, it might offer a perspective to bear in mind the concept of introducing asymptotic complexity increment. The latter would mean the goal is measuring how fast the effort of engaging, on one or more of the three parallel levels of interaction, must change to reach higher levels of partial certainty on the correctness of the implementation of the method in question, in this case the pedagogical paradigm. For the former, lower is better I guess, or in this case, in the intended sense, slower is faster. Let us consider an abstract example: People liked using the search engine Google (a Google session to put it in a fancy way) in the early days because it was as simple as it could get, a literally featureless entry point with no bells and whistles. That was the level of its visible complexity, or rather Google set a bar as low as it one could have, and then any higher point of VISIBLE complexity that was to be introduced, such a move would only be on the path of an asymptotic curve curving towards the set bar, never reaching it, as far as the entry point is concerned. We still see the same level of complexity when we fire up google and we never feel distracted to start with, except for the rather forgivable nuisance of the GDPR conformity pop-up notice which appears only AFTER the first move has been made, and thankfully it works plain and simple from there on (unless one starts feeling lucky, pun intended). Now, think about Youtube … the user experience complexity is a totally different matter, the same company today (unfortunately) yet one now has a steadily worsening engagement experience. Good learning sessions tend to be more of the Google search engine experience and a far cry from the current Youtube trend I would opine. Or, to sum it up and keep it sweet and simple, it helps to identify the limits of human-human and human-technology interaction, within the framework of any applicable technology-technology interaction and joy is the result of respecting those limits. Wishful thinking ?

  • +
  • Bring the cat back!

    +
      +
    • I wish it came, but it’s been resting all morning! I don’t bother it or stage apperances…

    • +
    +
  • +
  • Maybe having a digest/ summary of previous iterations of this session might be interesting. I feel a lot of experiences have been exchanged and a lot of techniques/ tools have been mentioned. Spending some time in compiling this into a selected list and adding it as content to the course itself might be worthwhile.

    +
      +
    • Good idea! We will write a blog post about this workshop and will include a summary of all discussions there :)

    • +
    +
  • +
  • Possibly have some command line examples from Windows rather than (just) *nix? I will look at the screenshots after the session. :+1: :+1:

    +
      +
    • Also, a thought if you do do breakout sessions with this work, do one for Unix, one for Windows, one for Mac as an option.

    • +
    +
  • +
  • I could not follow the part Radovan showed codes (Radovan is using Linux with (I think) the “i3 window manager”.)

  • +
  • ..

  • +
+

Any other comments?

+
    +
  • Looking forward to the topics of following sessions.

  • +
  • Looking forward to the next sessions!

  • +
  • Thank you!

  • +
  • Relax, nothing else matters, live a life and have fun ! If you obey all the rules you may end up missing all the fun. ‘The best way to predict your future is to create it.’ - Abraham Lincoln :+1:

  • +
+
+
+

Day 3 : sessiion 3 (27.08.24) - “About teaching and cool things we all would like to share”

+
+
:calendar: Schedule
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 9.45

Computational thinking

10.15 - 10.45

8.15 - 8.45

9.45 - 10.00

Break

10.25 - 11.00

8.25 - 9.00

10.00 - 10.30

Teaching philosophies

11.00 - 11.30

9.00 - 9.30

10.30 - 11.00

Co-teaching

11.30 - 12.00

9.30 - 10.00

11.00 - 11.15

Break

12.00 - 12.15

10.00 - 10.15

11.15 - 11.50

Sharing teaching gems (voluntary)

12.15 - 12.50

10.15 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+
:icecream: Icebreaker
+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • +
  • :sleeping:

  • +
  • :coffee:+2

  • +
  • :robot:

  • +
  • Still little sleeppy :)

  • +
  • 🥴 (:woozy_face: still not converted 🤷‍♂️)

  • +
  • Our planet could be a cube. It has six sides to it. It must be a cube. A cube it is, this Blue Planet … just wondering …

  • +
  • 🦾

  • +
  • :sweat_smile:

  • +
  • computer says no :-) some network trouble

  • +
  • running late, and participating from a :train2:

  • +
+
+
+
Introduction in breakoutrooms
+

Name / Affiliation / Location

+
+
+
Best classroom experiences
+

As a learner or teacher; what was the best workshop/lesson/seminar you have attended? What made the experience great?

+
    +
  • Room 1

    +
      +
    • First summer HPC streamed workshop (as a teacher). Somehow the first felt the best

    • +
    • CSC HPC summer workshop

    • +
    • story telling teaching approach

    • +
    +
  • +
  • Room 2

    +
      +
    • NVIDIA DLI Course on Deep Learning

      +
        +
      • very enthusiastic instructor

      • +
      • intuitive and very accessible way of showing technical details and fostering deeper understanding

      • +
      • a lot of hands-on material and smaller coding exercises

      • +
      +
    • +
    • Anything as long as its interactive and somehow enjoyable from both teacher and learner sides

    • +
    +
  • +
  • Room 4:

    +
      +
    • EPCC MPI Distributed training workshop.

      +
        +
      • Lots of hand on coding / experience gained.

      • +
      • Very interactive instructor who also discussed ideas for more personalised cases of distributed computing.

      • +
      +
    • +
    • Coderefinery RSE course

      +
        +
      • relevance of topic to my current work.

      • +
      • Dynamic / friendly / positive teaching style.

      • +
      • Modular Code Development; very instructive

      • +
      +
    • +
    • Some CSC courses / LinkedIn learning courses

      +
        +
      • up to date materials and topics.

      • +
      • Good way to merge theory with practicalities without making learner feel bored (Example: Jonathan Reichental)

      • +
      • Challenging information to learn more and research about the topic

      • +
      • Trainers are the experts in the field

      • +
      +
    • +
    +
  • +
+
+

Episode on teaching gems

+

If you want to share or demo something about tools and techniques you have found helpful in your teaching, please add your name/initials and rough topic below for smooth transition.

+
+

Note: It does not have to be your tool or your idea, this episode is meant to share experiences and discover new things. You also do not need any slides or materials, a story will do fine :) +Length of the stories will be depending on interest, but be prepared to fit it into 3 min (shortest possible).

+
+ +
+
+
+
+
+
+

:question: Questions

+
+
General / Practicalities
+
    +
  • What is this document for?

    +
      +
    • Asking questions, collecting discussion points, taking collaborative notes (Zoom chat deactivated, can only be used for communication with the hosts)

    • +
    +
  • +
  • Will the material be made available?

    +
      +
    • Materials are and will stay available at https://coderefinery.github.io/train-the-trainer/

      +
        +
      • Can I share them with a colleague

        +
          +
        • Yes please :)

        • +
        +
      • +
      • Can I resuse them in my own teaching?

        +
          +
        • Yes please :)

        • +
        +
      • +
      +
    • +
    +
  • +
  • Will these sessions be recorded?

    +
      +
    • No, but the materials (see above) should include everything needed for self-learning.

    • +
    +
  • +
  • Can I get a certificate for this workshop?

    +
      +
    • You can get a certificate of attendance after the workshop by sending an e-mail to support@coderefinery.org, telling us a bit about what you have learned and which sessions you attended.

    • +
    +
  • +
  • How often will we be talking in breakout rooms?

    +
      +
    • We’ll have about one breakoutroom session per episode

    • +
    +
  • +
+
+
+
+
Episode 1 : Computational thinking
+

Materials: https://coderefinery.github.io/train-the-trainer/computational-thinking/ (Link to slides in the middle of material)

+
+
Questions to audience
+

How might breaking down a complex problem into smaller parts change your approach to problem-solving in your current projects?

+
    +
  • Avoids cognitive overload

  • +
  • I used to give an example about this in workshops of cutting long tree into pieces from top to avoid that it falls and destroy a house bloc.

  • +
  • Easier to start on something small

  • +
  • Each individual part is familiar and can take existing solutions.

  • +
  • Only focus on the new things

  • +
  • One can lose oversight of where is supposed to be getting to due to problems with summation of biases introduced during the solving of the parts.

  • +
  • .

  • +
+

Can you think of a research project where identifying patterns in your data led to new insights or breakthroughs?

+
    +
  • Multi-targeted drug design where you need to identify both chemical and biological pathways/patterns

  • +
  • Distilling complex physics problems into simpler 1D statistics is very often done.

  • +
  • I used to do bioinformatics, pretty much everything in biology is about patterns in strings of charachters (DNA, proteins). Finding those patterns and using them is the way to go

  • +
  • Pattern recognition DOES NOT lead to new insight, it is new insight which allows for the recognition of a ‘pattern’, the latter being an allocation of possible bias.

  • +
  • +
  • ..

  • +
+

What challenges do you face when trying to simplify complex concepts in your field, and how do you decide which details to focus on?

+
    +
  • Absence of a terminology / jargon to describe a new idea. :+1:

  • +
  • Similar to above, when teaching often students know what they want to achive, but don’t have the termonology to express it, so working through what they want is helpful, after teaching them some termonology.

  • +
  • Whatever is most useful to the learner first?

  • +
  • I work with researchers in different fields. I don’t always fully understand their domain knowledge but I can take the basiscs or generalities and get code that works for them

  • +
  • A very practical problem is trying to resist going for a coffee in the midst of taking a shot at a complex concept, in the hope that the true details are to be found in the coffee.

  • +
  • not all information is easy to find or a lot of conflicting information or even sometimes imformation explosion

  • +
+

How do you determine the priority of tasks when designing algorithms for your academic projects, and what criteria do you use to ensure that the most critical tasks are addressed first?

+
    +
  • Working chronologically when going through a problem - start at the beginning.

  • +
  • What gives the more insight with the least effort can be a nice start

  • +
  • Talk to colleagues and Subject matter experts to understand various perspective to decide and prioritize.

  • +
  • Logic will get you from A to B. Imagination will take you everywhere. - Albert Einstein.

  • +
  • ..

  • +
+
+
+
Questions from the audience
+
    +
  • About the 4 core concepts, is this based on the model of how human brain works and perceives vision / abstract ideas?

  • +
  • I don’t know if it’s based on how the brain works, but it’s related to creating a framework for solving programming programs that has been extrapolated to solve any other problem as well.

  • +
  • Devil’s advocate question: cooking (by recipe) actually employs all four principles outlined here and has done so since before the advent of computers. Why then is this concept presented as “computational”?

    +
      +
    • Random aside, this is an interesting connection to our “cooking metaphor to HPC”

    • +
    +
  • +
  • Devil’s answer to the Devil’s advocate: Great question, cooking, as far as the act happens in the Devil’s kitchen, does not employ numerical algorithms. The Devil introduced the computer precisely to make man lose apetite for that what is cooked in the Devil’s kitchen to be served to all. Only then can the Devil eat the cake and keep it too …

    +
      +
    • Well, an algorithm without numbers is still an algorithm, i.e. a set of rules :)

    • +
    +
  • +
  • Are there other names for this technique? I may have missed something crucial, but it strikes me as ‘logical thinking’ in a way.

    +
      +
    • Yes, you could also just see it as problem solving. Most people know how to do it and if you’ve worked with programming, you’ve probably applied it. It can be the case that it’s very obvious to some, but not to others.

    • +
    +
  • +
  • Any chance we can ge a link to the slides?

    +
      +
    • They are in the course material: https://coderefinery.github.io/train-the-trainer/computational-thinking/ :thumbs_up:

    • +
    +
  • +
+
+
+
Exercise questions to discuss
+
    +
  1. Conceptually would the strategies provided by computational thinking help you in completing tasks more efficiently?

  2. +
+
    +
  • Room 1:

    +
      +
    • divide and conquer technique

    • +
    • We discussed what happens if you don’t use these, since they are so natural

    • +
    +
  • +
  • Room 2:

    +
      +
    • in some cases yes, if the task is not too small

    • +
    • not sure if more efficiently but it does help at least getting strted

    • +
    • Computational thinking is an extension of what others have called solutionism: the belief that any given problem can be solved by the application of computation. Whatever the practical or social problem we face, there is an app for it. - James Bridle

    • +
    +
  • +
  • Room 3:

    +
      +
    • Helps in starting the task.

    • +
    • For many it is the normal way to do problem solving. Also in Agile & Scrum methodlogies.

    • +
    +
  • +
  • Room 4:

    +
      +
    • Yes, it helped me during my scientific research to manage multiple projects and research publications simultaneously.

    • +
    • +
    +
  • +
+
    +
  1. Do you think that the effectiveness of computational thinking depends on the person’s personality type?

  2. +
+
    +
  • Room 1:

    +
      +
    • yes, we agree it’s quite different. But good vision and motivation this can be effective

    • +
    +
  • +
  • Room 2:

    +
      +
    • yes, laying out all the steps necessary to achieve an overall goal can be very daunting; some people are not good at/ comfortable with following fine-grained instructions

    • +
    • once the problem is broken down, different personalities might choose different ways to tackle the parts

    • +
    • The degree to which something, that is a result of what one means by ‘Computational Thinking,’ is successful in producing a desired result, that is success, cannot be a function of personality.

    • +
    +
  • +
  • Room 3:

    +
      +
    • Yes. Different people have different ways to communicate.

    • +
    • Online tools vs pen and paper

    • +
    +
  • +
  • Room 4:

    +
      +
    • We are all agree that it depends on the personality type but it could be learned and trained

    • +
    +
  • +
+
    +
  1. Would this type of thinking be an option for you to integrate into your current workflow?

  2. +
+
    +
  • Room 1:

    +
      +
    • Yes; we didn’t know the name explicitly; but we use it

    • +
    • It’s quite important for

    • +
    +
  • +
  • Room 2:

    +
      +
    • I’m already doing it implicitly :smile: :+1: :+1:

    • +
    • Writing a program is like writing a song, its all about the tune, lyrics are merely the necessary nuisance a coder needs to put up with. The latter can, if so written, result in a lot of noise.

    • +
    +
  • +
  • Room 3:

    +
      +
    • Easy if you are working alone. But different team may have their own ways of working (inertia). One way would be then to gradually show the rest of the team its effectiveness.

    • +
    • https://teamtopologies.com/key-concepts

    • +
    +
  • +
  • Room 4:

    +
      +
    • We are using it in our daily life so it’s already an option for us, only the terminologies are a bit new.

    • +
    +
  • +
+
+
+
+
Episode 2 : Teaching philosophies
+

Materials: https://coderefinery.github.io/train-the-trainer/teaching-philosophies/

+

Questions to discuss:

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+
Breakout Room exercise
+
    +
  • Room1

    +
      +
    • Motivation

      +
        +
      • For best practices in teaching, learning from each other, collaboration

      • +
      +
    • +
    • Learning applied tech is like an apprecentiship: there is theory, but real learning happens by co-working with others.

    • +
    • Worse is better: teach what can be used more quickly and it can be improved later

    • +
    • +
    • I think there are two bits of teaching - teach the basics and terminology so people know what they want to know, and then teaching how to find out how to do things like Richard said - how to find answers yourself.

    • +
    • Using Jupyter notebooks - good for learning a technique, but not for learning the basics.

    • +
    • Possibly command line usage has a branding problem - “programming other programs”?

    • +
    • the skills we learn in CR training are expected to stay , it is not exam oriented

    • +
    +
  • +
  • Room 2

    +
      +
    • State objectives clearly and repeat them a few times

    • +
    • Try to keep it informal, interactive, flexible

    • +
    • Helps when having practical tasks in mind for the materials taught

    • +
    • Leave some reasoning to the learner, not always giving full answers

      +
        +
      • How to deal with frustration though: try some personal approaches, more clues…

      • +
      +
    • +
    • The mediocre teacher tells. The good teacher explains. The superior teacher demonstrates. The great teacher inspires. — William Arthur Ward

    • +
    • Teaching kids to count is fine, but teaching them what counts is best. –Bob Talbert

    • +
    +
  • +
  • Room 4

    +
      +
    • Question 1: What is your motivation for taking this training?

      +
        +
      • Currently do instruction, wanting to improve as an instructor and helper when conducting software carpentries.

      • +
      • Planning to start some side hustles providing online courses and why not joining the CR in the near future

      • +
      +
    • +
    • Question 2: How structured or informal are your own teaching needs?

      +
        +
      • More recently, follow software carpentries, but look into what aspects can be tailored to keep to different time slots.

      • +
      • I used to be more informal in the past, repetetive practice sessions. Would like to be more structured given the teaching tools.

      • +
      • I’ve done life-coaching and some teaching but I feel i’m both of them

      • +
      +
    • +
    • Question 3: What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

      +
        +
      • Smaller size, and more targetted.

      • +
      • Collaborative tools and targeted audience working with small groups

      • +
      • Academic probably focuses on an audience with a more focused/narrow background, while this style encompasses a wider audience.

      • +
      • Academic teaching keeps theory and practical lab sessions very separate, whereas carpentries combine both.

      • +
      +
    • +
    • Question 4: What other skills need to be taught, but academic teaching isn’t the right setting?

      +
        +
      • Public speaking, collaborative meeting skills

      • +
      • Industrial cases and related work skills

      • +
      +
    • +
    +
  • +
+
+
+
Episode 3: Co-teaching
+

Materials: https://coderefinery.github.io/train-the-trainer/co-teaching/

+
    +
  • In general: Co-teaching is a beast with at least two personalities each of which

    +
      +
    • demand higher preparation requirements

    • +
    • face remarkable complexity in terms of coteacher coordination

    • +
    • in the virtual component face shortcomings related to the technical equipment and the failure of the human factor

    • +
    +
  • +
+
    +
  • Co-teaching requires the framework of co-operative learning. Team teaching does not by default translate into parallel learning, and vice versa.

  • +
+
    +
  • Re: CodeRefinery in-person beginnings – I agree with the “didn’t work so well in-person”, I’m not sure if it’s that we weren’t as ready for it, or that the different characteristics made it not work so much

  • +
  • How do the downsides compare to a single instructor monologuing?

    +
      +
    • That’s a great question! The main difference is that a single instructor can teach himself to be good (i.e. not just boring monologuing) alone, while for teams of 2+ to work well, everyone needs to be baseline-competent. So the effort to avoid downsides gets reduced if (and only if) all team members share it.

    • +
    +
  • +
+
+

Exercise/Discussion: https://coderefinery.github.io/train-the-trainer/co-teaching/#exercise

+

Questions:

+
    +
  • Have you already tried this or similar model in your teaching?

  • +
  • Does it seem natural to apply this model in your subject area (tell what it is)? How could it be adapted to fit best?

  • +
  • Have you tried or seen a different model for two instructors to present? Please share with us how it works.

  • +
+
+
    +
  • room 1

    +
      +
    • We have tendend to do presenter/interviewer more

    • +
    • challenges are co-teaching with different personalities

    • +
    +
  • +
  • room 2

    +
      +
    • Main challenge: finding enough personell :smile:

    • +
    • It’s not always possible/feasible to have colleagues co-teaching

    • +
    • A combination of both, but presenter and interviewer could be difficult to plan an to follow

    • +
    • Guide and demo-giver with technical / non-technical roles could be nice

      +
        +
      • How to plan the guide and demo-giver

        +
          +
        • First guide, then demo

        • +
        • Demo, then guide describes

        • +
        +
      • +
      +
    • +
    • Alternative model: main presenter + ‘technical expert’

      +
        +
      • main presenter introduces concepts from a birdseye view and passes on to the technical expert for additional details, experiences and answers to questions from the audience

      • +
      +
    • +
    • We frequently do a classical division: on person in presenting, one or more are answering questions in the chat; there is rarely any interaction between them however

    • +
    +
  • +
+
    +
  • As has been pointed out by Paolo Freire, in general, ‘education is suffering from narration sickness’ … ‘The outstanding characteristic of this narrative education, then, is the sonority of words, not their transforming power’. Perhaps one approach could be to rephrase the question after having the answer: It is not apriori about the model implemented, it is about whether that what was implemented was judged aposteriori to have succeeded in becoming, or at least could pretend to have done so, the intended context matched model implementation it probably was computed to be.

  • +
+
    +
  • room 4

    +
      +
    • the co-teaching approach does not seem to be widely practiced

    • +
    • it can be interesting to see “mistakes” which are less likely to happen in solo-teaching?

    • +
    • co-teaching can be nicer for audience but maybe more stress/anxiety for instructors to prepare? more stress in terms of not knowing all the questions in advance. less stress worrying about forgetting something.

    • +
    +
  • +
+
+
+
Teaching gems
+

(scroll up to find the green box “Episode on teaching gems”)

+

What’s your favorite way of teaching? Any nice tools you use?

+

Has anyone found a nice online tool to draw?

+
    +
  • I love this tool suite https://excalideck.com/

    +
      +
    • For drawing https://excalidraw.com/

    • +
    +
  • +
  • I have seen Miro …

  • +
  • I think the Code Refineries use something for their graphics that looks a bit ‘cartoony’ - but I cannot remember what it is called!

    +
      +
    • Drawn on remarkable and then coloured and tidied up in Inkscape. :+1:

    • +
    +
  • +
  • I am a big fan of remarkable. I think sharing option is fairly good. Unfortunately bit expensive tool.

    +
      +
    • true, for me it was worth it already for the pdf annotation for research papers, cannot read on computer screen

    • +
    +
  • +
  • https://webwhiteboard.com/

  • +
  • https://www.youtube.com/watch?v=4-l8MY5kYGc

  • +
  • Figma and Kahoot are useful as well

  • +
+

Screenkey: Screenkey for showing keyboard shortcuts

+
    +
  • Is there a Windows version people can recommend?

    +
      +
    • I found this list of alternative for windows users like me: https://alternativeto.net/software/screenkey/ :+1:

    • +
    +
  • +
  • I sometimes use the on-screen keyboard already provided by the OS :+1:

  • +
+
+
+
+

Wrapup

+
    +
  • Next session Tuesday September 3rd 9 CEST: About teaching & cool things we all would like to share

  • +
  • All workshop materials will stay available (and be put on Zenodo right after the workshop, currently other epsisodes are still in development)

  • +
  • CodeRefinery community: https://coderefinery.zulipchat.com/

  • +
  • If you want to co-teach with us in the upcoming (or any future) CodeRefinery workshop; or just want to learn more about this opportunity: Let us know in chat, send an e-mail to support@coderefinery.org, or join any of the upcoming Monday planning meetings at 14 CEST

  • +
  • Preparations for next week will be sent out by e-mail

  • +
+
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • The co-teaching lesson and experiences from others

  • +
  • Discussions were quite good, had a nice group

  • +
  • Breakout rooms and collaborative tools

  • +
  • Computational thinking and co-teaching are interesting ideas! I have seen it before, but never knew or even recognized it was a method.

  • +
  • Thanks for group discussions working with my chat only interaction! :smile:

  • +
  • ..

  • +
+

What one thing would you improve about this session?

+
    +
  • Minor point - it would be useful to have the teaching gmes box at the bottom of the document rather than the top - tricky to scroll between! In the end I opened two windows which was easier.

    +
      +
    • Thanks, yes agree. Also had that problem, but did not want to move it in between.

    • +
    +
  • +
  • The meaning of teaching “philosophy” wasn’t very clear, felt more like teaching “styles”

    +
      +
    • Thank you, we will take that into consideration

    • +
    +
  • +
  • Some prepared slides to present for an intro about the topics

    +
      +
    • You mean in addition to the materials? To use in the beginning of each session?

    • +
    +
  • +
  • The instructor views segment could be named as additional material, if it was not meant to be discussed within the course.

    +
      +
    • Thank you, we will take that into consideration

    • +
    +
  • +
+

Any other comments?

+
    +
  • Keeping it short and sweet: If at first you don’t succeed in teaching, try to explain it like you’re talking to a room full of cats. Caveat: In a room full of computational thinkers maybe if you tell students that the brain is a computational device that is forbidden, they might get excited and start using it.

  • +
+
+
+

Day4: Session 4 (3.09.24) - Streaming and video editing

+
+
:calendar: Schedule
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Time (CEST)

Title

EEST (UTC+3)

BST (UTC+1)

8.45 - 9.00

Connecting time

9.45 - 10.00

7.45 - 8.00

9.00 - 9.15

Intro and Icebreaker

10.00 - 10.15

8.00 - 8.15

9.15 - 10.00

Why we stream & Behind the scenes

10.15 - 11.00

8.15 - 9.00

10.00 - 10.15

Break

11.00 - 11.15

9.00 - 9.15

10.15 - 10.35

Video Editing

11.15 - 11.35

9.15 - 9.35

10.35 - 10.55

Exercise: Video Editing

11.35 - 11.55

9.35 - 9.55

10.55 - 11.10

Break

11.55 - 12.10

9.55 - 10.10

11.10 - 11.30

Open Broadcaster Software(OBS) introduction

12.10 - 12.30

10.10 - 10.30

11:30 - 11:50

OBS setup & what next

12.30 - 12.50

10.30 - 10.50

11.50 - 12.00

Outro and feedback

12.50 - 13.00

10.50 - 11.00

+
+
+
:icecream: Icebreaker
+
+
Check-in
+

Which emoji best describes your current state of mind? Emoji cheat sheet

+
    +
  • :coffee: +

  • +
  • :runner:

  • +
  • :tired_face: Tired!

  • +
  • :nerd_face:

  • +
  • +
  • :cloud: :tea:

  • +
+
+
+
Introduction in breakoutrooms
+
    +
  • Name / Affiliation / Location

  • +
+

What’s the most number of people you have taught to?

+
    +
  • 20 at a time, with 1 asleep, 2 fidgiting with some silly device and the rest were… well… staring at their good luck… straight ahead it was of course, right before them.

  • +
  • ~35

  • +
  • ~80 in a lecture in a previous (lecturer) role, 26 in a training course setting

  • +
  • ~30

  • +
  • ~50 in training spaces and more than 100 for public audience talk

  • +
  • 35 (software carpentry)

  • +
  • CodeRefinery answer: The biggest ones are maybe 200-300 people. “small” for a stream is ~100 people.

  • +
+

What’s the most number of people you have taught with?

+
    +
  • 5 or so

  • +
  • 2 or 3 in total

  • +
  • 3, as in three, none of them smiling. I wish I could figure out why… it was such fun really…

  • +
  • 7

  • +
  • 2 or 3

  • +
  • 3 (helpers, not really co-teaching)

  • +
  • CodeRefinery answer: our biggest workshops are something like 10-20 people helping out in many different roles.

  • +
+

How can you divide teaching into separate independent tasks?

+
    +
  • By content blocks, having roles like main and assistant…

  • +
  • Having responsibility for different sections of the course.

  • +
  • Wow, now thats what we call a question… bravo… indeed, how does one separate sleeping and snoring into separate independent tasks…

  • +
  • Course, exercices, resources, tools and forms.

  • +
  • Different people teach different topics

  • +
  • CodeRefinery answer: the big logical blocks are instructors, in-person and breakout room helpers, and Notes-questions answers.

  • +
+

What’s the most interesting or useful thing you’ve learned from an online workshop, and how have you applied it/planning to apply in your life or work

+
    +
  • Having breaks every hour or so

  • +
  • New approach to screensharing, using the ‘portrait’ approach

  • +
  • Manage breathing: reduce stress and use silence to let the audience grasp what you’re saying

  • +
  • Well, the most interesting or useful thing I’ve learned from online workshops is how not to conduct a workshop, or at least some elements of the same, and I have applied this understanding by engaging in the global effort to discover more about how not to conduct a workshop, or at least some elements of the same, with the motto: That’s one small step for a man, one giant leap for mankind..

  • +
+
+
+
+
:question: Questions
+
+
+
Why we stream
+
    +
  • If during streaming there is no interaction between the teacher and the audience, why don’t we just record the lectures and stream them? So one can do a better job, perhaps?

    +
      +
    • Streaming it making it a “thing” that’s a group experience. It feels good to be a part of it, so we hope that encourages people to actually attend. All the mass Q&A is fun, and the audience helps to make it easier to present. Still, this is a good question.

    • +
    • I really appriciate it being “a thing”. If it was just recorded, I would say I would watch it tomorrow, and then I never would.

      +
        +
      • But then you can just fake it, and still have all the breakout rooms and collaborative document and so on. I appreciate the value of having a proper “event”.

        +
          +
        • I think I follow you, but if you pre-recorded the talking bits, then the presentors couldn’t change what they do based on the feedback in the shared document.

          +
            +
          • true, but I assumed that the teachers were too busy to actually do that. The more (less )division of labor between the teachers and the helpers (or collaborative document editors), the more (less) sense it makes to pre-record - IMHO

          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
  • What interaction options do ‘streamers’ use, e.g. on Twitch/YouTube (not Code Refinary)?

    +
      +
    • I’m besides chat and things that happen in chat, I’m not sure. The Notes-doc is definitely unique to us.

    • +
    +
  • +
  • Streaming is a kind of exercise for the movie star type. If you cannot be one, act like one, pretend, fool the listener into thinking you are one, take their brains and emotions under control. And if they don’t leave the session with tears of love for learning running down their chubby cheeks you know who to kick for doing a job just that bit worse than it should have been necessary.

  • +
  • Have you kept track of streming stats? like how many people logged in and stayed troughout, how many interacted?

    +
      +
    • Yes please, it would be good to see the stats

    • +
    • Here is stats repo

    • +
    • Thanks, I get a 404 error, is it private?

    • +
    • No, I don’t think so. https://github.com/coderefinery/workshop-stats

    • +
    • Still get 404. Does it work for anyone else?

      +
        +
      • Yeah I think it’s private. We need to fix this…

      • +
      +
    • +
    +
  • +
  • How big is small (10-15), medium (~30-40)?

    +
      +
    • I would say below 50 is small.

    • +
    +
  • +
  • Have you considered scaling to more events instead of to a larger audience? I mean, this seems the opposite of scaling, but this kind of content would be more useful the more often is it taught (“I need to learn GIT/Python/* in December!”)

    +
      +
    • We would, but right now we simply don’t have enough time and people to do more small events. But yes, “scheduling conflict” is a big problem - the best we can do right now is written material+videos to follow up on (and hope it’s interesting enough)

    • +
    • Python for Scientific Computing 5-7/November/2024

      +
        +
      • This was just an example. I mean, if I am a PHD student that needs to start working on a topic on Month X which happens to be inconveniently placed in the year, I will not benefit as much from having a workshop at Month X+3

        +
          +
        • The materials are open and the videos are publically available on YouTube channel

          +
            +
          • What’s the ratio of people watching videos afterwards vs people attending the event? That ratio can give an idea of the popularity of the two possible approaches.

          • +
          +
        • +
        +
      • +
      +
    • +
    • The more you scale up the less interactive the course / workshop will need to be. It then becomes a question of priorities, and if teaching is a lower priority then learning than I guess there really should be no prizes for guessing which approach should reign the airwaves.

    • +
    +
  • +
  • I guess outside Europe / Africa, time zones could be a problem?

    +
      +
    • yes, that is true

    • +
    • +
    +
  • +
  • Sorry, I might have missed this: have you been rehearsing and/or doing dry runs?

    +
      +
    • With instructors I like to try to do a dry run. I often don’t do a live broadcast dry run these days since I’m confidente enough, but when you are just starting, it’s a good idea.

    • +
    +
  • +
  • Do you always use Zoom for the ‘presenter end’ or have you tried other things? Teams? Jitsi? etc.?

    +
      +
    • we use mostly zoom

    • +
    • It was first pioneered using Jitsi. You can probably use others, too.

    • +
    +
  • +
  • A comment: for deRSE24 we have been using the GWDG streaming service and OBS, it worked quite well (with a 20s delay or so)

    +
      +
    • Cool! Yes, there is plenty of livestreaming options. Twitch+our OBS config gives us 2-3s of latency (which is low enough for live Notes interaction). You might be able to tune this if needed.

    • +
    +
  • +
+
+
+
Behind the stream
+
    +
  • Does OBS take a lot of RAM or CPU? what are the specs on your machine?

    +
      +
    • Richard have a relatively powerful computer with 8 AMD CPUs.

    • +
    • 4 CPUs are relatively enough for a good OBS setup, most important is a stable internet connection (ideally wired).

    • +
    • An extra monitor is recommended for the setup

    • +
    • See the hardware notesrecommendation here

    • +
    +
  • +
  • Do you do a screenshare from Zoom -> OBS or OBS -> Zoom?

    +
      +
    • Instructors share to Zoom, OBS captures Zoom, OBS sends to the world.

    • +
    • When I am using OBS sfor a single-person presentation recording, I go the other way: OBS captures my desktop/camera, OBS generates the preview window, and then Zoom captures and broadcasts the preview window.

    • +
    +
  • +
+
+
+
Video editing
+
+
Poll
+
    +
  • Have you tried video editing? Add ano as answer below

    +
      +
    • yes: ooooo

    • +
    • no :

    • +
    • Video editing makes all the difference. I have never known a way to avoid this sacred of steps, so to speak. In short, no recording can ever be production ready by default in the books of the wiser among the streamers. In fact, during the editing one can considerably refine and improve the learning experience in great ways. But then one would need to invest both time and effort.

    • +
    +
  • +
  • If yes Which are the tools you use?

    +
      +
    • Windows Movie Maker / ClipChamp

    • +
    • (raw stream from Zoom)

    • +
    • I think it was shotcut - I did only basic trimming

    • +
    • Kdenlive

    • +
    • Clipchamp, OpenShot, Sony Vegas

    • +
    • also ffmpeg from command line to cut beginning and end

    • +
    +
  • +
+
+
+
Questions
+
    +
  • What is Whisper?

    +
      +
    • Open-source model from OpenAI that converts speech to text transcripts.

    • +
    • this one? https://openai.com/index/whisper/

    • +
    • curious if anyone has tried it with languages other than english

    • +
    • I heard that one of my spanish colleague try it with another software. I don’t remember the tool. But with AI bloom there are many licensed tools that can do it with fifferent language

    • +
    +
  • +
  • What do you use to crop the videos?

    +
      +
    • I see now, ffmpeg

    • +
    +
  • +
  • how to merge multiple parts in one? I asked because you edited only the icebreaker part?

    +
      +
    • you can manage it in input part, see ffmpeg-editlist readme.

    • +
    +
  • +
  • Do you generate custom thumbnails for the video?

    +
      +
    • no, because of the time, but its good to have. If we had a volunteer to manage that, then we should!

    • +
    +
  • +
  • Does anyone recommend any other (GUI) tools that work well? ffmpeg is very new to me!

    +
      +
    • if you want a basic trimming and editing , you can use Quicktime player/imovies on mac

    • +
    • Clipchamp as the Microsoft video editor

    • +
    • Thanks :smile:

    • +
    +
  • +
  • How do subtitles get uploaded to YouTube?

    +
      +
    • You upload the video and subtitles as part of upload.

    • +
    • :+1:

    • +
    +
  • +
  • How does codewhisperer compare against youtube’s automatically generated subtitles?

    +
      +
    • by experience, whisper was better couple of years ago. We haven’t compared it recently

    • +
    • I guess and advantage is that you can edit whisper subtitles in case something is odd or whatever, probs cannot do that in YouTube

    • +
    +
  • +
+
+
+
+
Open Broadcaster Software (OBS) introduction & setup
+
    +
  • Are the profiles public?

    +
      +
    • Yes, you can see it here

    • +
    +
  • +
  • Does it work in Linux+Wayland?

    +
      +
    • I think everything we do with OBS would.

    • +
    +
  • +
+
+
+
+

Wrapup

+ +
+
+

Feedback about todays session

+

What one thing was the most valuable/useful thing you learned today? Or generally one thing you liked about this session:

+
    +
  • ffmpeg seems great, will give a try for fun!

  • +
  • great to see everything in practice!

  • +
  • Very insightful to see what happens behind the scenes.

  • +
+

What one thing would you improve about this session?

+
    +
  • Some more interactivity would’ve been nice but since most the group preferred demo instead of exercise perhaps it’s only a personal opinion

  • +
  • It would have been good to share the OBS profiles repo beforehand in the setup email - so I could have had it to hand. (https://github.com/coderefinery/obs-config)

    +
      +
    • +1 good idea, we should do this next time

    • +
    +
  • +
  • Perhaps a simpler starter OBS setup?

    +
      +
    • Good idea… I should have, but basically ran out of time to prepare.

    • +
    +
  • +
+

Any other comments?

+
    +
  • Cool to see the switch from RSE to trainer to AV guy, impressive!

  • +
+
+
+
+
+

Instructor guide

+
+

Target audience

+
    +
  • Everyone teaching online workshops about computational topics or interested in teaching.

  • +
  • Previous and future instructors and helpers of CodeRefinery workshops.

  • +
+
+
+

Timing

+

Session 1

+
    +
  • 15 min: Intro

  • +
  • 45 min: Lesson design and development

  • +
  • 15 min: Break

  • +
  • 45 min: Lesson template

  • +
  • 15 min: Break

  • +
  • 30 min: How we collect feedback and measure impact

  • +
  • 10 min: Outro and feedback

  • +
+

Session 2

+
    +
  • 15 min: Intro

  • +
  • 10 min: About the CodeRefinery project and CodeRefinery workshops in general

  • +
  • 30 min: Collaborative notes and interaction

  • +
  • 15 min: Break

  • +
  • 35 min: Workshop overview, roles, onboarding/installation, helpers

  • +
  • 20 min: Sound

  • +
  • 15 min: Break

  • +
  • 30 min: Screenshare

  • +
  • 10 min: Outro and feedback

  • +
+

Session 3

+
    +
  • 15 min: Intro

  • +
  • 30 min: Computational thinking

  • +
  • 15 min: Break

  • +
  • 30 min: Teaching philosohies

  • +
  • 30 min: Co-teaching

  • +
  • 15 min: Break

  • +
  • 35 min: Sharing teaching tips, tricks, tools etc

  • +
  • 10 min: Outro and feedback

  • +
+

Session 4

+
    +
  • 15 min: Intro

  • +
  • 10 min: Why we stream

  • +
  • 20 min: Behind the stream

  • +
  • 15 min: Video editing (part 1)

  • +
  • 15 min: Break

  • +
  • 25 min: Video editing (part 2, exercise)

  • +
  • 20 min: OBS introduction

  • +
  • 15 min: Break

  • +
  • 30 min: OBS setup

  • +
  • 15 min: What’s next?

  • +
+
+
+

Talking points for each sessions intro

+
    +
  • Brief CodeRefinery intro

  • +
  • Instructors intros

  • +
  • Notes intro

    +
      +
    • Check-in

    • +
    • Icebreaker

    • +
    • Participant intros in breakoutrooms (Random assign first, then same for whole session)

    • +
    +
  • +
  • Daily schedule, learning objectives

  • +
  • Code of conduct

  • +
  • Chat (please use collaborative notes)

  • +
+
+
+

Participant preparations for each session

+

Copied from e-mail communication with participants before each session.

+

Session 1: +In general you will only need your brain for the exercises and discussions, but some will have the option to go deeper, which may require some accounts or tools to be set-up. We will inform about these things the week before each session.

+

For Session 1 we recommend to have a GitHub account (https://coderefinery.github.io/installation/github/#github). There will be an optional exercise where you can build a lesson locally. This requires a basic Python environment (https://github.com/coderefinery/sphinx-lesson-template/blob/main/requirements.txt), but do not worry if you cannot or do not want to set up these, there will be plenty of other exercises.

+

Session 2: +In general you will only need your brain for the exercises and discussions. To get the most out of this workshop day we recommend that you join the session with the same computer, display and microphone setup as you would usually use for teaching/ presenting. It may also help to get familar with the different options your computer and Zoom setup provides for screenshare and audio adjustments. +But it is not a must.

+

Session 3: +In general you will only need your brain for the exercises and discussions. If you want to share some “cool gem” in the last episode of this workshop day, please update your registration (link to edit can be found in the registration confirmation e-mail sent by support@coderefinery.org or noreply@neic.org). This is very low barrier, you do not have to be the developer of a tool or technique to share with the group what makes it useful for you; and it does not even have to be cool, sometimes the small “normal” things are the best. You can check out some topics that have been proposed so far in this GitHub issue (#90), you can also comment there if you want to add or change your topic. These will be lightning talk length, so something between 2-5 min depending on how many are interested to share something, but we can collect them all in the collaborative notes for further exploration/reading. +But it is not a must.

+

Session 4: +This upcoming session (session number 4) will cover the technical aspects of CodeRefinery-style online teaching. These topics have never before been covered in this much detail, so if it’s interesting to you, don’t miss it. (You might also want to pass this on to others who are interested in technical production of online events; registration is still open!).

+

First, we talk about why we stream (how we got here, advantages, disadvantages, how to be an instructor in a livestreamed workshop, and what it looks like from a broad level from the production side)

+

Then, we show how we are able to release videos so quickly. This is useful far beyond CodeRefinery, and there are also some hands-on exercises. Come prepared to set up a Python environment and the ffmpeg command line tool if you want to try these.

+

Finally, we see details about how to set up Zoom→Livestream environment for yourself. There isn’t time to do this as a proper exercise, but it’s the starting point and the instructor will offer help after the course for those interested. If you want to try this out during the session, install OBS Studio in advance.

+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright CodeRefinery project.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/singlehtml/objects.inv b/singlehtml/objects.inv new file mode 100644 index 0000000..e7d370e Binary files /dev/null and b/singlehtml/objects.inv differ diff --git a/sound/index.html b/sound/index.html new file mode 100644 index 0000000..040b61f --- /dev/null +++ b/sound/index.html @@ -0,0 +1,366 @@ + + + + + + + Sound — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Sound

+
+

Objectives

+
    +
  • Understand that sound quality is very important

  • +
  • Evaluate your and others sound quality and know how to improve it

  • +
  • Test tips and tricks for achieving good sound quality

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Exercises: 10 min

  • +
+
+
+

The importance of audio

+
    +
  • Pleasing audio quality makes events much more enjoyable

  • +
  • Audio is one of the most important things you can control

  • +
  • Things that can go wrong:

    +
      +
    • Too quiet

    • +
    • Too loud

    • +
    • Instructors’ volumes imbalanced

    • +
    • Background noise

    • +
    • Low-quality/breaking up audio hard to hear.

    • +
    • “Ducking” (first words lower volume, or lower volume other times)

    • +
    +
  • +
+
+
+

Tips for good sound quality

+
    +
  • Have a headset with mounted microphone

    +
      +
    • Even if you have a professional external microphone, it doesn’t +matter if your room has bad acoustics.

    • +
    • The close pickup can’t be beat with normal tools.

    • +
    • As long as it’s headset mounted, price doesn’t seem to matter +that much.

    • +
    +
  • +
  • Don’t use Bluetooth

    +
      +
    • Bluetooth can have too much latency (300-500ms)

    • +
    • This may seem small but for interactive work, it’s a lot

    • +
    • Use a wired headset, or wireless with a non-Bluetooth USB plug +(like gaming headsets have). These have much lower latency.

    • +
    • Bluetooth 5 can have much lower latency, but you probably +shouldn’t count on that without testing.

    • +
    • It can also have lower sound quality on some devices due to +bandwidth limitations.

    • +
    +
  • +
  • Once you have a headset, turn input noise cancellation to low +(wherever it might be: headphone, meeting software, etc.).

  • +
+
+
+

Balancing and dynamic adjustment

+
    +
  • It’s important that instructors volumes match.

  • +
  • An exercise will go over a systematic procedure for matching +volumes.

    +
      +
    • Practice so that you can do this quickly.

    • +
    +
  • +
  • May need re-adjusting when instructors swap out or start getting +excited.

  • +
  • An exercise below will demonstrate our procedure.

  • +
+
+
+

Speak up when there are problems

+
    +
  • If you notice someone with audio issues, let them know right away +(voice if bad, or chat/notes if less urgent).

  • +
  • Take the time to fix it as soon as practical.

  • +
  • Make a culture of speaking up, helping, and not suffering.

  • +
+
+
+

Recommendations

+
    +
  • Procure some reasonable headset.

  • +
  • Low/medium-priced gaming-type headsets have worked well for us.

    +
      +
    • (gaming headsets usually aren’t Bluetooth, because gaming needs +low latency.)

    • +
    +
  • +
  • Show this page to your workplace (if you have one) and call a good +headset work equipment.

  • +
+
+
+

Exercises

+
+

Sound-1: Evaluate sound quality

+

It’s important to be able to discuss with others the quality of their +audio. They can’t hear themselves, after all.

+
    +
  • Within the teams, discuss each person’s audio quality and what kind +of setup they have.

  • +
  • Be respectful and constructive (and realize that people came +prepared to listen, not teach).

  • +
  • Consider, for example

    +
      +
    • Volume

    • +
    • Clarity

    • +
    • Background noise

    • +
    • Noise cancellation artifacts

    • +
    • “Ducking”: first words at lower volume or missing

    • +
    +
  • +
  • Discuss how to bring this up during other courses and meetings.

  • +
+
+
+

Sound-2: Adjust volume up and down

+

In addition to individual quality, it is important that sound is +balanced among all instructors. Have you ever been to a event when +one person is too quiet and they can’t make themselves any louder? +And they can’t adjust it?

+

You should ensure that you have a range of volumes available to you. +You might have to look into several different locations in order to +make the full adjustment ().

+
    +
  • Go to your sound settings

  • +
  • One by one, each person

    +
      +
    • Adjusts their microphone volume so quiet that they can’t be heard.

    • +
    • Adjusts their microphone volume so that it is extremely loud (this +may require going beyond 100% if possible).

    • +
    +
  • +
  • Basically, make sure you aren’t so close to either end that you have +no potential to make an adjustment in that direction.

  • +
  • Everyone tries to set the volume to something reasonable, in +preparation for the next exercise.

  • +
+

Once you know where these settings are , you won’t be panicked when the +volume is too low or high during a course.

+
+
+

Sound-3: Do a balance check

+

It’s important that instructor audio is balanced (the same volume). +But how can you do this?

+
    +
  • Pick a leader.

  • +
  • The leader decides the order (“I am first, then [name-1] and +[name-2]”)

  • +
  • The leader says “one”. Everyone else says “one” in the order +specified.

  • +
  • The leader says “two”. Everyone else says “two” in the order.

  • +
  • The leader asks for opinions on who they think is louder or softer. +If there are more than three people, you can figure it out +yourselves. With less than two, you have to ask someone in the +audience.

  • +
+

Example:

+
    +
  • Leader: Let’s do a sound check. I am first, then AAA and BBB.

  • +
  • Leader: One

  • +
  • AAA: One

  • +
  • BBB: One

  • +
  • Leader: Two

  • +
  • AAA: Two

  • +
  • BBB: Two

  • +
  • Leader: Three

  • +
  • AAA: Three

  • +
  • BBB: Three

  • +
  • Leader: How did that sound to everyone?

  • +
  • [Someone else]: Leader and BBB were pretty similar but AAA is a bit +lower.

  • +
+
+
+
+

Summary

+
+

Keypoints

+
    +
  • Audio quality is important and one of the most notable parts of the +workshop.

  • +
  • Improving audio isn’t hard or expensive, but does require preparation.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/streaming-whats-next/index.html b/streaming-whats-next/index.html new file mode 100644 index 0000000..916e18c --- /dev/null +++ b/streaming-whats-next/index.html @@ -0,0 +1,202 @@ + + + + + + + What’s next? — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

What’s next?

+
+

Objectives

+
    +
  • Know next steps if you want to do streaming

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 5 min

  • +
  • Q&A 5 min

  • +
+
+

What comes next?

+
    +
  • We talked a lot about theory, and gave demonstrations.

  • +
  • Hands-on is very different. We recommend working with someone to +put it in practice.

  • +
  • +
+
    +
  • Work with someone who can show you the way

  • +
  • Use it for smaller courses with a backup plan

  • +
+
+

See also

+
+

Keypoints

+
    +
  • These lessons about streaming have been the theoretical part of +streaming training.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/streaming/index.html b/streaming/index.html new file mode 100644 index 0000000..54c786f --- /dev/null +++ b/streaming/index.html @@ -0,0 +1,274 @@ + + + + + + + Behind the stream — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Behind the stream

+
+

Objectives

+
    +
  • Take a first look at the broadcaster’s view.

  • +
  • Get to know what happens “behind the stream” of a workshop

  • +
  • See what the “broadcaster” sees and what they need to do.

  • +
  • Not yet: learn details of how to do this.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Q&A 10 min

  • +
+
+

In this episode, you’ll see an end-to-end view of streaming from the +broadcaster’s point of view. It’s a tour but not an explanation or +tutorial.

+
+

Who does what

+

We have certain role definitions:

+
    +
  • Broadcaster: Our term for the person who manages the streaming.

  • +
  • Director: Person who is guiding the instructors to their +sessions, changing the scenes, calling the breaks, etc.

    +
      +
    • Could be the same as broadcaster.

    • +
    +
  • +
  • Instructor: One who is teaching. They don’t have to know +anything else about how streaming works.

  • +
+

This lesson describes what the Broadcaster/Director sees.

+
+
+

Window layouts

+

What does the broadcaster see on their screen?

+
    +
  • What are the main windows you see?

  • +
  • What do each of them do?

  • +
  • Which ones do you need to focus on?

  • +
  • How do you keep all this straight in your head?

  • +
+
+
+

CodeRefinery control panel

+
    +
  • A custom application that controls scenes

  • +
  • Based on OBS-websocket (remote control connection for OBS - we’ll +learn about this later)

  • +
  • Can also work remotely, so that you can have a remote director

  • +
+
+
+

How scenes are controlled

+

What has to be done during a course?

+
    +
  • How do you start the stream?

  • +
  • How do you change the view?

  • +
  • How do you adjust things based on what the instructors share?

  • +
  • How do you coordinate with the instructors?

  • +
  • How do you know when to change the view?

  • +
+
+
+

Getting it set up

+
    +
  • How hard was it to figure this out?

  • +
  • How hard is it to set it up for each new workshop?

  • +
+
+
+

What can go wrong

+
    +
  • What’s the worst that has happened?

  • +
  • What if you need to walk away for a bit?

  • +
  • Someone broadcasts something unexpectedly

  • +
+
+
+

Alternatives

+
    +
  • Youtube vs Twitch

  • +
  • Zoom stream directly to YouTube/Twitch

  • +
  • Direct streaming platform, e.g. streamyard

  • +
+
+
+

Q&A

+

Q&A from audience

+
+

Keypoints

+
    +
  • The broadcaster’s view shouldn’t be so scary.

  • +
  • There is a lot to manage, but each individual part isn’t that hard.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/teaching-philosophies/index.html b/teaching-philosophies/index.html new file mode 100644 index 0000000..155b81a --- /dev/null +++ b/teaching-philosophies/index.html @@ -0,0 +1,314 @@ + + + + + + + CodeRefinery teaching philosophies — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CodeRefinery teaching philosophies

+
+

Objectives

+
    +
  • Get to know the teaching philosophies of CodeRefinery instructors

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 10 min

  • +
  • Discussion: 20 min

  • +
+
+
+

Introduction

+

During this episode we split into breakoutrooms and discuss own teaching philosophies. +Collect your teaching philosophies in the collaborative document. We will be going through +these and the end of the lesson.

+
+

Ice-breaker in groups (20 minutes)

+
    +
  • Share your approach to teaching and your teaching philosophy with your group.

  • +
  • Please share your tricks and solutions in the live document for others.

  • +
+

Additional ice-breaker questions:

+
    +
  • What is your motivation for taking this training?

  • +
  • How structured or informal are your own teaching needs?

  • +
  • What difference do you notice between the teaching what we (also Carpentries) do and traditional academic teaching?

  • +
  • What other skills need to be taught, but academic teaching isn’t the right setting?

  • +
+
+
+
+

Instructor views

+

Here CodeRefinery instructors share their training philosophy to show that we +all have different teaching styles and how these differences are beneficial to +CodeRefinery workshops.

+

It is important to explain how much we value individuals and that there is not +one way to teach but as many ways as individuals. We want to help each other to +find the way that is best for each of us.

+
+

Video recordings

+

We have recorded some of the below as videos: https://www.youtube.com/playlist?list=PLpLblYHCzJAAHF89P-GCjEXWC8CF-7nhX

+
+
+

Bjørn Lindi

+

My teaching style has changed a bit since I started with CodeRefinery. In the beginning I had this “BLOB” (Binary Large OBject) of knowledge and experience that I wanted to to convey to the participants. With experience and some help from the Carpentries Instructor training, I have realized I need to serialize the “BLOB”, to be able to share it with others.

+

In a similar fashion as you would do with a binary large object which you intend to send over the wire, you will need stop signals, check-sums and re-transmissions, when you give a lecture. I have come to appreciate the natural periods/breaks the lessons offers, the questions raised, the errors that appear during type-along and the re-transmission. Co-instructors are good to use for re-transmission or broadening a specific topic.

+

When I started with CodeRefinery my inclination was to give a lecture. Today I am trying to be a guide during a learning experience, a learning experience which includes me as well. That may sound a bit self-centric, but is in fact the opposite, as I have to be more sensitive to what is going on in the room. The more conscious I am of being a guide, the better lesson.

+

Tools that I find useful in preparing a lesson is concept maps and Learner Personas (though I have developed too few of them):

+ +
+
+

Radovan Bast

+

My teaching changed by 180 degrees after taking the Carpentries instructor +training. Before that I used slides, 45 minute lecture blocks, and separate +exercise sessions. After the Carpentries instructor training I embraced the +interaction, exercises, demos, and typos.

+

My goal for a lesson is to spark curiosity to try things after the lesson, both +for the novices (“This looks like a useful tool, I want to try using it after +the workshop.”) and the more experienced participants (“Aha - I did not know +you could do this. I wonder whether I can make it work with X.”). I like to +start lessons with a question because this makes participants look up from +their browsers.

+

Keeping both the novices and the experts engaged during a lesson can be +difficult and offering additional exercises seems to be a good compromise.

+

For me it is a good sign if there are many questions. I like to encourage +questions by asking questions to the participants. But I also try not to go +into a rabbit hole when I get a question where only experts will appreciate the +answer.

+

I try to avoid jargon and “war stories” from the professional developers’ +perspective or the business world. Most researchers may not relate to them. +For examples I always try to use the research context. Avoid “customer”, +“production”, also a lot of Agile jargon is hard to relate to.

+

Less and clear is better than more and unclear. Simple examples are better than +complicated examples. Almost never I have felt or got the feedback that +something was too simple. I am repeating in my head to not use the words +“simply”, “just”, “easy”. If participants take home one or two points from a +lesson, that’s for me success.

+

I prepare for the lesson by reading the instructor guide and all issues and +open pull requests. I might not be able to solve issues, but I don’t want to be +surprised by known issues. I learn the material to a point where I know +precisely what comes next and am never surprised by the next episode or slide. +This allows me to skip and distill the essence and not read bullet point by +bullet point.

+

I try to never deviate from the script and if I do, be very explicit about it.

+

A great exercise I can recommend is to watch a tutorial on a new programming +language/tool you have never used. It can feel very overwhelming and fast to +get all these new concepts and tools thrown at self. This can prepare me for +how a participant might feel listening to me.

+

I very much like the co-teaching approach where the other person helps +detecting when I go too fast or become too confusing. I like when two +instructors complement each other during a lesson.

+
+
+

Sabry Razick

+

My approach is to show it is fun to demystify concepts. Once a concept is +not a mystery anymore, the learners will understand is what it means, where +it is coming from, why it is in place and what it could it offer for their future. +I try to relate concepts to real life with a twist of humour whenever possible if +the outcome is certain not be offensive to any one. I use diagrams whenever possible, +I have spent weeks creating diagrams that is sometime three or four sentences. That +effort I consider worthwhile as my intention is not to teach, but to demystify. +Once that is achieved, learners will learn the nitty gritty on their own easily +and with confidence, when they have the use-case.

+
+
+

Richard Darst

+

Like many people, I’ve often been teaching, but rarely a teacher. I +tend to teach like I am doing an informal mentorship. +I’ve realized long ago that my most important lessons weren’t +learned in classes, but by a combination of seeing things done by +friends and independent study after that. I’ve realized that +teaching (the things I teach) is trying to correct these differences +in backgrounds.

+

My main job is supporting computing infrastructure, so my teaching +is very grounded in real-world problems. I’m often start at the +very basics, because this is what I see missing most often.

+

When teaching, I like lots of audience questions and don’t mind +going off-script a bit (even though I know it should be minimized). +I find that sufficient audience interest allows any lesson to be a +success - you don’t have to know everything perfectly, just show how +you’d approach a problem.

+
+
+

Stepas Toliautas

+

I aim for my learners to understand things (concepts, techniques…), instead of just memorizing them. The phrase I use from time to time when teaching information technology topics (be it hardware or software) is “there is no magic”: everything can be explained if necessary. While CodeRefinery also emphasizes usefulness/ immediate applicability of the content, often having the correct notions actually helps to start using them sooner and with less mistakes.

+

I try to guide my audience through the presented material with occasional questions related to previous topics and common knowledge – to help them link the concepts already during the lesson. I’m also fully aware that waiting for someone to answer is quite uncomfortable in-person and doubly so in an online environment, especially if no one uses their cameras :)

+

And if I get the question I don’t have the answer for (or material to show it) at the moment, in university classes I prepare and come back to it next time. While with one-off workshops there might not be a “next time”, open-source material used by CodeRefinery allows to have the same outcome: the latest and greatest version stays available for self-study afterwards.

+
+
+
+

Summary

+
+

Keypoints

+
    +
  • People have different viewpoints on teaching.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/video-editing/index.html b/video-editing/index.html new file mode 100644 index 0000000..bdf96d4 --- /dev/null +++ b/video-editing/index.html @@ -0,0 +1,606 @@ + + + + + + + Video editing — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Video editing

+
+

Objectives

+
    +
  • Get to know ways of quick video editing to be able to provide +accessible videos

  • +
  • Learn how video editing can be distributed and done the same day.

  • +
+
+
+

Instructor note

+
    +
  • Teaching: 20 min

  • +
  • Exercises: 20 min

  • +
+
+

Video recordings could be useful for people watching later, +but also are (perhaps more) useful for immediate review and catching +up after missing a day in a workshop. For this, they need to be +released immediately, within a few hours of the workshop. +CodeRefinery does this, and you can too.

+

Hypothesis: videos must be processed the same evening as they were +recorded, otherwise (it may never happen) or (it’s too late to be +useful). To do that, we have to make processing good enough (not +perfect) and fast and the work distributeable.

+
+

Primary articles

+ +
+
+

How this relates to streaming

+
    +
  • If you stream, then the audience can not appear in the recorded +videos

  • +
  • This allows you to release videos very quickly if you have the +right tools.

  • +
  • When you have a large audience, the videos start helping more +(review a missed day, catch up later, review later)

  • +
  • Thus

    +
      +
    • If you would never want videos, there may never be a benefit to +streaming

    • +
    • If you want videos, it gives motivation to stream.

    • +
    +
  • +
+
+
+

Summary

+
    +
  • Basic principle: privacy is more important than any other factor. +If we can’t guarantee privacy, we can’t release videos at all.

    +
      +
    • Disclaimers such as “if you don’t want to appear in a recording, +leave your video off and don’t say anything”, since a) accidents +happen especially when coming back from breakout rooms. b) it +creates an incentive to not interact or participate in the course.

    • +
    +
  • +
  • Livestreaming is important here: by separating the instruction from +the audience audio/video, there is no privacy risk in the raw +recording. They could be released or shared unprocessed.

  • +
  • Our overall priorities

    +
      +
    1. No learner (or anyone not staff) video, audio, names, etc. are +present in the recordings.

    2. +
    3. Good descriptions.

    4. +
    5. Removing breaks and other dead time.

    6. +
    7. Splitting videos into useful chunks (e.g. per-episode), perhaps +equal with the next one:

    8. +
    9. Good Table of Contents information so learners can jump to the +right spots (this also helps with “good description”.)

    10. +
    +
  • +
  • ffmpeg-editlist +allows us to define an edit in a text file (crowdsourceable on +Github), and then generate videos very quickly.

  • +
+
+
+

How we do it

+

The full explanation is in the form of the exercises below. As a +summary:

+
    +
  • Record raw video (if from a stream, audience can’t possibly be in +it)

  • +
  • Run Whisper to get good-enough subtitles. Distribute to someone for +checking and improving.

  • +
  • Define the editing steps (which segments become which videos and +their descriptions) in a YAML file.

  • +
  • Run ffmpeg-editlist, which takes combines the previous three steps +into final videos.

  • +
+
+
+

Exercises

+
+

Exercise A

+

These exercises will take you through the whole sequence.

+
+

Editing-1: Get your sample video

+

Download a sample video:

+ +
+

Editing-2: Run Whisper to generate raw subtitles and test video.

+

First off, install Whisper and generate the base subtitles, based +on the. Since this is probably too much to expect for a short +lesson, they are provided for you (above), but if you want you can +try using Whisper, or generating the subtitles some other way.

+

You can start generating subtitles now, while you do the next +steps, so that they are ready by the time you are ready to apply +the editlist. ffmpeg-editlist can also slice up the subtitles from +the main video to make subtitles for each segment you cut out.

+

Whisper is left as an exercise to the reader.

+ +
+
+
+

Editing-3: Create the basic editlist.yaml file

+

Install +ffmpeg-editlist and +try to follow its instructions, to create an edit with these features:

+
    +
  • The input definition.

  • +
  • Two output sections: the “Intro to the course”, and “From data +storage to your science” talks (Remember it said the recording +started at 11:35… look at the schedule for hints on when it +might start!). This should have a start/end timestamp from the +original video.

  • +
+

A basic example:

+
- input: day1-raw.mkv
+
+# This is the output from one section.  Your result should have two of these sections.
+- output: part1.mkv
+  title: something
+  description: >-
+    some long
+    description of the
+    segment
+  editlist:
+    - start: 10:00    # start timestamp of the section, in *original* video
+    - end: 20:00      # end timestamp of the section, in the *original* video
+
+
+ +
+
+

Discussion: what makes a video easy to edit?

+
    +
  • Clear speaking and have high audio quality.

  • +
  • For subtitle generation: Separate sentences cleanly, otherwise it +gets in a “stream of words” instead of “punctuated sentences” +mode.

  • +
  • Clearly screen-sharing the place you are at, including section +name.

  • +
  • Clear transitions, “OK, now let’s move on to the next lesson, +LESSON-NAME. Going back to the main page, we see it here.”

  • +
  • Clearly indicate where the transitions are

  • +
  • Hover mouse cursor over the area you are currently talking about.

  • +
  • Scroll screen when you move on to a new topic.

  • +
  • Accurate course webpage and sticking to the schedule

  • +
+

All of these are also good for learners. By editing videos, you +become an advocate for good teaching overall.

+
+
+

Editing-4: Run ffmpeg-editlist

+

Install ffmpeg-editlist: pip install ffmpeg-editlist[srt] (you +may want to use a virtual environment, but these are very minimal +dependencies).

+

The ffmpeg command line tool must be available in your +PATH.

+ +
+
+

Editing-5: Add more features

+
    +
  • Several chapter definitions.(re-run and you should see a +.info.txt file also generated). Video chapter definitions +are timestamps of the original video, that get translated to +timestamps of the output video.

    +
    - output: part1.mkv
    +  editlist:
    +  - start: 10:00
    +  - -: Introduction    #  <-- New, `-` means "at start time"
    +  - 10:45: Part 1      #  <-- New
    +  - 15:00: Part 2      #  <-- New
    +  - end: 20:00
    +
    +
    +

    Look at the .info.txt files that come out now. What is new in it?

    +
  • +
  • Add in “workshop title”, “workshop description”, and see the +.info.txt files that come out now. This is ready for +copy-pasting into a YouTube description (first line is the title, +rest is the description).

    +

    Look at the new .info.txt files. What is new?

    +
  • +
+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+ +
+
+

Editing-6: Subtitles

+

Re-run ffmpeg-editlist with the --srt option (you have to +install it with pip install ffmpeg-editlist[srt] to pull in the +necessary dependency). Notice how .srt files come out now.

+

Use some subtitle editor to edit the original subtitle file, to +fix up any transcription mistakes you may find. You could edit +directly, use subtitle-editor on Linux, or find some other +tool.

+

What do you learn from editing the subtitles?

+
+
+

Editing-7: Generate the final output file.

+
    +
  • Run ffmpeg-editlist with the --reencode option: this +re-encodes the video and makes sure that there is no black point +at the start.

  • +
  • If you re-run with --check, it won’t output a new video file, +but it will re-output the .info.txt and .srt files. +This is useful when you adjust descriptions or chapters.

  • +
+
+
+

Discussion: how to distribute this?

+

Create a flowchat of all the parts that need to be done, and which +parts can be done in parallel. Don’t forget things that you might +need to do before the workshop starts.

+

How hard was this editing? Was it worth it?

+
+
+
+

Exercise B

+

This is a more limited (and older) version of the above exercise, +using an synthetic example video.

+
+

Use ffmpeg-editlist to edit this sample video

+

Prerequisites: ffmpeg must be installed on your computer +outside of Python. Be able to install ffmpeg-editlist. This is +simple in a Python virtual environment, but if not the only +dependency is PyYAML.

+ + +
+
+
+
+

See also

+ +
+

Keypoints

+
    +
  • Video editing is very useful for learning

  • +
  • Set your time budget and make it good enough in that time

  • +
  • Reviewing videos improves your teaching, too.

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/why-we-stream/index.html b/why-we-stream/index.html new file mode 100644 index 0000000..666d0cf --- /dev/null +++ b/why-we-stream/index.html @@ -0,0 +1,298 @@ + + + + + + + Why we stream — Train the trainer workshop documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Why we stream

+
+

Objectives

+
    +
  • Learn the general history of CodeRefinery streaming.

  • +
  • Discuss the benefits of streaming and recording

  • +
  • Discuss the downsides and difficulties

  • +
+
+
+

Instructor note

+
    +
  • Discussion: 10 min

  • +
  • Q&A: 5 min

  • +
  • Exercises: 0 min

  • +
+
+

This is a general discussion of the topics of the day, focused on the +history of why we stream and record, how we got here, and how people +feel about it. We won’t focus on how anything is done.

+
+

Icebreaker questions

+
    +
  • What is the most people you have taught for?

  • +
  • What are the distinct parts of teaching, that can be +separated? (teaching, helping, etc)

  • +
+
+
+

What is streaming and recording?

+
    +
  • Streaming is mass communication: one to many

    +
      +
    • Interaction audience→presenters is more limited (but different)

    • +
    +
  • +
  • Using consumer-grade tools, normal people can reach huge audiences +by Twitch/YouTube/etc.

  • +
  • This isn’t actually that hard: people with much less training than +us do it all the time.

  • +
  • They reach huge audiences and maintain engagement for long events.

  • +
+

Recording and rapid video editing is useful even without +streaming.

+
+
+

History

+
    +
  • In-person workshops

    +
      +
    • 3 × full day, required travel, infrequent, one-shot

    • +
    +
  • +
  • Covid and remote teaching

    +
      +
    • Traditional “Zoom” teaching several times

    • +
    +
  • +
  • Mega-CodeRefinery workshop

    +
      +
    • 100-person Zoom teaching

    • +
    • Emphasis on teams

    • +
    +
  • +
  • Research Software Hour

    +
      +
    • Livestream free-form discussions on Twitch

    • +
    +
  • +
  • Streamed “HPC Kickstart” courses

  • +
+
+
+

Benefits and disadvantages

+

Benefits:

+
    +
  • Larger size gives more (but different) interaction possibility

    +
      +
    • “Notes” for async Q&A

    • +
    +
  • +
  • Recording (with no privacy risk) allows instant reviews

  • +
  • Stream-scale allows for many of the things you have learned about in +days 1-3.

  • +
+

Disadvantages:

+
    +
  • Requires training for using the tools

  • +
  • Requires a certain scale to be worth it

  • +
  • Coordination is much harder for big events

  • +
+

When would I recommend it?

+
    +
  • No: For small courses

  • +
  • Questionable: Medium sized courses with no videos

  • +
  • Yes: When you want the largest audience

  • +
  • Yes: When you want without registration required

  • +
  • Yes: When you want good reusability/fast videos

  • +
+
+
+

Future prospects (briefly)

+
    +
  • Streaming probably stays as a CodeRefinery tool

  • +
  • We can scale our courses much larger than they are now. Why don’t +we, together with others?

  • +
  • These tools are useful in other places too

    +
      +
    • I’ve used them to record my own talks to make videos of my +single-person presentations or record conference talks nicer than Zoom.

    • +
    +
  • +
+
+
+

Q&A

+

Q&A from audience

+
+

Keypoints

+
    +
  • Streaming optimizes a course for different things

  • +
  • The disadvantages can be compensated for

  • +
  • There are benefits and disadvantages

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file